mirror of
				https://github.com/pure-admin/pure-admin-thin.git
				synced 2025-11-04 17:44:48 +08:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/main'
# Conflicts: # package.json # pnpm-lock.yaml # public/serverConfig.json
This commit is contained in:
		
						commit
						caba16e30f
					
				@ -12,6 +12,7 @@ const include = [
 | 
				
			|||||||
  "pinia",
 | 
					  "pinia",
 | 
				
			||||||
  "js-cookie",
 | 
					  "js-cookie",
 | 
				
			||||||
  "sortablejs",
 | 
					  "sortablejs",
 | 
				
			||||||
 | 
					  "pinyin-pro",
 | 
				
			||||||
  "@vueuse/core",
 | 
					  "@vueuse/core",
 | 
				
			||||||
  "@pureadmin/utils",
 | 
					  "@pureadmin/utils",
 | 
				
			||||||
  "responsive-storage"
 | 
					  "responsive-storage"
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										27
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								package.json
									
									
									
									
									
								
							@ -39,7 +39,7 @@
 | 
				
			|||||||
    "crypto-js": "^4.1.1",
 | 
					    "crypto-js": "^4.1.1",
 | 
				
			||||||
    "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.6",
 | 
				
			||||||
    "js-cookie": "^3.0.5",
 | 
					    "js-cookie": "^3.0.5",
 | 
				
			||||||
    "jsencrypt": "^3.3.2",
 | 
					    "jsencrypt": "^3.3.2",
 | 
				
			||||||
    "mitt": "^3.0.0",
 | 
					    "mitt": "^3.0.0",
 | 
				
			||||||
@ -48,19 +48,20 @@
 | 
				
			|||||||
    "path": "^0.12.7",
 | 
					    "path": "^0.12.7",
 | 
				
			||||||
    "pinia": "^2.1.4",
 | 
					    "pinia": "^2.1.4",
 | 
				
			||||||
    "qrcode": "^1.5.3",
 | 
					    "qrcode": "^1.5.3",
 | 
				
			||||||
 | 
					    "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",
 | 
				
			||||||
    "typeit": "^8.7.1",
 | 
					    "typeit": "^8.7.1",
 | 
				
			||||||
    "vue": "^3.3.4",
 | 
					    "vue": "^3.3.4",
 | 
				
			||||||
    "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",
 | 
				
			||||||
    "@pureadmin/theme": "^3.1.0",
 | 
					    "@pureadmin/theme": "^3.1.0",
 | 
				
			||||||
    "@types/js-cookie": "^3.0.3",
 | 
					    "@types/js-cookie": "^3.0.3",
 | 
				
			||||||
@ -69,8 +70,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",
 | 
				
			||||||
@ -80,7 +81,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",
 | 
				
			||||||
@ -92,9 +93,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",
 | 
				
			||||||
@ -107,7 +108,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",
 | 
				
			||||||
@ -116,7 +117,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": {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										650
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										650
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -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,10 +1,11 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { match } from "pinyin-pro";
 | 
				
			||||||
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 { 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";
 | 
				
			||||||
@ -61,12 +62,18 @@ 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 &&
 | 
					      ? menu.meta?.title
 | 
				
			||||||
      menu.meta?.title
 | 
					          .toLocaleLowerCase()
 | 
				
			||||||
        .toLocaleLowerCase()
 | 
					          .includes(keyword.value.toLocaleLowerCase().trim()) ||
 | 
				
			||||||
        .includes(keyword.value.toLocaleLowerCase().trim())
 | 
					        !isAllEmpty(
 | 
				
			||||||
 | 
					          match(
 | 
				
			||||||
 | 
					            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;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user