fix: update @pureadmin/utils

This commit is contained in:
xiaoxian521 2022-07-02 12:11:09 +08:00
parent af04611d6c
commit 5a23bd02a4
72 changed files with 1355 additions and 1981 deletions

View File

@ -138,9 +138,9 @@ In principle, no fees and copyrights are charged, and you can use it with confid
Thank you very much for your support, I believe the project will get better and better :heart:
| xueyuheng | taolei1990 | hang-kim | madwolfcrazy | limuen | BenLakes |
| :--------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: |
| <a href="https://github.com/xueyuheng"><img src="https://avatars.githubusercontent.com/u/48202935?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/taolei1990"><img src="https://avatars.githubusercontent.com/u/23173640?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/hang-kim"><img src="https://avatars.githubusercontent.com/u/52914259?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/madwolfcrazy"><img src="https://avatars.githubusercontent.com/u/223671?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/limuen"><img src="https://avatars.githubusercontent.com/u/31790606?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/BenLakes"><img src="https://avatars.githubusercontent.com/u/15206046?v=4" width="60px" height="60px" /></a> |
| xueyuheng | taolei1990 | hang-kim | madwolfcrazy | limuen | BenLakes | mollerzhu | cnyyk |
| :--------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------: |
| <a href="https://github.com/xueyuheng"><img src="https://avatars.githubusercontent.com/u/48202935?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/taolei1990"><img src="https://avatars.githubusercontent.com/u/23173640?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/hang-kim"><img src="https://avatars.githubusercontent.com/u/52914259?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/madwolfcrazy"><img src="https://avatars.githubusercontent.com/u/223671?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/limuen"><img src="https://avatars.githubusercontent.com/u/31790606?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/BenLakes"><img src="https://avatars.githubusercontent.com/u/15206046?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/mollerzhu"><img src="https://avatars.githubusercontent.com/u/49627902?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/mollerzhu"><img src="https://avatars.githubusercontent.com/u/275233?v=4" width="60px" height="60px" /></a> |
## Contributors

View File

@ -144,9 +144,9 @@ pnpm build
非常感谢你们的支持,相信项目会越来越好 :heart:
| xueyuheng | taolei1990 | hang-kim | madwolfcrazy | limuen | BenLakes | mollerzhu |
| :--------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------: |
| <a href="https://github.com/xueyuheng"><img src="https://avatars.githubusercontent.com/u/48202935?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/taolei1990"><img src="https://avatars.githubusercontent.com/u/23173640?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/hang-kim"><img src="https://avatars.githubusercontent.com/u/52914259?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/madwolfcrazy"><img src="https://avatars.githubusercontent.com/u/223671?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/limuen"><img src="https://avatars.githubusercontent.com/u/31790606?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/BenLakes"><img src="https://avatars.githubusercontent.com/u/15206046?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/mollerzhu"><img src="https://avatars.githubusercontent.com/u/49627902?v=4" width="60px" height="60px" /></a> |
| xueyuheng | taolei1990 | hang-kim | madwolfcrazy | limuen | BenLakes | mollerzhu | cnyyk |
| :--------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------: |
| <a href="https://github.com/xueyuheng"><img src="https://avatars.githubusercontent.com/u/48202935?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/taolei1990"><img src="https://avatars.githubusercontent.com/u/23173640?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/hang-kim"><img src="https://avatars.githubusercontent.com/u/52914259?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/madwolfcrazy"><img src="https://avatars.githubusercontent.com/u/223671?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/limuen"><img src="https://avatars.githubusercontent.com/u/31790606?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/BenLakes"><img src="https://avatars.githubusercontent.com/u/15206046?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/mollerzhu"><img src="https://avatars.githubusercontent.com/u/49627902?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/mollerzhu"><img src="https://avatars.githubusercontent.com/u/275233?v=4" width="60px" height="60px" /></a> |
## 贡献者

View File

@ -33,8 +33,8 @@
"@logicflow/extension": "^1.1.16",
"@pureadmin/components": "^1.0.6",
"@pureadmin/descriptions": "^1.1.0",
"@pureadmin/table": "^1.1.0",
"@pureadmin/utils": "^0.0.11",
"@pureadmin/table": "^1.2.0",
"@pureadmin/utils": "^0.0.14",
"@vueuse/core": "^8.7.4",
"@vueuse/motion": "^2.0.0-beta.12",
"@vueuse/shared": "^8.7.4",
@ -48,7 +48,7 @@
"dayjs": "^1.11.3",
"driver.js": "^0.9.8",
"echarts": "^5.3.3",
"element-plus": "^2.2.6",
"element-plus": "^2.2.8",
"element-resize-detector": "^1.2.3",
"js-cookie": "^3.0.1",
"jsbarcode": "^3.11.5",
@ -144,7 +144,7 @@
"unplugin-vue-define-options": "^0.6.1",
"vite": "^2.9.13",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-remove-console": "^1.0.0",
"vite-plugin-remove-console": "^1.0.3",
"vite-svg-loader": "^3.3.0",
"vue-eslint-parser": "^8.2.0"
},

2177
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
import { withInstall } from "/@/utils";
import reBarcode from "./src/index.vue";
import { withInstall } from "@pureadmin/utils";
/** 条形码组件 */
export const ReBarcode = withInstall(reBarcode);

View File

@ -1,6 +1,6 @@
import { withInstall } from "/@/utils";
import reNormalCountTo from "./src/normal";
import reboundCountTo from "./src/rebound";
import { withInstall } from "@pureadmin/utils";
/** 普通数字动画组件 */
const ReNormalCountTo = withInstall(reNormalCountTo);

View File

@ -7,7 +7,7 @@ import {
unref
} from "vue";
import { countToProps } from "./props";
import { isNumber } from "/@/utils/is";
import { isNumber } from "@pureadmin/utils";
export default defineComponent({
name: "ReNormalCountTo",

View File

@ -1,5 +1,5 @@
import reCropper from "./src";
import { withInstall } from "/@/utils";
import { withInstall } from "@pureadmin/utils";
/** 图片裁剪组件 */
export const ReCropper = withInstall(reCropper);

View File

@ -9,7 +9,7 @@ import {
PropType
} from "vue";
import { templateRef } from "@vueuse/core";
import { useAttrs } from "/@/utils/useAttrs";
import { useAttrs } from "@pureadmin/utils";
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.css";

View File

@ -1,5 +1,5 @@
import reFlop from "./src/index.vue";
import { withInstall } from "/@/utils";
import { withInstall } from "@pureadmin/utils";
/** 时间翻牌组件 */
export const ReFlop = withInstall(reFlop);

View File

@ -1,7 +1,7 @@
import { withInstall } from "/@/utils";
import control from "./src/Control.vue";
import nodePanel from "./src/NodePanel.vue";
import dataDialog from "./src/DataDialog.vue";
import { withInstall } from "@pureadmin/utils";
/** LogicFlow流程图-控制面板 */
const Control = withInstall(control);

View File

@ -1,5 +1,5 @@
import { withInstall } from "/@/utils";
import reImageVerify from "./src/index.vue";
import { withInstall } from "@pureadmin/utils";
/** 图形验证码组件 */
export const ReImageVerify = withInstall(reImageVerify);

View File

@ -1,5 +1,5 @@
import amap from "./src/Amap.vue";
import { withInstall } from "/@/utils";
import { withInstall } from "@pureadmin/utils";
/** 高德地图组件 */
export const Amap = withInstall(amap);

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { reactive, getCurrentInstance, onBeforeMount, onUnmounted } from "vue";
import { deviceDetection } from "/@/utils/deviceDetection";
import { deviceDetection } from "@pureadmin/utils";
import AMapLoader from "@amap/amap-jsapi-loader";
import { mapJson } from "/@/api/mock";
import car from "/@/assets/car.png";

View File

@ -1,5 +1,5 @@
import reQrcode from "./src/index";
import { withInstall } from "/@/utils";
import { withInstall } from "@pureadmin/utils";
/** 二维码组件 */
export const ReQrcode = withInstall(reQrcode);

View File

@ -8,8 +8,8 @@ import {
defineComponent
} from "vue";
import "./index.scss";
import { isString } from "/@/utils/is";
import { cloneDeep } from "lodash-unified";
import { isString } from "@pureadmin/utils";
import { propTypes } from "/@/utils/propTypes";
import { IconifyIconOffline } from "../../ReIcon";
import QRCode, { QRCodeRenderersOptions } from "qrcode";

View File

@ -1,5 +1,5 @@
import { withInstall } from "/@/utils";
import reSeamlessScroll from "./src/index.vue";
import { withInstall } from "@pureadmin/utils";
/** 无缝滚动组件 */
export const ReSeamlessScroll = withInstall(reSeamlessScroll);

View File

@ -1,5 +1,5 @@
import reSelector from "./src";
import { withInstall } from "/@/utils";
import { withInstall } from "@pureadmin/utils";
/** 选择器组件 */
export const ReSelector = withInstall(reSelector);

View File

@ -6,7 +6,7 @@ import {
getCurrentInstance,
unref
} from "vue";
import { addClass, removeClass, toggleClass } from "/@/utils/operate";
import { addClass, removeClass, toggleClass } from "@pureadmin/utils";
import "./index.css";
const stayClass = "stay"; //鼠标点击
@ -254,23 +254,32 @@ export default defineComponent({
});
addClass(
instance.refs["hsdiv" + props.HsKey + item[0]],
instance.refs["hsdiv" + props.HsKey + item[0]] as Element,
activeClass,
stayClass
);
addClass(instance.refs["hstd" + props.HsKey + item[0]], bothLeftSides);
addClass(
instance.refs["hsdiv" + props.HsKey + item[1]],
instance.refs["hstd" + props.HsKey + item[0]] as Element,
bothLeftSides
);
addClass(
instance.refs["hsdiv" + props.HsKey + item[1]] as Element,
activeClass,
stayClass
);
addClass(instance.refs["hstd" + props.HsKey + item[1]], bothRightSides);
addClass(
instance.refs["hstd" + props.HsKey + item[1]] as Element,
bothRightSides
);
while (item[1] >= item[0]) {
addClass(instance.refs["hstd" + props.HsKey + item[0]], inRange);
addClass(
instance.refs["hstd" + props.HsKey + item[0]] as Element,
inRange
);
item[0]++;
}
};

View File

@ -1,5 +1,5 @@
import tableProBar from "./src/bar";
import { withInstall } from "/@/utils";
import { withInstall } from "@pureadmin/utils";
/** table-crud组件 */
export const TableProBar = withInstall(tableProBar);

View File

@ -1,5 +1,5 @@
// 参考https://www.npmjs.com/package/element-tree-line (主要是替换需要通过函数传参的方式去注册组件并添加更好的类型支持并移除this.$scopedSlots在3.x中,将所有this.$scopedSlots替换为this.$slots)
import { isFunction } from "/@/utils/is";
import { isFunction } from "@pureadmin/utils";
import { h, defineComponent } from "vue";
import type { PropType } from "vue";
import "./index.scss";

View File

@ -9,7 +9,7 @@ import avatars from "/@/assets/avatars.jpg";
import Hamburger from "./sidebar/hamBurger.vue";
import { watch, getCurrentInstance } from "vue";
import Breadcrumb from "./sidebar/breadCrumb.vue";
import { deviceDetection } from "/@/utils/deviceDetection";
import { deviceDetection } from "@pureadmin/utils";
import screenfull from "../components/screenfull/index.vue";
import globalization from "/@/assets/svg/globalization.svg?component";

View File

@ -2,8 +2,8 @@
import { useRouter } from "vue-router";
import SearchResult from "./SearchResult.vue";
import SearchFooter from "./SearchFooter.vue";
import { deleteChildren } from "/@/utils/tree";
import { transformI18n } from "/@/plugins/i18n";
import { deleteChildren } from "@pureadmin/utils";
import { useDebounceFn, onKeyStroke } from "@vueuse/core";
import { ref, watch, computed, nextTick, shallowRef } from "vue";
import { usePermissionStoreHook } from "/@/store/modules/permission";

View File

@ -15,16 +15,16 @@ import { useRouter } from "vue-router";
import panel from "../panel/index.vue";
import { emitter } from "/@/utils/mitt";
import { templateRef } from "@vueuse/core";
import { debounce } from "/@/utils/debounce";
import { themeColorsType } from "../../types";
import { routerArrays } from "/@/layout/types";
import type { StorageConfigs } from "/#/index";
import { useAppStoreHook } from "/@/store/modules/app";
import { shadeBgColor } from "../../theme/element-plus";
import { useEpThemeStoreHook } from "/@/store/modules/epTheme";
import { storageLocal, storageSession } from "/@/utils/storage";
import { toggleTheme } from "@pureadmin/theme/dist/browser-utils";
import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";
import { createNewStyle, writeNewStyle } from "../../theme/element-plus";
import { toggleTheme } from "@pureadmin/theme/dist/browser-utils";
import { debounce, storageLocal, storageSession } from "@pureadmin/utils";
import dayIcon from "/@/assets/svg/day.svg?component";
import darkIcon from "/@/assets/svg/dark.svg?component";
@ -64,7 +64,7 @@ const horizontalRef = templateRef<HTMLElement | null>("horizontalRef", null);
const mixRef = templateRef<HTMLElement | null>("mixRef", null);
let layoutTheme =
ref(storageLocal.getItem("responsive-layout")) ||
ref(storageLocal.getItem<StorageConfigs>("responsive-layout")) ||
ref({
layout: instanceConfig?.Layout ?? "vertical",
theme: instanceConfig?.Theme ?? "default"

View File

@ -8,7 +8,7 @@ import SidebarItem from "./sidebarItem.vue";
import avatars from "/@/assets/avatars.jpg";
import screenfull from "../screenfull/index.vue";
import { useRoute, useRouter } from "vue-router";
import { deviceDetection } from "/@/utils/deviceDetection";
import { deviceDetection } from "@pureadmin/utils";
import { watch, nextTick, onMounted, getCurrentInstance } from "vue";
import { usePermissionStoreHook } from "/@/store/modules/permission";
import globalization from "/@/assets/svg/globalization.svg?component";

View File

@ -8,7 +8,7 @@ import avatars from "/@/assets/avatars.jpg";
import { transformI18n } from "/@/plugins/i18n";
import screenfull from "../screenfull/index.vue";
import { useRoute, useRouter } from "vue-router";
import { deviceDetection } from "/@/utils/deviceDetection";
import { deviceDetection } from "@pureadmin/utils";
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
import { useEpThemeStoreHook } from "/@/store/modules/epTheme";
import { getParentPaths, findRouteByPath } from "/@/router/utils";

View File

@ -3,7 +3,8 @@ import Logo from "./logo.vue";
import { emitter } from "/@/utils/mitt";
import { useNav } from "../../hooks/nav";
import SidebarItem from "./sidebarItem.vue";
import { storageLocal } from "/@/utils/storage";
import type { StorageConfigs } from "/#/index";
import { storageLocal } from "@pureadmin/utils";
import { useRoute, useRouter } from "vue-router";
import { ref, computed, watch, onBeforeMount } from "vue";
import { findRouteByPath, getParentPaths } from "/@/router/utils";
@ -12,7 +13,7 @@ import { usePermissionStoreHook } from "/@/store/modules/permission";
const route = useRoute();
const routers = useRouter().options.routes;
const showLogo = ref(
storageLocal.getItem("responsive-configure")?.showLogo ?? true
storageLocal.getItem<StorageConfigs>("responsive-configure")?.showLogo ?? true
);
const { pureApp, isCollapse, menuSelect } = useNav();
@ -43,7 +44,7 @@ getSubMenuData(route.path);
onBeforeMount(() => {
emitter.on("logoChange", key => {
showLogo.value = key;
showLogo.value = key as unknown as boolean;
});
});

View File

@ -22,8 +22,8 @@ import closeRight from "/@/assets/svg/close_right.svg?component";
import { useI18n } from "vue-i18n";
import { emitter } from "/@/utils/mitt";
import type { StorageConfigs } from "/#/index";
import { routerArrays } from "/@/layout/types";
import { storageLocal } from "/@/utils/storage";
import { useRoute, useRouter } from "vue-router";
import { isEqual, isEmpty } from "lodash-unified";
import { transformI18n, $t } from "/@/plugins/i18n";
@ -32,8 +32,13 @@ import { useSettingStoreHook } from "/@/store/modules/settings";
import { handleAliveRoute, delAliveRoutes } from "/@/router/utils";
import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";
import { usePermissionStoreHook } from "/@/store/modules/permission";
import { toggleClass, removeClass, hasClass } from "/@/utils/operate";
import { templateRef, useResizeObserver, useDebounceFn } from "@vueuse/core";
import {
toggleClass,
removeClass,
hasClass,
storageLocal
} from "@pureadmin/utils";
const { t } = useI18n();
const route = useRoute();
@ -47,7 +52,9 @@ const tabDom = templateRef<HTMLElement | null>("tabDom", null);
const containerDom = templateRef<HTMLElement | null>("containerDom", null);
const scrollbarDom = templateRef<HTMLElement | null>("scrollbarDom", null);
const showTags =
ref(storageLocal.getItem("responsive-configure").hideTabs) ?? "false";
ref(storageLocal.getItem<StorageConfigs>("responsive-configure").hideTabs) ??
"false";
// @ts-expect-error
let multiTags: ComputedRef<Array<RouteConfigs>> = computed(() => {
return useMultiTagsStoreHook()?.multiTags;
});
@ -240,10 +247,13 @@ const tagsViews = reactive<Array<tagsViewsType>>([
//
const showModel = ref(
storageLocal.getItem("responsive-configure")?.showModel || "smart"
storageLocal.getItem<StorageConfigs>("responsive-configure")?.showModel ||
"smart"
);
if (!showModel.value) {
const configure = storageLocal.getItem("responsive-configure");
const configure = storageLocal.getItem<StorageConfigs>(
"responsive-configure"
);
configure.showModel = "card";
storageLocal.setItem("responsive-configure", configure);
}
@ -600,7 +610,9 @@ onBeforeMount(() => {
//
emitter.on("tagViewsChange", key => {
// @ts-expect-error
if (unref(showTags) === key) return;
// @ts-expect-error
showTags.value = key;
});

View File

@ -4,9 +4,10 @@ import { getConfig } from "/@/config";
import { emitter } from "/@/utils/mitt";
import { routeMetaType } from "../types";
import { remainingPaths } from "/@/router";
import type { StorageConfigs } from "/#/index";
import { routerArrays } from "/@/layout/types";
import { transformI18n } from "/@/plugins/i18n";
import { storageSession } from "/@/utils/storage";
import { storageSession } from "@pureadmin/utils";
import { useAppStoreHook } from "/@/store/modules/app";
import { i18nChangeLanguage } from "@wangeditor/editor";
import { useEpThemeStoreHook } from "/@/store/modules/epTheme";
@ -17,7 +18,8 @@ const errorInfo = "当前路由配置不正确,请检查配置";
export function useNav() {
const pureApp = useAppStoreHook();
// 用户名
const username: string = storageSession.getItem("info")?.username;
const username: string =
storageSession.getItem<StorageConfigs>("info")?.username;
// 设置国际化选中后的样式
const getDropdownItemStyle = computed(() => {

View File

@ -11,8 +11,8 @@ import { setType } from "./types";
import { useI18n } from "vue-i18n";
import { routerArrays } from "./types";
import { emitter } from "/@/utils/mitt";
import { deviceDetection } from "@pureadmin/utils";
import { useAppStoreHook } from "/@/store/modules/app";
import { deviceDetection } from "/@/utils/deviceDetection";
import { useMultiTagsStore } from "/@/store/modules/multiTags";
import { useSettingStoreHook } from "/@/store/modules/settings";

View File

@ -9,7 +9,7 @@ import { MotionPlugin } from "@vueuse/motion";
import { useEcharts } from "/@/plugins/echarts";
import VirtualScroller from "vue-virtual-scroller";
import { useTable } from "../src/plugins/vxe-table";
import { injectResponsiveStorage } from "/@/utils/storage/responsive";
import { injectResponsiveStorage } from "/@/utils/responsive";
import Table from "@pureadmin/table";
import PureDescriptions from "@pureadmin/descriptions";

View File

@ -1,4 +1,4 @@
import { App } from "vue";
import type { App } from "vue";
import * as echarts from "echarts/core";
import { SVGRenderer } from "echarts/renderers";
import { PieChart, BarChart, LineChart } from "echarts/charts";

View File

@ -1,6 +1,7 @@
// 多组件库的国际化和本地项目国际化兼容
import { App, WritableComputedRef } from "vue";
import { storageLocal } from "/@/utils/storage";
import type { StorageConfigs } from "/#/index";
import { storageLocal } from "@pureadmin/utils";
import { type I18n, createI18n } from "vue-i18n";
// element-plus国际化
@ -62,7 +63,8 @@ export const $t = (key: string) => key;
export const i18n: I18n = createI18n({
legacy: false,
locale: storageLocal.getItem("responsive-locale")?.locale ?? "zh",
locale:
storageLocal.getItem<StorageConfigs>("responsive-locale")?.locale ?? "zh",
fallbackLocale: "en",
messages: localesConfigs
});

View File

@ -1,12 +1,9 @@
import { isUrl } from "/@/utils/is";
import { getConfig } from "/@/config";
import { toRouteType } from "./types";
import { openLink } from "/@/utils/link";
import NProgress from "/@/utils/progress";
import { findIndex } from "lodash-unified";
import type { StorageConfigs } from "/#/index";
import { transformI18n } from "/@/plugins/i18n";
import { storageSession } from "/@/utils/storage";
import { buildHierarchyTree } from "/@/utils/tree";
import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";
import { usePermissionStoreHook } from "/@/store/modules/permission";
import {
@ -27,6 +24,12 @@ import {
formatTwoStageRoutes,
formatFlatteningRoutes
} from "./utils";
import {
buildHierarchyTree,
openLink,
isUrl,
storageSession
} from "@pureadmin/utils";
import pptRouter from "./modules/ppt";
import homeRouter from "./modules/home";
@ -107,9 +110,9 @@ router.beforeEach((to: toRouteType, _from, next) => {
handleAliveRoute(newMatched);
}
}
const name = storageSession.getItem("info");
const name = storageSession.getItem<StorageConfigs>("info");
NProgress.start();
const externalLink = isUrl(to?.name);
const externalLink = isUrl(to?.name as string);
if (!externalLink)
to.matched.some(item => {
if (!item.meta.title) return "";
@ -122,7 +125,7 @@ router.beforeEach((to: toRouteType, _from, next) => {
if (_from?.name) {
// name为超链接
if (externalLink) {
openLink(to?.name);
openLink(to?.name as string);
NProgress.done();
} else {
next();

View File

@ -10,7 +10,7 @@ import { router } from "./index";
import { loadEnv } from "../../build";
import { useTimeoutFn } from "@vueuse/core";
import { RouteConfigs } from "/@/layout/types";
import { buildHierarchyTree } from "/@/utils/tree";
import { buildHierarchyTree } from "@pureadmin/utils";
import { usePermissionStoreHook } from "/@/store/modules/permission";
const Layout = () => import("/@/layout/index.vue");
const IFrame = () => import("/@/layout/frameView.vue");

View File

@ -2,22 +2,23 @@ import { store } from "/@/store";
import { appType } from "./types";
import { defineStore } from "pinia";
import { getConfig } from "/@/config";
import { storageLocal } from "/@/utils/storage";
import { deviceDetection } from "/@/utils/deviceDetection";
import type { StorageConfigs } from "/#/index";
import { deviceDetection, storageLocal } from "@pureadmin/utils";
export const useAppStore = defineStore({
id: "pure-app",
state: (): appType => ({
sidebar: {
opened:
storageLocal.getItem("responsive-layout")?.sidebarStatus ??
getConfig().SidebarStatus,
storageLocal.getItem<StorageConfigs>("responsive-layout")
?.sidebarStatus ?? getConfig().SidebarStatus,
withoutAnimation: false,
isClickHamburger: false
},
// 这里的layout用于监听容器拖拉后恢复对应的导航模式
layout:
storageLocal.getItem("responsive-layout")?.layout ?? getConfig().Layout,
storageLocal.getItem<StorageConfigs>("responsive-layout")?.layout ??
getConfig().Layout,
device: deviceDetection() ? "mobile" : "desktop"
}),
getters: {
@ -30,7 +31,7 @@ export const useAppStore = defineStore({
},
actions: {
TOGGLE_SIDEBAR(opened?: boolean, resize?: string) {
const layout = storageLocal.getItem("responsive-layout");
const layout = storageLocal.getItem<StorageConfigs>("responsive-layout");
if (opened && resize) {
this.sidebar.withoutAnimation = true;
this.sidebar.opened = true;

View File

@ -1,16 +1,18 @@
import { store } from "/@/store";
import { defineStore } from "pinia";
import { getConfig } from "/@/config";
import { storageLocal } from "/@/utils/storage";
import type { StorageConfigs } from "/#/index";
import { storageLocal } from "@pureadmin/utils";
export const useEpThemeStore = defineStore({
id: "pure-epTheme",
state: () => ({
epThemeColor:
storageLocal.getItem("responsive-layout")?.epThemeColor ??
storageLocal.getItem<StorageConfigs>("responsive-layout")?.epThemeColor ??
getConfig().EpThemeColor,
epTheme:
storageLocal.getItem("responsive-layout")?.theme ?? getConfig().Theme
storageLocal.getItem<StorageConfigs>("responsive-layout")?.theme ??
getConfig().Theme
}),
getters: {
getEpThemeColor() {
@ -29,7 +31,7 @@ export const useEpThemeStore = defineStore({
},
actions: {
setEpThemeColor(newColor: string): void {
const layout = storageLocal.getItem("responsive-layout");
const layout = storageLocal.getItem<StorageConfigs>("responsive-layout");
this.epTheme = layout?.theme;
this.epThemeColor = newColor;
layout.epThemeColor = newColor;

View File

@ -1,19 +1,21 @@
import { defineStore } from "pinia";
import { store } from "/@/store";
import { isUrl } from "/@/utils/is";
import { isEqual } from "lodash-unified";
import type { StorageConfigs } from "/#/index";
import { routerArrays } from "/@/layout/types";
import { storageLocal } from "/@/utils/storage";
import { multiType, positionType } from "./types";
import { isUrl, storageLocal } from "@pureadmin/utils";
export const useMultiTagsStore = defineStore({
id: "pure-multiTags",
state: () => ({
// 存储标签页信息(路由信息)
multiTags: storageLocal.getItem("responsive-configure").multiTagsCache
? storageLocal.getItem("responsive-tags")
multiTags: storageLocal.getItem<StorageConfigs>("responsive-configure")
.multiTagsCache
? storageLocal.getItem<StorageConfigs>("responsive-tags")
: [...routerArrays],
multiTagsCache: storageLocal.getItem("responsive-configure").multiTagsCache
multiTagsCache: storageLocal.getItem<StorageConfigs>("responsive-configure")
.multiTagsCache
}),
getters: {
getMultiTagsCache() {

View File

@ -3,7 +3,7 @@ import { store } from "/@/store";
import { userType } from "./types";
import { router } from "/@/router";
import { routerArrays } from "/@/layout/types";
import { storageSession } from "/@/utils/storage";
import { storageSession } from "@pureadmin/utils";
import { getLogin, refreshToken } from "/@/api/user";
import { getToken, setToken, removeToken } from "/@/utils/auth";
import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";

5
src/utils/README.md Normal file
View File

@ -0,0 +1,5 @@
### 备注
- [文档](https://pure-admin-utils.vercel.app)
- [npm](https://www.npmjs.com/package/@pureadmin/utils)
- vue-pure-admin 从 3.3.0 版本之后(不包括 3.3.0 版本),大部分工具和 hooks 都集成到了[@pureadmin/utils](https://pure-admin-utils.vercel.app)

View File

@ -1,39 +0,0 @@
import { unref } from "vue";
import type { Ref } from "vue";
type FunctionArgs<Args extends any[] = any[], Return = void> = (
...args: Args
) => Return;
type MaybeRef<T> = T | Ref<T>;
// 延迟函数
export const delay = (timeout: number) =>
new Promise(resolve => setTimeout(resolve, timeout));
/**
*
* @param fn
* @param timeout
* @param immediate
* @returns
*/
export const debounce = <T extends FunctionArgs>(
fn: T,
timeout: MaybeRef<number> = 200,
immediate = false
) => {
let timmer: TimeoutHandle;
const wait = unref(timeout);
return () => {
timmer && clearTimeout(timmer);
if (immediate) {
if (!timmer) {
fn();
}
timmer = setTimeout(() => (timmer = null), wait);
} else {
timmer = setTimeout(fn, wait);
}
};
};

View File

@ -1,37 +0,0 @@
interface deviceInter {
match: Fn;
}
interface BrowserInter {
browser: string;
version: string;
}
// 检测设备类型(手机返回true,反之)
export const deviceDetection = () => {
const sUserAgent: deviceInter = navigator.userAgent.toLowerCase();
// const bIsIpad = sUserAgent.match(/ipad/i) == "ipad";
const bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
const bIsMidp = sUserAgent.match(/midp/i) == "midp";
const bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
const bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
const bIsAndroid = sUserAgent.match(/android/i) == "android";
const bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
const bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";
return (
bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM
);
};
// 获取浏览器型号以及版本
export const getBrowserInfo = () => {
const ua = navigator.userAgent.toLowerCase();
const re = /(msie|firefox|chrome|opera|version).*?([\d.]+)/;
const m = ua.match(re);
const Sys: BrowserInter = {
browser: m[1].replace(/version/, "'safari"),
version: m[2]
};
return Sys;
};

View File

@ -1,9 +0,0 @@
import type { App, Plugin } from "vue";
export const withInstall = <T>(component: T) => {
const comp = component as any;
comp.install = (app: App) => {
app.component(comp.name, component);
};
return component as T & Plugin;
};

View File

@ -1,118 +0,0 @@
const toString = Object.prototype.toString;
export function is(val: unknown, type: string) {
return toString.call(val) === `[object ${type}]`;
}
export function isDef<T = unknown>(val?: T): val is T {
return typeof val !== "undefined";
}
export function isUnDef<T = unknown>(val?: T): val is T {
return !isDef(val);
}
export function isObject(val: any): val is Record<any, any> {
return val !== null && is(val, "Object");
}
export function isEmpty<T = unknown>(val: T): val is T {
if (isArray(val) || isString(val)) {
return val.length === 0;
}
if (val instanceof Map || val instanceof Set) {
return val.size === 0;
}
if (isObject(val)) {
return Object.keys(val).length === 0;
}
return false;
}
export function isDate(val: unknown): val is Date {
return is(val, "Date");
}
export function isNull(val: unknown): val is null {
return val === null;
}
export function isNullAndUnDef(val: unknown): val is null | undefined {
return isUnDef(val) && isNull(val);
}
export function isNullOrUnDef(val: unknown): val is null | undefined {
return isUnDef(val) || isNull(val);
}
export function isNumber(val: unknown): val is number {
return is(val, "Number");
}
export function isPromise<T = any>(val: unknown): val is Promise<T> {
return (
is(val, "Promise") &&
isObject(val) &&
isFunction(val.then) &&
isFunction(val.catch)
);
}
export function isString(val: unknown): val is string {
return is(val, "String");
}
export function isFunction(val: unknown): val is Function {
return typeof val === "function";
}
export function isBoolean(val: unknown): val is boolean {
return is(val, "Boolean");
}
export function isRegExp(val: unknown): val is RegExp {
return is(val, "RegExp");
}
export function isArray(val: any): val is Array<any> {
return val && Array.isArray(val);
}
export function isWindow(val: any): val is Window {
return typeof window !== "undefined" && is(val, "Window");
}
export function isElement(val: unknown): val is Element {
return isObject(val) && !!val.tagName;
}
export const isServer = typeof window === "undefined";
export const isClient = !isServer;
/** url链接正则 */
export function isUrl<T>(value: T): boolean {
const reg =
// eslint-disable-next-line no-useless-escape
/(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
// @ts-expect-error
return reg.test(value);
}
/** 手机号码正则 */
export function isPhone<T>(value: T): boolean {
const reg =
/^[1](([3][0-9])|([4][0,1,4-9])|([5][0-3,5-9])|([6][2,5,6,7])|([7][0-8])|([8][0-9])|([9][0-3,5-9]))[0-9]{8}$/;
// @ts-expect-error
return reg.test(value);
}
/** 邮箱正则 */
export function isEmail<T>(value: T): boolean {
const reg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
// @ts-expect-error
return reg.test(value);
}

View File

@ -1,13 +0,0 @@
export const openLink = <T>(link: T): void => {
const $a: HTMLElement = document.createElement("a");
// @ts-expect-error
$a.setAttribute("href", link);
$a.setAttribute("target", "_blank");
$a.setAttribute("rel", "noreferrer noopener");
$a.setAttribute("id", "external");
document.getElementById("external") &&
document.body.removeChild(document.getElementById("external"));
document.body.appendChild($a);
$a.click();
$a.remove();
};

View File

@ -1,54 +0,0 @@
interface ProxyLoader {
loadCss(src: string): any;
loadScript(src: string): Promise<any>;
loadScriptConcurrent(src: Array<string>): Promise<any>;
}
class loaderProxy implements ProxyLoader {
constructor() {}
protected scriptLoaderCache: Array<string> = [];
public loadCss = (src: string): any => {
const element: HTMLLinkElement = document.createElement("link");
element.rel = "stylesheet";
element.href = src;
document.body.appendChild(element);
};
public loadScript = async (src: string): Promise<any> => {
if (this.scriptLoaderCache.includes(src)) {
return src;
} else {
const element: HTMLScriptElement = document.createElement("script");
element.src = src;
document.body.appendChild(element);
element.onload = () => {
return this.scriptLoaderCache.push(src);
};
}
};
public loadScriptConcurrent = async (
srcList: Array<string>
): Promise<any> => {
if (Array.isArray(srcList)) {
const len: number = srcList.length;
if (len > 0) {
let count = 0;
srcList.map(src => {
if (src) {
this.loadScript(src).then(() => {
count++;
if (count === len) {
return;
}
});
}
});
}
}
};
}
export const loader = new loaderProxy();

View File

@ -1,38 +0,0 @@
import { ElMessage } from "element-plus";
// 消息
const Message = (message: string): any => {
return ElMessage({
showClose: true,
message
});
};
// 成功
const successMessage = (message: string): any => {
return ElMessage({
showClose: true,
message,
type: "success"
});
};
// 警告
const warnMessage = (message: string): any => {
return ElMessage({
showClose: true,
message,
type: "warning"
});
};
// 失败
const errorMessage = (message: string): any => {
return ElMessage({
showClose: true,
message,
type: "error"
});
};
export { Message, successMessage, warnMessage, errorMessage };

View File

@ -1,57 +0,0 @@
import type { FunctionArgs } from "@vueuse/core";
export const hasClass = (ele: RefType<any>, cls: string): any => {
return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
};
export const addClass = (
ele: RefType<any>,
cls: string,
extracls?: string
): any => {
if (!hasClass(ele, cls)) ele.className += " " + cls;
if (extracls) {
if (!hasClass(ele, extracls)) ele.className += " " + extracls;
}
};
export const removeClass = (
ele: RefType<any>,
cls: string,
extracls?: string
): any => {
if (hasClass(ele, cls)) {
const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
ele.className = ele.className.replace(reg, " ").trim();
}
if (extracls) {
if (hasClass(ele, extracls)) {
const regs = new RegExp("(\\s|^)" + extracls + "(\\s|$)");
ele.className = ele.className.replace(regs, " ").trim();
}
}
};
export const toggleClass = (
flag: boolean,
clsName: string,
target?: RefType<any>
): any => {
const targetEl = target || document.body;
let { className } = targetEl;
className = className.replace(clsName, "");
targetEl.className = flag ? `${className} ${clsName} ` : className;
};
export function useRafThrottle<T extends FunctionArgs>(fn: T): T {
let locked = false;
// @ts-ignore
return function (...args) {
if (locked) return;
locked = true;
window.requestAnimationFrame(() => {
fn.apply(this, args);
locked = false;
});
};
}

View File

@ -1,35 +0,0 @@
import ResizeObserver from "resize-observer-polyfill";
const isServer = typeof window === "undefined";
const resizeHandler = (entries: any[]): void => {
for (const entry of entries) {
const listeners = entry.target.__resizeListeners__ || [];
if (listeners.length) {
listeners.forEach((fn: () => any) => {
fn();
});
}
}
};
export const addResizeListener = (element: any, fn: () => any): any => {
if (isServer) return;
if (!element.__resizeListeners__) {
element.__resizeListeners__ = [];
element.__ro__ = new ResizeObserver(resizeHandler);
element.__ro__.observe(element);
}
element.__resizeListeners__.push(fn);
};
export const removeResizeListener = (element: any, fn: () => any): any => {
if (!element || !element.__resizeListeners__) return;
element.__resizeListeners__.splice(
element.__resizeListeners__.indexOf(fn),
1
);
if (!element.__resizeListeners__.length) {
element.__ro__.disconnect();
}
};

View File

@ -1,46 +0,0 @@
interface ProxyStorage {
getItem(key: string): any;
setItem(Key: string, value: string): void;
removeItem(key: string): void;
clear(): void;
}
//sessionStorage operate
class sessionStorageProxy implements ProxyStorage {
protected storage: ProxyStorage;
constructor(storageModel: ProxyStorage) {
this.storage = storageModel;
}
// 存
public setItem(key: string, value: any): void {
this.storage.setItem(key, JSON.stringify(value));
}
// 取
public getItem(key: string): any {
return JSON.parse(this.storage.getItem(key));
}
// 删
public removeItem(key: string): void {
this.storage.removeItem(key);
}
// 清空
public clear(): void {
this.storage.clear();
}
}
//localStorage operate
class localStorageProxy extends sessionStorageProxy implements ProxyStorage {
constructor(localStorage: ProxyStorage) {
super(localStorage);
}
}
export const storageSession = new sessionStorageProxy(sessionStorage);
export const storageLocal = new localStorageProxy(localStorage);

View File

@ -1,175 +0,0 @@
/**
* uniqueId
* @param {Array} {menuTree }
* @param {return}} expandedPaths uniqueId组成的数组
*/
const expandedPaths = [];
export function extractPathList(menuTree) {
if (!Array.isArray(menuTree)) {
console.warn("menuTree must be an array");
return;
}
if (!menuTree || menuTree.length === 0) return;
for (const node of menuTree) {
const hasChildren = node.children && node.children.length > 0;
if (hasChildren) {
extractPathList(node.children);
}
expandedPaths.push(node.uniqueId);
}
return expandedPaths;
}
/**
* children的length为1children并自动组建唯一uniqueId
* @param {Array} {menuTree }
* @param {Array} {pathList id组成的数组}
* @param {return}}
*/
export function deleteChildren(menuTree, pathList = []) {
if (!Array.isArray(menuTree)) {
console.warn("menuTree must be an array");
return;
}
if (!menuTree || menuTree.length === 0) return;
for (const [key, node] of menuTree.entries()) {
if (node.children && node.children.length === 1) delete node.children;
node.id = key;
node.parentId = pathList.length ? pathList[pathList.length - 1] : null;
node.pathList = [...pathList, node.id];
node.uniqueId =
node.pathList.length > 1 ? node.pathList.join("-") : node.pathList[0];
const hasChildren = node.children && node.children.length > 0;
if (hasChildren) {
deleteChildren(node.children, node.pathList);
}
}
return menuTree;
}
// 创建层级关系
export function buildHierarchyTree(menuTree, pathList = []) {
if (!Array.isArray(menuTree)) {
console.warn("menuTree must be an array");
return;
}
if (!menuTree || menuTree.length === 0) return;
for (const [key, node] of menuTree.entries()) {
node.id = key;
node.parentId = pathList.length ? pathList[pathList.length - 1] : null;
node.pathList = [...pathList, node.id];
const hasChildren = node.children && node.children.length > 0;
if (hasChildren) {
buildHierarchyTree(node.children, node.pathList);
}
}
return menuTree;
}
/**
* 广
* @param {Array} tree
* @param {Number|String} uniqueId uniqueId
* @return {Object} node
*/
export function getNodeByUniqueId(menuTree, uniqueId) {
if (!Array.isArray(menuTree)) {
console.warn("menuTree must be an array");
return;
}
if (!menuTree || menuTree.length === 0) return;
const item = menuTree.find(node => node.uniqueId === uniqueId);
if (item) return item;
const childrenList = menuTree
.filter(node => node.children)
.map(i => i.children)
.flat(1);
return getNodeByUniqueId(childrenList, uniqueId);
}
/**
* uniqueId节点追加字段
* @param {Array} {menuTree }
* @param {Number|String} uniqueId uniqueId
* @param {Object} fields uniqueId
* @return {menuTree}
*/
export function appendFieldByUniqueId(
menuTree: Array<any>,
uniqueId: Number | String,
fields: Object
) {
if (!Array.isArray(menuTree)) {
console.warn("menuTree must be an array");
return;
}
if (!menuTree || menuTree.length === 0) return {};
for (const node of menuTree) {
const hasChildren = node.children && node.children.length > 0;
if (
node.uniqueId === uniqueId &&
Object.prototype.toString.call(fields) === "[object Object]"
)
Object.assign(node, fields);
if (hasChildren) {
appendFieldByUniqueId(node.children, uniqueId, fields);
}
}
return menuTree;
}
/**
*
* @param {*} data
* @param {*} id id字段 'id'
* @param {*} parentId 'parentId'
* @param {*} children 'children'
*/
export function handleTree(
data,
id?: string,
parentId?: string,
children?: string
) {
const config = {
id: id || "id",
parentId: parentId || "parentId",
childrenList: children || "children"
};
const childrenListMap = {};
const nodeIds = {};
const tree = [];
for (const d of data) {
const parentId = d[config.parentId];
if (childrenListMap[parentId] == null) {
childrenListMap[parentId] = [];
}
nodeIds[d[config.id]] = d;
childrenListMap[parentId].push(d);
}
for (const d of data) {
const parentId = d[config.parentId];
if (nodeIds[parentId] == null) {
tree.push(d);
}
}
for (const t of tree) {
adaptToChildrenList(t);
}
function adaptToChildrenList(o) {
if (childrenListMap[o[config.id]] !== null) {
o[config.childrenList] = childrenListMap[o[config.id]];
}
if (o[config.childrenList]) {
for (const c of o[config.childrenList]) {
adaptToChildrenList(c);
}
}
}
return tree;
}

View File

@ -1,42 +0,0 @@
import { getCurrentInstance, reactive, shallowRef, watchEffect } from "vue";
import type { Ref } from "vue";
interface Params {
excludeListeners?: boolean;
excludeKeys?: string[];
}
const DEFAULT_EXCLUDE_KEYS = ["class", "style"];
const LISTENER_PREFIX = /^on[A-Z]/;
export function entries<T>(obj: Recordable<T>): [string, T][] {
return Object.keys(obj).map((key: string) => [key, obj[key]]);
}
export function useAttrs(params: Params = {}): Ref<Recordable> | {} {
const instance = getCurrentInstance();
if (!instance) return {};
const { excludeListeners = false, excludeKeys = [] } = params;
const attrs = shallowRef({});
const allExcludeKeys = excludeKeys.concat(DEFAULT_EXCLUDE_KEYS);
// Since attrs are not reactive, make it reactive instead of doing in `onUpdated` hook for better performance
instance.attrs = reactive(instance.attrs);
watchEffect(() => {
const res = entries(instance.attrs).reduce((acm, [key, val]) => {
if (
!allExcludeKeys.includes(key) &&
!(excludeListeners && LISTENER_PREFIX.test(key))
) {
acm[key] = val;
}
return acm;
}, {} as Recordable);
attrs.value = res;
});
return attrs;
}

View File

@ -1,4 +0,0 @@
import { h, resolveComponent } from "vue";
export const dynamicComponent = (component: string) =>
h(resolveComponent(component));

View File

@ -1,72 +0,0 @@
import { ref, watch } from "vue";
import { isDef } from "/@/utils/is";
interface Options {
target?: HTMLElement;
}
export function useCopyToClipboard(initial?: string) {
const clipboardRef = ref(initial || "");
const isSuccessRef = ref(false);
const copiedRef = ref(false);
watch(
clipboardRef,
(str?: string) => {
if (isDef(str)) {
copiedRef.value = true;
isSuccessRef.value = copyTextToClipboard(str);
}
},
{ immediate: !!initial, flush: "sync" }
);
return { clipboardRef, isSuccessRef, copiedRef };
}
export function copyTextToClipboard(
input: string,
{ target = document.body }: Options = {}
) {
const element = document.createElement("textarea");
const previouslyFocusedElement = document.activeElement;
element.value = input;
element.setAttribute("readonly", "");
(element.style as any).contain = "strict";
element.style.position = "absolute";
element.style.left = "-9999px";
element.style.fontSize = "12pt";
const selection = document.getSelection();
let originalRange;
if (selection && selection.rangeCount > 0) {
originalRange = selection.getRangeAt(0);
}
target.append(element);
element.select();
element.selectionStart = 0;
element.selectionEnd = input.length;
let isSuccess = false;
try {
isSuccess = document.execCommand("copy");
} catch (e) {
throw new Error(e);
}
element.remove();
if (originalRange && selection) {
selection.removeAllRanges();
selection.addRange(originalRange);
}
if (previouslyFocusedElement) {
(previouslyFocusedElement as HTMLElement).focus();
}
return isSuccess;
}

View File

@ -1,28 +0,0 @@
const hexList: string[] = [];
for (let i = 0; i <= 15; i++) {
hexList[i] = i.toString(16);
}
export function buildUUID(): string {
let uuid = "";
for (let i = 1; i <= 36; i++) {
if (i === 9 || i === 14 || i === 19 || i === 24) {
uuid += "-";
} else if (i === 15) {
uuid += 4;
} else if (i === 20) {
uuid += hexList[(Math.random() * 4) | 8];
} else {
uuid += hexList[(Math.random() * 16) | 0];
}
}
return uuid.replace(/-/g, "");
}
let unique = 0;
export function buildShortUUID(prefix = ""): string {
const time = Date.now();
const random = Math.floor(Math.random() * 1000000000);
unique++;
return prefix + "_" + random + unique + String(time);
}

View File

@ -1,116 +0,0 @@
import {
ref,
Ref,
unref,
shallowRef,
onBeforeUnmount,
getCurrentInstance
} from "vue";
import { isDef } from "/@/utils/is";
import { useRafThrottle } from "/@/utils/operate";
import { addResizeListener, removeResizeListener } from "/@/utils/resize";
const domSymbol = Symbol("watermark-dom");
type attr = {
font?: string;
fillStyle?: string;
};
export function useWatermark(
appendEl: Ref<HTMLElement | null> = ref(document.body) as Ref<HTMLElement>
) {
const func = useRafThrottle(function () {
const el = unref(appendEl);
if (!el) return;
const { clientHeight: height, clientWidth: width } = el;
updateWatermark({ height, width });
});
const id = domSymbol.toString();
const watermarkEl = shallowRef<HTMLElement>();
const clear = () => {
const domId = unref(watermarkEl);
watermarkEl.value = undefined;
const el = unref(appendEl);
if (!el) return;
domId && el.removeChild(domId);
removeResizeListener(el, func);
};
function createBase64(str: string, attr?: attr) {
const can = document.createElement("canvas");
const width = 300;
const height = 240;
Object.assign(can, { width, height });
const cans = can.getContext("2d");
if (cans) {
cans.rotate((-20 * Math.PI) / 120);
cans.font = attr?.font ?? "15px Reggae One";
cans.fillStyle = attr?.fillStyle ?? "rgba(0, 0, 0, 0.15)";
cans.textAlign = "left";
cans.textBaseline = "middle";
cans.fillText(str, width / 20, height);
}
return can.toDataURL("image/png");
}
function updateWatermark(
options: {
width?: number;
height?: number;
str?: string;
attr?: attr;
} = {}
) {
const el = unref(watermarkEl);
if (!el) return;
if (isDef(options.width)) {
el.style.width = `${options.width}px`;
}
if (isDef(options.height)) {
el.style.height = `${options.height}px`;
}
if (isDef(options.str)) {
el.style.background = `url(${createBase64(
options.str,
options.attr
)}) left top repeat`;
}
}
const createWatermark = (str: string, attr?: attr) => {
if (unref(watermarkEl)) {
updateWatermark({ str, attr });
return id;
}
const div = document.createElement("div");
watermarkEl.value = div;
div.id = id;
div.style.pointerEvents = "none";
div.style.top = "0px";
div.style.left = "0px";
div.style.position = "absolute";
div.style.zIndex = "100000";
const el = unref(appendEl);
if (!el) return id;
const { clientHeight: height, clientWidth: width } = el;
updateWatermark({ str, width, height, attr });
el.appendChild(div);
return id;
};
function setWatermark(str: string, attr?: attr) {
createWatermark(str, attr);
addResizeListener(document.documentElement, func);
const instance = getCurrentInstance();
if (instance) {
onBeforeUnmount(() => {
clear();
});
}
}
return { setWatermark, clear };
}

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { ElMessage } from "element-plus";
import { debounce } from "/@/utils/debounce";
import { debounce } from "@pureadmin/utils";
import { useDebounceFn, useThrottleFn } from "@vueuse/core";
defineOptions({

View File

@ -2,7 +2,7 @@
import { computed } from "vue";
import { transformI18n } from "/@/plugins/i18n";
import ElTreeLine from "/@/components/ReTreeLine";
import { extractPathList, deleteChildren } from "/@/utils/tree";
import { extractPathList, deleteChildren } from "@pureadmin/utils";
import { usePermissionStoreHook } from "/@/store/modules/permission";
defineOptions({

View File

@ -3,7 +3,7 @@ import { ref, computed } from "vue";
import type { ElTreeV2 } from "element-plus";
import { transformI18n } from "/@/plugins/i18n";
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
import { extractPathList, deleteChildren } from "/@/utils/tree";
import { extractPathList, deleteChildren } from "@pureadmin/utils";
import { usePermissionStoreHook } from "/@/store/modules/permission";
import type { TreeNode } from "element-plus/es/components/tree-v2/src/types";

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref } from "vue";
import { useWatermark } from "/@/utils/watermark";
import { useWatermark } from "@pureadmin/utils";
defineOptions({
name: "WaterMark"

View File

@ -2,8 +2,8 @@
import { onMounted } from "vue";
import Player from "xgplayer/dist/simple_player";
import volume from "xgplayer/es/controls/volume";
import { deviceDetection } from "@pureadmin/utils";
import screenShot from "xgplayer/es/controls/screenShot";
import { deviceDetection } from "/@/utils/deviceDetection";
import playbackRate from "xgplayer/es/controls/playbackRate";
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, onBeforeMount } from "vue";
import { loader } from "/@/utils/loaders";
import { useLoader } from "@pureadmin/utils";
import { ElDesignForm } from "vue-form-create2";
defineOptions({
@ -8,13 +8,14 @@ defineOptions({
});
const loading = ref(true);
const { loadScript } = useLoader();
onBeforeMount(() => {
loader
.loadScript("https://unpkg.com/ace-builds/src-noconflict/ace.js")
.then(() => {
loading.value = false;
});
loadScript({
src: "https://unpkg.com/ace-builds/src-noconflict/ace.js"
}).then(message => {
if (message === "success") loading.value = false;
});
});
</script>

View File

@ -9,7 +9,7 @@ import update from "./components/update.vue";
import { initRouter } from "/@/router/utils";
import { message } from "@pureadmin/components";
import type { FormInstance } from "element-plus";
import { storageSession } from "/@/utils/storage";
import { storageSession } from "@pureadmin/utils";
import { ref, reactive, watch, computed } from "vue";
import { operates, thirdParty } from "./utils/enums";
import { useUserStoreHook } from "/@/store/modules/user";

View File

@ -1,5 +1,5 @@
import { reactive } from "vue";
import { isPhone } from "/@/utils/is";
import { isPhone } from "@pureadmin/utils";
import type { FormRules } from "element-plus";
import { useUserStoreHook } from "/@/store/modules/user";

View File

@ -1,12 +1,15 @@
<script setup lang="ts">
import { ref } from "vue";
import { storageSession } from "/@/utils/storage";
import type { StorageConfigs } from "/#/index";
import { storageSession } from "@pureadmin/utils";
defineOptions({
name: "PermissionButton"
});
const auth = ref<boolean>(storageSession.getItem("info").username || "admin");
const auth = ref(
storageSession.getItem<StorageConfigs>("info").username || "admin"
);
function changRole(value) {
storageSession.setItem("info", {

View File

@ -1,13 +1,16 @@
<script setup lang="ts">
import { ref, unref } from "vue";
import { storageSession } from "/@/utils/storage";
import type { StorageConfigs } from "/#/index";
import { storageSession } from "@pureadmin/utils";
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
defineOptions({
name: "PermissionPage"
});
let purview = ref<string>(storageSession.getItem("info").username);
let purview = ref<string>(
storageSession.getItem<StorageConfigs>("info").username
);
function changRole() {
if (unref(purview) === "admin") {

View File

@ -1,6 +1,6 @@
<script setup lang="ts">
import { useColumns } from "./columns";
import { handleTree } from "/@/utils/tree";
import { handleTree } from "@pureadmin/utils";
import { getDeptList } from "/@/api/system";
import { FormInstance } from "element-plus";
import { reactive, ref, onMounted } from "vue";

View File

@ -4,8 +4,8 @@ import Config from "./config.vue";
import { useI18n } from "vue-i18n";
import { cloneDeep } from "lodash-unified";
import { reactive, ref, unref, nextTick } from "vue";
import { useCopyToClipboard } from "@pureadmin/utils";
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
import { useCopyToClipboard } from "/@/utils/useCopyToClipboard";
import {
VXETable,
type TablePublicMethods,

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import type { ElTree } from "element-plus";
import { handleTree } from "/@/utils/tree";
import { getDeptList } from "/@/api/system";
import { handleTree } from "@pureadmin/utils";
import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
import { ref, watch, onMounted, getCurrentInstance } from "vue";

View File

@ -8,7 +8,7 @@ import {
deleteChildren,
appendFieldByUniqueId,
getNodeByUniqueId
} from "/@/utils/tree";
} from "@pureadmin/utils";
import { useDetail } from "./hooks";
defineOptions({

28
types/index.ts Normal file
View File

@ -0,0 +1,28 @@
export interface StorageConfigs {
version?: string;
title?: string;
fixedHeader?: boolean;
hiddenSideBar?: boolean;
multiTagsCache?: boolean;
keepAlive?: boolean;
locale?: string;
layout?: string;
theme?: string;
darkMode?: boolean;
grey?: boolean;
weak?: boolean;
hideTabs?: boolean;
sidebarStatus?: boolean;
epThemeColor?: string;
showLogo?: boolean;
showModel?: string;
mapConfigure?: {
amapKey?: string;
options: {
resizeEnable?: boolean;
center?: number[];
zoom?: number;
};
};
username?: string;
}