hookehuyr

🎉 init: 项目初始化

1 +dist/
2 +deploy_versions/
3 +.temp/
4 +.rn_temp/
5 +node_modules/
6 +.DS_Store
7 +.swc
8 +.history
1 +// babel-preset-taro 更多选项和默认值:
2 +// https://github.com/NervJS/taro/blob/next/packages/babel-preset-taro/README.md
3 +module.exports = {
4 + presets: [
5 + ['taro', {
6 + framework: 'vue3',
7 + ts: false
8 + }]
9 + ]
10 +}
1 +// generated by unplugin-vue-components
2 +// We suggest you to commit this file into source control
3 +// Read more: https://github.com/vuejs/core/pull/3399
4 +import '@vue/runtime-core'
5 +
6 +export {}
7 +
8 +declare module '@vue/runtime-core' {
9 + export interface GlobalComponents {
10 + NutButton: typeof import('@nutui/nutui-taro')['Button']
11 + NutCol: typeof import('@nutui/nutui-taro')['Col']
12 + NutRow: typeof import('@nutui/nutui-taro')['Row']
13 + RouterLink: typeof import('vue-router')['RouterLink']
14 + RouterView: typeof import('vue-router')['RouterView']
15 + }
16 +}
1 +module.exports = {
2 + env: {
3 + NODE_ENV: '"development"'
4 + },
5 + defineConstants: {
6 + },
7 + mini: {},
8 + h5: {}
9 +}
1 +const path = require('path')
2 +
3 +import ComponentsPlugin from 'unplugin-vue-components/webpack'
4 +import NutUIResolver from '@nutui/nutui-taro/dist/resolver'
5 +
6 +const config = {
7 + projectName: 'custom_form',
8 + date: '2023-3-23',
9 + designWidth(input) {
10 + if (input?.file?.replace(/\\+/g, '/').indexOf('@nutui') > -1) {
11 + return 375
12 + }
13 + return 750
14 + },
15 + deviceRatio: {
16 + 640: 2.34 / 2,
17 + 750: 1,
18 + 828: 1.81 / 2,
19 + 375: 2 / 1,
20 + },
21 + alias: {
22 + // 配置目录别名
23 + '@/utils': path.resolve(__dirname, '../src/utils'),
24 + '@/components': path.resolve(__dirname, '../src/components'),
25 + '@/images': path.resolve(__dirname, '../src/assets/images'),
26 + '@/assets': path.resolve(__dirname, '../src/assets'),
27 + '@/composables': path.resolve(__dirname, '../src/composables'),
28 + '@/api': path.resolve(__dirname, '../src/api'),
29 + '@/stores': path.resolve(__dirname, '../src/stores'),
30 + '@/hooks': path.resolve(__dirname, '../src/hooks'),
31 + },
32 + sourceRoot: 'src',
33 + outputRoot: `dist/${process.env.TARO_ENV}`,
34 + plugins: ['@tarojs/plugin-html'],
35 + defineConstants: {},
36 + copy: {
37 + patterns: [],
38 + options: {},
39 + },
40 + framework: 'vue3',
41 + compiler: {
42 + type: 'webpack5',
43 + prebundle: { enable: false },
44 + },
45 + cache: {
46 + enable: false, // Webpack 持久化缓存配置,建议开启。默认配置请参考:https://docs.taro.zone/docs/config-detail#cache
47 + },
48 + sass: {
49 + data: `@import "@nutui/nutui-taro/dist/styles/variables.scss";`,
50 + },
51 + mini: {
52 + webpackChain(chain) {
53 + chain.plugin('unplugin-vue-components').use(
54 + ComponentsPlugin({
55 + resolvers: [NutUIResolver({ taro: true })],
56 + }),
57 + )
58 + },
59 + postcss: {
60 + pxtransform: {
61 + enable: true,
62 + config: {
63 + // selectorBlackList: ['nut-']
64 + },
65 + },
66 + url: {
67 + enable: true,
68 + config: {
69 + limit: 1024, // 设定转换尺寸上限
70 + },
71 + },
72 + cssModules: {
73 + enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
74 + config: {
75 + namingPattern: 'module', // 转换模式,取值为 global/module
76 + generateScopedName: '[name]__[local]___[hash:base64:5]',
77 + },
78 + },
79 + },
80 + enableSourceMap: false
81 + },
82 + h5: {
83 + webpackChain(chain) {
84 + chain.plugin('unplugin-vue-components').use(
85 + ComponentsPlugin({
86 + resolvers: [NutUIResolver({ taro: true })],
87 + }),
88 + )
89 + },
90 + publicPath: '/',
91 + staticDirectory: 'static',
92 + esnextModules: ['nutui-taro', 'icons-vue-taro'],
93 + postcss: {
94 + autoprefixer: {
95 + enable: true,
96 + config: {},
97 + },
98 + cssModules: {
99 + enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
100 + config: {
101 + namingPattern: 'module', // 转换模式,取值为 global/module
102 + generateScopedName: '[name]__[local]___[hash:base64:5]',
103 + },
104 + },
105 + },
106 + },
107 +}
108 +
109 +module.exports = function (merge) {
110 + if (process.env.NODE_ENV === 'development') {
111 + return merge({}, config, require('./dev'))
112 + }
113 + return merge({}, config, require('./prod'))
114 +}
1 +module.exports = {
2 + env: {
3 + NODE_ENV: '"production"'
4 + },
5 + defineConstants: {
6 + },
7 + mini: {},
8 + h5: {
9 + /**
10 + * WebpackChain 插件配置
11 + * @docs https://github.com/neutrinojs/webpack-chain
12 + */
13 + // webpackChain (chain) {
14 + // /**
15 + // * 如果 h5 端编译后体积过大,可以使用 webpack-bundle-analyzer 插件对打包体积进行分析。
16 + // * @docs https://github.com/webpack-contrib/webpack-bundle-analyzer
17 + // */
18 + // chain.plugin('analyzer')
19 + // .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [])
20 +
21 + // /**
22 + // * 如果 h5 端首屏加载时间过长,可以使用 prerender-spa-plugin 插件预加载首页。
23 + // * @docs https://github.com/chrisvfritz/prerender-spa-plugin
24 + // */
25 + // const path = require('path')
26 + // const Prerender = require('prerender-spa-plugin')
27 + // const staticDir = path.join(__dirname, '..', 'dist')
28 + // chain
29 + // .plugin('prerender')
30 + // .use(new Prerender({
31 + // staticDir,
32 + // routes: [ '/pages/index/index' ],
33 + // postProcess: (context) => ({ ...context, outputPath: path.join(staticDir, 'index.html') })
34 + // }))
35 + // }
36 + }
37 +}
1 +{
2 + "name": "custom_form",
3 + "version": "1.0.0",
4 + "private": true,
5 + "description": "自定义表单",
6 + "templateInfo": {
7 + "name": "vue3-NutUI4",
8 + "typescript": false,
9 + "css": "less"
10 + },
11 + "scripts": {
12 + "build:weapp": "taro build --type weapp",
13 + "build:swan": "taro build --type swan",
14 + "build:alipay": "taro build --type alipay",
15 + "build:tt": "taro build --type tt",
16 + "build:h5": "taro build --type h5",
17 + "build:rn": "taro build --type rn",
18 + "build:qq": "taro build --type qq",
19 + "build:jd": "taro build --type jd",
20 + "build:quickapp": "taro build --type quickapp",
21 + "dev:weapp": "npm run build:weapp -- --watch",
22 + "dev:swan": "npm run build:swan -- --watch",
23 + "dev:alipay": "npm run build:alipay -- --watch",
24 + "dev:tt": "npm run build:tt -- --watch",
25 + "dev:h5": "npm run build:h5 -- --watch",
26 + "dev:rn": "npm run build:rn -- --watch",
27 + "dev:qq": "npm run build:qq -- --watch",
28 + "dev:jd": "npm run build:jd -- --watch",
29 + "dev:quickapp": "npm run build:quickapp -- --watch"
30 + },
31 + "browserslist": [
32 + "last 3 versions",
33 + "Android >= 4.1",
34 + "ios >= 8"
35 + ],
36 + "author": "",
37 + "license": "MIT",
38 + "dependencies": {
39 + "@babel/runtime": "^7.7.7",
40 + "@nutui/icons-vue-taro": "^0.0.9",
41 + "@nutui/nutui-taro": "^4.0.0",
42 + "@tarojs/components": "3.6.2",
43 + "@tarojs/helper": "3.6.2",
44 + "@tarojs/plugin-framework-vue3": "3.6.2",
45 + "@tarojs/plugin-html": "3.6.2",
46 + "@tarojs/plugin-platform-alipay": "3.6.2",
47 + "@tarojs/plugin-platform-h5": "3.6.2",
48 + "@tarojs/plugin-platform-jd": "3.6.2",
49 + "@tarojs/plugin-platform-qq": "3.6.2",
50 + "@tarojs/plugin-platform-swan": "3.6.2",
51 + "@tarojs/plugin-platform-tt": "3.6.2",
52 + "@tarojs/plugin-platform-weapp": "3.6.2",
53 + "@tarojs/runtime": "3.6.2",
54 + "@tarojs/shared": "3.6.2",
55 + "@tarojs/taro": "3.6.2",
56 + "dayjs": "^1.11.7",
57 + "pinia": "^2.0.33",
58 + "vue": "^3.0.0"
59 + },
60 + "devDependencies": {
61 + "@babel/core": "^7.8.0",
62 + "@tarojs/cli": "3.6.2",
63 + "@tarojs/webpack5-runner": "3.6.2",
64 + "@types/webpack-env": "^1.13.6",
65 + "@vue/babel-plugin-jsx": "^1.0.6",
66 + "@vue/compiler-sfc": "^3.0.0",
67 + "babel-preset-taro": "3.6.2",
68 + "css-loader": "3.4.2",
69 + "eslint": "^8.12.0",
70 + "eslint-config-taro": "3.6.2",
71 + "eslint-plugin-vue": "^8.0.0",
72 + "style-loader": "1.3.0",
73 + "stylelint": "9.3.0",
74 + "unplugin-vue-components": "^0.23.0",
75 + "vue-loader": "^17.0.0",
76 + "webpack": "5.69.0"
77 + }
78 +}
1 +{
2 + "miniprogramRoot": "./dist",
3 + "projectname": "custom_form",
4 + "description": "自定义表单",
5 + "appid": "touristappid",
6 + "setting": {
7 + "urlCheck": true,
8 + "es6": false,
9 + "enhance": false,
10 + "compileHotReLoad": false,
11 + "postcss": false,
12 + "minified": false
13 + },
14 + "compileType": "miniprogram"
15 +}
1 +{
2 + "miniprogramRoot": "./",
3 + "projectname": "custom_form",
4 + "description": "自定义表单",
5 + "appid": "touristappid",
6 + "setting": {
7 + "urlCheck": true,
8 + "es6": false,
9 + "postcss": false,
10 + "minified": false
11 + },
12 + "compileType": "miniprogram"
13 +}
1 +export default defineAppConfig({
2 + pages: [
3 + 'pages/index/index'
4 + ],
5 + window: {
6 + backgroundTextStyle: 'light',
7 + navigationBarBackgroundColor: '#fff',
8 + navigationBarTitleText: 'WeChat',
9 + navigationBarTextStyle: 'black'
10 + }
11 +})
1 +/*
2 + * @Date: 2023-03-23 11:17:54
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2023-03-23 13:47:12
5 + * @FilePath: /custom_form/src/app.js
6 + * @Description: 文件描述
7 + */
8 +import { createApp } from 'vue'
9 +import { createPinia } from 'pinia'
10 +import './app.less'
11 +
12 +const App = createApp({
13 + onShow (options) {},
14 + // 入口组件不需要实现 render 方法,即使实现了也会被 taro 所覆盖
15 +})
16 +
17 +App.use(createPinia())
18 +
19 +export default App
File mode changed
1 +<!DOCTYPE html>
2 +<html>
3 +<head>
4 + <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
5 + <meta content="width=device-width,initial-scale=1,user-scalable=no" name="viewport">
6 + <meta name="apple-mobile-web-app-capable" content="yes">
7 + <meta name="apple-touch-fullscreen" content="yes">
8 + <meta name="format-detection" content="telephone=no,address=no">
9 + <meta name="apple-mobile-web-app-status-bar-style" content="white">
10 + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" >
11 + <title>custom_form</title>
12 + <script><%= htmlWebpackPlugin.options.script %></script>
13 +</head>
14 +<body>
15 + <div id="app"></div>
16 +</body>
17 +</html>
1 +export default definePageConfig({
2 + navigationBarTitleText: '首页'
3 +})
1 +<template>
2 + <view class="index">
3 + <nut-row>
4 + <nut-col :span="is_pc ? 22 : 24" :offset="is_pc ? 1 : 0">
5 + <div style="background-color: red; color: white;">span:24</div>
6 + </nut-col>
7 + </nut-row>
8 + </view>
9 +</template>
10 +
11 +<script setup>
12 +import { storeToRefs } from 'pinia'
13 +import { mainStore } from '@/stores'
14 +import { wxInfo, getUrlParams } from "@/utils/tools";
15 +import { computed, watchEffect, onMounted } from "vue";
16 +
17 +// web端判断
18 +const is_pc = computed(() => process.env.TARO_ENV === 'h5' && wxInfo().isPC);
19 +
20 +const store = mainStore();
21 +const { formInfo } = storeToRefs(store);
22 +
23 +console.warn(is_pc.value);
24 +
25 +</script>
26 +
27 +<style lang="less">
28 +</style>
1 +/*
2 + * @Date: 2022-04-18 15:59:42
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2023-03-23 13:19:21
5 + * @FilePath: /custom_form/src/stores/index.js
6 + * @Description: 文件描述
7 + */
8 +import { defineStore } from 'pinia';
9 +// import { testStore } from './test'; // 另一个store
10 +
11 +export const mainStore = defineStore('main', {
12 + state: () => {
13 + return {
14 + fieldName: '',
15 + formInfo: {}, // 表单字段信息
16 + formSetting: {}, // 表单数据收集设置
17 + successInfo: {}, // 表单提交返回值
18 + };
19 + },
20 + getters: {
21 + getKeepPages () {
22 + return this.keepPages
23 + },
24 + // getTestStoreList () {
25 + // return testStore().list // 返回另一个store的值
26 + // }
27 + },
28 + actions: {
29 + changeFieldName (v) {
30 + this.fieldName = v;
31 + },
32 + changeFormInfo (v) {
33 + this.formInfo = v;
34 + },
35 + changeFormSetting (v) {
36 + this.formSetting = v;
37 + },
38 + changeSuccessInfo (v) {
39 + this.successInfo = v;
40 + },
41 + },
42 +});
1 +/*
2 + * @Date: 2022-06-20 01:22:50
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-06-20 01:23:18
5 + * @FilePath: /tswj/src/composables/useMonitorKeyboard.js
6 + * @Description: 文件描述
7 + */
8 +/**
9 + * @class 监听虚拟键盘
10 + * @classdesc 监听虚拟键盘弹出隐藏
11 + * @public onEnd 结束监听虚拟键盘
12 + * @public onShow 传递一个回调 监听虚拟键盘弹出
13 + * @public onHidden 传递一个回调 监听虚拟键盘隐藏
14 + */
15 +class MonitorKeyboard {
16 + constructor() {
17 + this.type = this.IsIA();
18 + this.originalHeight = window.innerHeight;
19 + }
20 +
21 + /**
22 + * @function IsIA 获取设备类型
23 + * @param 1 Android 2 iOS
24 + */
25 + IsIA = () => {
26 + const userAgent = typeof window === 'object' ? window.navigator.userAgent : '';
27 + if (/android/i.test(userAgent)) {
28 + return 1;
29 + } else if (/iPhone|iPod|iPad/i.test(userAgent)) {
30 + return 2;
31 + }
32 + }
33 +
34 + // Android系统
35 + onResize = () => {
36 + //键盘弹起与隐藏都会引起窗口的高度发生变化
37 + const resizeHeight = window.innerHeight;
38 +
39 + if (this.originalHeight - resizeHeight > 50) {
40 + this.show('Android系统: 软键盘弹出');
41 + } else {
42 + this.hidden('Android系统: 软键盘收起');
43 + }
44 + }
45 +
46 + // iOS获取焦点
47 + onFocusin = () => {
48 + this.show('iOS系统:软键盘弹出');
49 + }
50 +
51 + // iOS失去焦点
52 + onFocusout = () => {
53 + this.hidden('iOS系统:软键盘收起');
54 + }
55 +
56 + /**
57 + * @function onStart 开始监听虚拟键盘
58 + */
59 + onStart = () => {
60 + if (this.type == 1) {
61 + // 获取窗口的高度
62 + window.addEventListener('resize', this.onResize);
63 + }
64 + if (this.type == 2) {
65 + // iOS系统
66 + window.addEventListener('focusin', this.onFocusin);
67 + window.addEventListener('focusout', this.onFocusout);
68 + }
69 + }
70 +
71 + /**
72 + * @function onEnd 结束监听虚拟键盘
73 + */
74 + onEnd = () => {
75 + if (this.type == 1) {
76 + //获取窗口的高度
77 + window.removeEventListener('resize', this.onResize);
78 + }
79 + if (this.type == 2) {
80 + window.removeEventListener('focusin', this.onFocusin);
81 + window.removeEventListener('focusout', this.onFocusout);
82 + }
83 + }
84 +
85 + /**
86 + * @function onShow 传递一个回调函数
87 + * @param 虚拟键盘弹出时触发
88 + */
89 + onShow = (fn) => {
90 + this.show = fn;
91 + }
92 +
93 + /**
94 + * @function onHidden 传递一个回调函数
95 + * @param 虚拟键盘隐藏时触发
96 + */
97 + onHidden = (fn) => {
98 + this.hidden = fn;
99 + }
100 +}
101 +
102 +export default MonitorKeyboard
1 +/*
2 + * @Author: hookehuyr hookehuyr@gmail.com
3 + * @Date: 2022-05-28 10:17:40
4 + * @LastEditors: hookehuyr hookehuyr@gmail.com
5 + * @LastEditTime: 2022-12-01 16:33:51
6 + * @FilePath: /data-table/src/utils/axios.js
7 + * @Description:
8 + */
9 +import axios from 'axios';
10 +import router from '@/router';
11 +import qs from 'Qs'
12 +import { strExist } from '@/utils/tools'
13 +// import { parseQueryString } from '@/utils/tools'
14 +
15 +axios.defaults.params = {
16 + f: 'custom_form',
17 +};
18 +
19 +/**
20 + * @description 请求拦截器
21 + */
22 +axios.interceptors.request.use(
23 + config => {
24 + // const url_params = parseQueryString(location.href);
25 + // GET请求默认打上时间戳,避免从缓存中拿数据。
26 + const timestamp = config.method === 'get' ? (new Date()).valueOf() : '';
27 + /**
28 + * POST PHP需要修改数据格式
29 + * 序列化POST请求时需要屏蔽上传相关接口,上传相关接口序列化后报错
30 + */
31 + // config.data = config.method === 'post' && !strExist(['a=upload', 'upload.qiniup.com'], config.url) ? qs.stringify(config.data) : config.data;
32 + // 绑定默认请求头
33 + config.params = { ...config.params, timestamp }
34 + return config;
35 + },
36 + error => {
37 + // 请求错误处理
38 + return Promise.reject(error);
39 + });
40 +
41 +/**
42 + * @description 响应拦截器
43 + */
44 +axios.interceptors.response.use(
45 + response => {
46 + return response;
47 + },
48 + error => {
49 + return Promise.reject(error);
50 + });
51 +
52 +export default axios;
This diff is collapsed. Click to expand it.
1 +/*
2 + * @Date: 2022-07-18 10:22:22
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-08-22 18:23:07
5 + * @FilePath: /front/src/utils/generateIcons.js
6 + * @Description: 文件描述
7 + */
8 +import icon_nav from '@images/icon/nav.png'
9 +import icon_gz from '@images/icon/icon_gz.png'
10 +
11 +export {
12 + icon_nav,
13 + icon_gz,
14 +}
1 +/*
2 + * @Author: hookehuyr hookehuyr@gmail.com
3 + * @Date: 2022-05-17 11:17:58
4 + * @LastEditors: hookehuyr hookehuyr@gmail.com
5 + * @LastEditTime: 2022-07-18 10:42:12
6 + * @FilePath: /front/src/utils/generateModules.js
7 + * @Description:
8 + */
9 +import MuiVideo from '@/components/MuiVideo/index.vue'
10 +
11 +export {
12 + MuiVideo,
13 +}
1 +/*
2 + * @Date: 2022-05-17 11:26:03
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-08-05 15:18:06
5 + * @FilePath: /front/src/utils/generatePackage.js
6 + * @Description: 文件描述
7 + */
8 +import Cookies from 'js-cookie'
9 +import $ from 'jquery'
10 +import _ from 'lodash'
11 +import dayjs from 'dayjs'
12 +import axios from '@/utils/axios';
13 +import { storeToRefs } from 'pinia'
14 +import { mainStore } from '@/store'
15 +import { Toast, Dialog } from 'vant';
16 +import { wxInfo, hasEllipsis } from '@/utils/tools';
17 +import { useTitle } from '@vueuse/core'
18 +
19 +export {
20 + Cookies,
21 + $,
22 + _,
23 + axios,
24 + storeToRefs,
25 + mainStore,
26 + Toast,
27 + Dialog,
28 + wxInfo,
29 + hasEllipsis,
30 + useTitle,
31 + dayjs
32 +}
1 +/*
2 + * @Date: 2022-05-16 17:21:45
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-06-29 17:00:15
5 + * @FilePath: /tswj/src/utils/generateRoute.js
6 + * @Description: 文件描述
7 + */
8 +
9 +/**
10 + * 根据后台返回的路径,生成页面的组件模版
11 + * @param {*} component
12 + * @returns 模版地址
13 + */
14 +function loadView(component) {
15 + return () => import(`../views/${component}.vue`)
16 +}
17 +
18 +/**
19 + * 生成路由结构
20 + * @param {*} routes
21 + */
22 +const generateRoutes = (routes) => {
23 + const arr = []
24 + routes.forEach(route => {
25 + const router = {}
26 + const {
27 + path,
28 + redirect,
29 + name,
30 + component,
31 + keepAlive,
32 + meta,
33 + children
34 + } = route
35 +
36 + router.path = path
37 + redirect && (router.redirect = redirect)
38 + name && (router.name = name)
39 + router.component = loadView(component)
40 + keepAlive && (router.keepAlive = keepAlive)
41 + meta && (router.meta = meta)
42 + router.children = !Array.isArray(children) || generateRoutes(children);
43 + arr.push(router)
44 + })
45 + return arr
46 +}
47 +
48 +export default generateRoutes;
1 +import sha1 from "js-sha1";
2 +
3 +function getEtag(buffer, callback) {
4 + // sha1算法
5 + var shA1 = sha1.digest;
6 +
7 + // 以4M为单位分割
8 + var blockSize = 4 * 1024 * 1024;
9 + var sha1String = [];
10 + var prefix = 0x16;
11 + var blockCount = 0;
12 +
13 + var bufferSize = buffer.size || buffer.length || buffer.byteLength;
14 + blockCount = Math.ceil(bufferSize / blockSize);
15 +
16 + for (var i = 0; i < blockCount; i++) {
17 + sha1String.push(shA1(buffer.slice(i * blockSize, (i + 1) * blockSize)));
18 + }
19 + function concatArr2Uint8(s) {//Array 2 Uint8Array
20 + var tmp = [];
21 + for (var i of s) tmp = tmp.concat(i);
22 + return new Uint8Array(tmp);
23 + }
24 + function Uint8ToBase64(u8Arr, urisafe) {//Uint8Array 2 Base64
25 + var CHUNK_SIZE = 0x8000; //arbitrary number
26 + var index = 0;
27 + var length = u8Arr.length;
28 + var result = '';
29 + var slice;
30 + while (index < length) {
31 + slice = u8Arr.subarray(index, Math.min(index + CHUNK_SIZE, length));
32 + result += String.fromCharCode.apply(null, slice);
33 + index += CHUNK_SIZE;
34 + }
35 + return urisafe ? btoa(result).replace(/\//g, '_').replace(/\+/g, '-') : btoa(result);
36 + }
37 + function calcEtag() {
38 + if (!sha1String.length) return 'Fto5o-5ea0sNMlW_75VgGJCv2AcJ';
39 + var sha1Buffer = concatArr2Uint8(sha1String);
40 + // 如果大于4M,则对各个块的sha1结果再次sha1
41 + if (blockCount > 1) {
42 + prefix = 0x96;
43 + sha1Buffer = shA1(sha1Buffer.buffer);
44 + } else {
45 + sha1Buffer = Array.apply([], sha1Buffer);
46 + }
47 + sha1Buffer = concatArr2Uint8([[prefix], sha1Buffer]);
48 + return Uint8ToBase64(sha1Buffer, true);
49 + }
50 + return (calcEtag());
51 +}
52 +
53 +export { getEtag }
This diff is collapsed. Click to expand it.
1 +/*
2 + * @Date: 2022-04-18 15:59:42
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2023-02-24 16:13:06
5 + * @FilePath: /data-table/src/utils/tools.js
6 + * @Description: 文件描述
7 + */
8 +import dayjs from 'dayjs';
9 +
10 +// 格式化时间
11 +const formatDate = (date) => {
12 + return dayjs(date).format('YYYY-MM-DD HH:mm');
13 +};
14 +
15 +/**
16 + * @description 判断浏览器属于平台
17 + * @returns
18 + */
19 +const wxInfo = () => {
20 + let u = navigator.userAgent;
21 + let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端或者uc浏览器
22 + let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
23 + let isMobile = u.indexOf('Android') > -1 || u.indexOf('iPhone') > -1 || u.indexOf('iPad') > -1; // 移动端平台
24 + let isIpad = u.indexOf('iPad') > -1; // iPad平台
25 + let uAgent = navigator.userAgent.toLowerCase();
26 + let isWeiXin = (uAgent.match(/MicroMessenger/i) == 'micromessenger') ? true : false;
27 + let isPC = (uAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone|micromessenger)/i)) ? false : true;
28 + return {
29 + isAndroid,
30 + isiOS,
31 + isWeiXin,
32 + isMobile,
33 + isIpad,
34 + isPC
35 + };
36 +};
37 +
38 +/**
39 + * @description 判断多行省略文本
40 + * @param {*} id 目标dom标签
41 + * @returns
42 + */
43 +const hasEllipsis = (id) => {
44 + let oDiv = document.getElementById(id);
45 + let flag = false;
46 + if (oDiv.scrollHeight > oDiv.clientHeight) {
47 + flag = true
48 + }
49 + return flag
50 +}
51 +
52 +/**
53 + * @description 解析URL参数
54 + * @param {*} url
55 + * @returns
56 + */
57 +const parseQueryString = url => {
58 + var json = {};
59 + var arr = url.indexOf('?') >= 0 ? url.substr(url.indexOf('?') + 1).split('&') : [];
60 + arr.forEach(item => {
61 + var tmp = item.split('=');
62 + json[tmp[0]] = decodeURIComponent(tmp[1]);
63 + });
64 + return json;
65 +}
66 +
67 +/**
68 + * 字符串包含字符数组中字符的状态
69 + * @param {*} array 字符数组
70 + * @param {*} str 字符串
71 + * @returns 包含状态
72 + */
73 +const strExist = (array, str) => {
74 + const exist = array.filter(arr => {
75 + if (str.indexOf(arr) >= 0) return str;
76 + })
77 + return exist.length > 0
78 +}
79 +
80 +/**
81 + * 自定义替换参数
82 + * @param {*} url
83 + * @param {*} arg
84 + * @param {*} arg_val
85 + * @returns
86 + */
87 +const changeURLArg = (url, arg, arg_val) => {
88 + var pattern = arg + '=([^&]*)';
89 + var replaceText = arg + '=' + arg_val;
90 + if (url.match(pattern)) {
91 + var tmp = '/(' + arg + '=)([^&]*)/gi';
92 + tmp = url.replace(eval(tmp), replaceText);
93 + return tmp;
94 + } else {
95 + if (url.match('[\?]')) {
96 + return url + '&' + replaceText;
97 + } else {
98 + return url + '?' + replaceText;
99 + }
100 + }
101 + return url + '\n' + arg + '\n' + arg_val;
102 +}
103 +
104 +// 获取参数key/value值对
105 +const getUrlParams = (url) => {
106 + // 没有参数处理
107 + if (url.split('?').length === 1) return false;
108 + let arr = url.split('?');
109 + let res = arr[1].split('&');
110 + let items = {};
111 + for (let i = 0; i < res.length; i++) {
112 + let [key, value] = res[i].split('=');
113 + items[key] = value;
114 + }
115 + return items
116 +}
117 +
118 +// 格式化URL参数为字符串
119 +const stringifyQuery = (params) => {
120 + const queryString = [];
121 + Object.keys(params || {}).forEach((k) => {
122 + queryString.push(k + '=' + params[k]);
123 + });
124 +
125 + return '?' + queryString.join('&');
126 +};
127 +
128 +export {
129 + formatDate,
130 + wxInfo,
131 + hasEllipsis,
132 + parseQueryString,
133 + strExist,
134 + changeURLArg,
135 + getUrlParams,
136 + stringifyQuery,
137 +};
1 +import VConsole from 'vconsole';
2 +
3 +// const vConsole = new VConsole();
4 +let vConsole = '';
5 +// 或者使用配置参数来初始化,详情见文档
6 +if (+import.meta.env.VITE_CONSOLE) {
7 + vConsole = new VConsole({ theme: 'dark' });
8 +}
9 +
10 +export default vConsole
This diff could not be displayed because it is too large.