mirror of
https://github.com/pure-admin/pure-admin-thin.git
synced 2025-04-25 16:07:19 +08:00
release: update 4.5.0
This commit is contained in:
parent
96a39b3974
commit
a9ba7cbe61
@ -13,6 +13,7 @@ const include = [
|
|||||||
"vue-i18n",
|
"vue-i18n",
|
||||||
"js-cookie",
|
"js-cookie",
|
||||||
"sortablejs",
|
"sortablejs",
|
||||||
|
"pinyin-pro",
|
||||||
"@vueuse/core",
|
"@vueuse/core",
|
||||||
"@pureadmin/utils",
|
"@pureadmin/utils",
|
||||||
"responsive-storage"
|
"responsive-storage"
|
||||||
|
29
package.json
29
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pure-admin-thin",
|
"name": "pure-admin-thin",
|
||||||
"version": "4.4.0",
|
"version": "4.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
|
"dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
|
||||||
@ -38,26 +38,27 @@
|
|||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"dayjs": "^1.11.8",
|
"dayjs": "^1.11.8",
|
||||||
"echarts": "^5.4.2",
|
"echarts": "^5.4.2",
|
||||||
"element-plus": "^2.3.6",
|
"element-plus": "^2.3.7",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"mitt": "^3.0.0",
|
"mitt": "^3.0.0",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
"pinia": "^2.1.4",
|
"pinia": "^2.1.4",
|
||||||
|
"pinyin-pro": "^3.15.2",
|
||||||
"qs": "^6.11.2",
|
"qs": "^6.11.2",
|
||||||
"responsive-storage": "^2.2.0",
|
"responsive-storage": "^2.2.0",
|
||||||
"sortablejs": "^1.15.0",
|
"sortablejs": "^1.15.0",
|
||||||
"vue": "^3.3.4",
|
"vue": "^3.3.4",
|
||||||
"vue-i18n": "^9.2.2",
|
"vue-i18n": "^9.2.2",
|
||||||
"vue-router": "^4.2.2",
|
"vue-router": "^4.2.2",
|
||||||
"vue-types": "^5.0.4"
|
"vue-types": "^5.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.6.5",
|
"@commitlint/cli": "^17.6.6",
|
||||||
"@commitlint/config-conventional": "^17.6.5",
|
"@commitlint/config-conventional": "^17.6.6",
|
||||||
"@iconify-icons/ep": "^1.2.11",
|
"@iconify-icons/ep": "^1.2.12",
|
||||||
"@iconify-icons/ri": "^1.2.8",
|
"@iconify-icons/ri": "^1.2.9",
|
||||||
"@iconify/vue": "^4.1.1",
|
"@iconify/vue": "^4.1.1",
|
||||||
"@intlify/unplugin-vue-i18n": "^0.11.0",
|
"@intlify/unplugin-vue-i18n": "^0.11.0",
|
||||||
"@pureadmin/theme": "^3.1.0",
|
"@pureadmin/theme": "^3.1.0",
|
||||||
@ -67,8 +68,8 @@
|
|||||||
"@types/nprogress": "0.2.0",
|
"@types/nprogress": "0.2.0",
|
||||||
"@types/qs": "^6.9.7",
|
"@types/qs": "^6.9.7",
|
||||||
"@types/sortablejs": "^1.15.1",
|
"@types/sortablejs": "^1.15.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
||||||
"@typescript-eslint/parser": "^5.59.11",
|
"@typescript-eslint/parser": "^5.60.0",
|
||||||
"@vitejs/plugin-vue": "^4.2.3",
|
"@vitejs/plugin-vue": "^4.2.3",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
||||||
"@vue/eslint-config-prettier": "^7.1.0",
|
"@vue/eslint-config-prettier": "^7.1.0",
|
||||||
@ -78,7 +79,7 @@
|
|||||||
"cssnano": "^6.0.1",
|
"cssnano": "^6.0.1",
|
||||||
"eslint": "^8.43.0",
|
"eslint": "^8.43.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-vue": "^9.15.0",
|
"eslint-plugin-vue": "^9.15.1",
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"lint-staged": "^13.2.2",
|
"lint-staged": "^13.2.2",
|
||||||
"picocolors": "^1.0.0",
|
"picocolors": "^1.0.0",
|
||||||
@ -90,9 +91,9 @@
|
|||||||
"pretty-quick": "^3.1.3",
|
"pretty-quick": "^3.1.3",
|
||||||
"rimraf": "^5.0.1",
|
"rimraf": "^5.0.1",
|
||||||
"rollup-plugin-visualizer": "^5.9.2",
|
"rollup-plugin-visualizer": "^5.9.2",
|
||||||
"sass": "^1.63.4",
|
"sass": "^1.63.6",
|
||||||
"sass-loader": "^13.3.2",
|
"sass-loader": "^13.3.2",
|
||||||
"stylelint": "^15.8.0",
|
"stylelint": "^15.9.0",
|
||||||
"stylelint-config-html": "^1.1.0",
|
"stylelint-config-html": "^1.1.0",
|
||||||
"stylelint-config-recess-order": "^4.2.0",
|
"stylelint-config-recess-order": "^4.2.0",
|
||||||
"stylelint-config-recommended": "^12.0.0",
|
"stylelint-config-recommended": "^12.0.0",
|
||||||
@ -105,7 +106,7 @@
|
|||||||
"stylelint-scss": "^5.0.1",
|
"stylelint-scss": "^5.0.1",
|
||||||
"svgo": "^3.0.2",
|
"svgo": "^3.0.2",
|
||||||
"tailwindcss": "^3.3.2",
|
"tailwindcss": "^3.3.2",
|
||||||
"terser": "^5.18.0",
|
"terser": "^5.18.1",
|
||||||
"typescript": "5.0.4",
|
"typescript": "5.0.4",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"vite-plugin-cdn-import": "^0.3.5",
|
"vite-plugin-cdn-import": "^0.3.5",
|
||||||
@ -114,7 +115,7 @@
|
|||||||
"vite-plugin-remove-console": "^2.1.1",
|
"vite-plugin-remove-console": "^2.1.1",
|
||||||
"vite-svg-loader": "^4.0.0",
|
"vite-svg-loader": "^4.0.0",
|
||||||
"vue-eslint-parser": "^9.3.1",
|
"vue-eslint-parser": "^9.3.1",
|
||||||
"vue-tsc": "^1.8.0"
|
"vue-tsc": "^1.8.1"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"peerDependencyRules": {
|
"peerDependencyRules": {
|
||||||
|
509
pnpm-lock.yaml
generated
509
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"Version": "4.4.0",
|
"Version": "4.5.0",
|
||||||
"Title": "PureAdmin",
|
"Title": "PureAdmin",
|
||||||
"FixedHeader": true,
|
"FixedHeader": true,
|
||||||
"HiddenSideBar": false,
|
"HiddenSideBar": false,
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
|
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
|
||||||
import { delay, getKeyList, cloneDeep } from "@pureadmin/utils";
|
|
||||||
import { defineComponent, ref, computed, type PropType, nextTick } from "vue";
|
import { defineComponent, ref, computed, type PropType, nextTick } from "vue";
|
||||||
|
import {
|
||||||
|
delay,
|
||||||
|
cloneDeep,
|
||||||
|
isBoolean,
|
||||||
|
isFunction,
|
||||||
|
getKeyList
|
||||||
|
} from "@pureadmin/utils";
|
||||||
|
|
||||||
import Sortable from "sortablejs";
|
import Sortable from "sortablejs";
|
||||||
import DragIcon from "./svg/drag.svg?component";
|
import DragIcon from "./svg/drag.svg?component";
|
||||||
@ -37,8 +43,13 @@ export default defineComponent({
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const checkAll = ref(true);
|
const checkAll = ref(true);
|
||||||
const isIndeterminate = ref(false);
|
const isIndeterminate = ref(false);
|
||||||
|
const filterColumns = cloneDeep(props?.columns).filter(column =>
|
||||||
|
isBoolean(column?.hide)
|
||||||
|
? !column.hide
|
||||||
|
: !(isFunction(column?.hide) && column?.hide())
|
||||||
|
);
|
||||||
let checkColumnList = getKeyList(cloneDeep(props?.columns), "label");
|
let checkColumnList = getKeyList(cloneDeep(props?.columns), "label");
|
||||||
const checkedColumns = ref(checkColumnList);
|
const checkedColumns = ref(getKeyList(cloneDeep(filterColumns), "label"));
|
||||||
const dynamicColumns = ref(cloneDeep(props?.columns));
|
const dynamicColumns = ref(cloneDeep(props?.columns));
|
||||||
|
|
||||||
const getDropdownItemStyle = computed(() => {
|
const getDropdownItemStyle = computed(() => {
|
||||||
@ -120,7 +131,7 @@ export default defineComponent({
|
|||||||
dynamicColumns.value = cloneDeep(props?.columns);
|
dynamicColumns.value = cloneDeep(props?.columns);
|
||||||
checkColumnList = [];
|
checkColumnList = [];
|
||||||
checkColumnList = await getKeyList(cloneDeep(props?.columns), "label");
|
checkColumnList = await getKeyList(cloneDeep(props?.columns), "label");
|
||||||
checkedColumns.value = checkColumnList;
|
checkedColumns.value = getKeyList(cloneDeep(filterColumns), "label");
|
||||||
}
|
}
|
||||||
|
|
||||||
const dropdown = {
|
const dropdown = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { hasAuth } from "@/router/utils";
|
import { hasAuth } from "@/router/utils";
|
||||||
import { Directive, type DirectiveBinding } from "vue";
|
import type { Directive, DirectiveBinding } from "vue";
|
||||||
|
|
||||||
export const auth: Directive = {
|
export const auth: Directive = {
|
||||||
mounted(el: HTMLElement, binding: DirectiveBinding) {
|
mounted(el: HTMLElement, binding: DirectiveBinding) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { message } from "@/utils/message";
|
import { message } from "@/utils/message";
|
||||||
import { useEventListener } from "@vueuse/core";
|
import { useEventListener } from "@vueuse/core";
|
||||||
import { copyTextToClipboard } from "@pureadmin/utils";
|
import { copyTextToClipboard } from "@pureadmin/utils";
|
||||||
import { Directive, type DirectiveBinding } from "vue";
|
import type { Directive, DirectiveBinding } from "vue";
|
||||||
|
|
||||||
interface CopyEl extends HTMLElement {
|
interface CopyEl extends HTMLElement {
|
||||||
copyValue: string;
|
copyValue: string;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
export * from "./auth";
|
export * from "./auth";
|
||||||
export * from "./copy";
|
export * from "./copy";
|
||||||
|
export * from "./longpress";
|
||||||
export * from "./optimize";
|
export * from "./optimize";
|
||||||
|
63
src/directives/longpress/index.ts
Normal file
63
src/directives/longpress/index.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { useEventListener } from "@vueuse/core";
|
||||||
|
import type { Directive, DirectiveBinding } from "vue";
|
||||||
|
import { subBefore, subAfter, isFunction } from "@pureadmin/utils";
|
||||||
|
|
||||||
|
export const longpress: Directive = {
|
||||||
|
mounted(el: HTMLElement, binding: DirectiveBinding) {
|
||||||
|
const cb = binding.value;
|
||||||
|
if (cb && isFunction(cb)) {
|
||||||
|
let timer = null;
|
||||||
|
let interTimer = null;
|
||||||
|
let num = 500;
|
||||||
|
let interNum = null;
|
||||||
|
const isInter = binding?.arg?.includes(":") ?? false;
|
||||||
|
|
||||||
|
if (isInter) {
|
||||||
|
num = Number(subBefore(binding.arg, ":"));
|
||||||
|
interNum = Number(subAfter(binding.arg, ":"));
|
||||||
|
} else if (binding.arg) {
|
||||||
|
num = Number(binding.arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clear = () => {
|
||||||
|
if (timer) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
|
if (interTimer) {
|
||||||
|
clearInterval(interTimer);
|
||||||
|
interTimer = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDownInter = (ev: PointerEvent) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
if (interTimer === null) {
|
||||||
|
interTimer = setInterval(() => cb(), interNum);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDown = (ev: PointerEvent) => {
|
||||||
|
clear();
|
||||||
|
ev.preventDefault();
|
||||||
|
if (timer === null) {
|
||||||
|
timer = isInter
|
||||||
|
? setTimeout(() => {
|
||||||
|
cb();
|
||||||
|
onDownInter(ev);
|
||||||
|
}, num)
|
||||||
|
: setTimeout(() => cb(), num);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register using addEventListener on mounted, and removeEventListener automatically on unmounted
|
||||||
|
useEventListener(el, "pointerdown", onDown);
|
||||||
|
useEventListener(el, "pointerup", clear);
|
||||||
|
useEventListener(el, "pointerleave", clear);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
'[Directive: longpress]: need callback and callback must be a function! Like v-longpress="callback"'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -6,7 +6,7 @@ import {
|
|||||||
throttle
|
throttle
|
||||||
} from "@pureadmin/utils";
|
} from "@pureadmin/utils";
|
||||||
import { useEventListener } from "@vueuse/core";
|
import { useEventListener } from "@vueuse/core";
|
||||||
import { Directive, type DirectiveBinding } from "vue";
|
import type { Directive, DirectiveBinding } from "vue";
|
||||||
|
|
||||||
/** 防抖(v-optimize或v-optimize:debounce)、节流(v-optimize:throttle)指令 */
|
/** 防抖(v-optimize或v-optimize:debounce)、节流(v-optimize:throttle)指令 */
|
||||||
export const optimize: Directive = {
|
export const optimize: Directive = {
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { match } from "pinyin-pro";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { cloneDeep } from "@pureadmin/utils";
|
|
||||||
import SearchResult from "./SearchResult.vue";
|
import SearchResult from "./SearchResult.vue";
|
||||||
import SearchFooter from "./SearchFooter.vue";
|
import SearchFooter from "./SearchFooter.vue";
|
||||||
import { useNav } from "@/layout/hooks/useNav";
|
import { useNav } from "@/layout/hooks/useNav";
|
||||||
import { transformI18n } from "@/plugins/i18n";
|
import { transformI18n } from "@/plugins/i18n";
|
||||||
import { ref, computed, shallowRef } from "vue";
|
import { ref, computed, shallowRef } from "vue";
|
||||||
|
import { cloneDeep, isAllEmpty } from "@pureadmin/utils";
|
||||||
import { useDebounceFn, onKeyStroke } from "@vueuse/core";
|
import { useDebounceFn, onKeyStroke } from "@vueuse/core";
|
||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||||
import Search from "@iconify-icons/ri/search-line";
|
import Search from "@iconify-icons/ri/search-line";
|
||||||
@ -23,6 +25,7 @@ const { device } = useNav();
|
|||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
const props = withDefaults(defineProps<Props>(), {});
|
const props = withDefaults(defineProps<Props>(), {});
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const { locale } = useI18n();
|
||||||
|
|
||||||
const keyword = ref("");
|
const keyword = ref("");
|
||||||
const scrollbarRef = ref();
|
const scrollbarRef = ref();
|
||||||
@ -62,12 +65,19 @@ function flatTree(arr) {
|
|||||||
/** 查询 */
|
/** 查询 */
|
||||||
function search() {
|
function search() {
|
||||||
const flatMenusData = flatTree(menusData.value);
|
const flatMenusData = flatTree(menusData.value);
|
||||||
resultOptions.value = flatMenusData.filter(
|
resultOptions.value = flatMenusData.filter(menu =>
|
||||||
menu =>
|
keyword.value
|
||||||
keyword.value &&
|
? transformI18n(menu.meta?.title)
|
||||||
transformI18n(menu.meta?.title)
|
.toLocaleLowerCase()
|
||||||
.toLocaleLowerCase()
|
.includes(keyword.value.toLocaleLowerCase().trim()) ||
|
||||||
.includes(keyword.value.toLocaleLowerCase().trim())
|
(locale.value === "zh" &&
|
||||||
|
!isAllEmpty(
|
||||||
|
match(
|
||||||
|
transformI18n(menu.meta?.title).toLocaleLowerCase(),
|
||||||
|
keyword.value.toLocaleLowerCase().trim()
|
||||||
|
)
|
||||||
|
))
|
||||||
|
: false
|
||||||
);
|
);
|
||||||
if (resultOptions.value?.length > 0) {
|
if (resultOptions.value?.length > 0) {
|
||||||
activePath.value = resultOptions.value[0].path;
|
activePath.value = resultOptions.value[0].path;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useI18n } from "vue-i18n";
|
import { transformI18n } from "@/plugins/i18n";
|
||||||
import { useResizeObserver } from "@vueuse/core";
|
import { useResizeObserver } from "@vueuse/core";
|
||||||
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
|
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
|
||||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||||
@ -7,8 +7,6 @@ import { ref, computed, getCurrentInstance, onMounted } from "vue";
|
|||||||
import enterOutlined from "@/assets/svg/enter_outlined.svg?component";
|
import enterOutlined from "@/assets/svg/enter_outlined.svg?component";
|
||||||
import Bookmark2Line from "@iconify-icons/ri/bookmark-2-line";
|
import Bookmark2Line from "@iconify-icons/ri/bookmark-2-line";
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
interface optionsItem {
|
interface optionsItem {
|
||||||
path: string;
|
path: string;
|
||||||
meta?: {
|
meta?: {
|
||||||
@ -98,7 +96,9 @@ defineExpose({ handleScroll });
|
|||||||
@mouseenter="handleMouse(item)"
|
@mouseenter="handleMouse(item)"
|
||||||
>
|
>
|
||||||
<component :is="useRenderIcon(item.meta?.icon ?? Bookmark2Line)" />
|
<component :is="useRenderIcon(item.meta?.icon ?? Bookmark2Line)" />
|
||||||
<span class="result-item-title">{{ t(item.meta?.title) }}</span>
|
<span class="result-item-title">
|
||||||
|
{{ transformI18n(item.meta?.title) }}
|
||||||
|
</span>
|
||||||
<enterOutlined />
|
<enterOutlined />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user