hookehuyr

项目初始化

Showing 69 changed files with 2795 additions and 0 deletions
# port
VITE_PORT = 5173
# API请求前缀
VITE_PROXY_PREFIX = /admin/
# 打包输出文件夹名称
VITE_OUTDIR = custom_dashboard
# 资源公共路径
VITE_BASE = /
# 反向代理服务器地址
VITE_PROXY_TARGET = http://oa-dev.onwall.cn
# VITE_PROXY_TARGET = http://www.wxgzjs.cn/
# 移动端地址
VITE_MOBILE_URL = http://localhost:8108/
# 资源公共路径
VITE_BASE = /admin/custom_dashboard
# 反向代理服务器地址
VITE_PROXY_TARGET = http://oa.onwall.cn
# VITE_PROXY_TARGET = http://www.wxgzjs.cn/
# 移动端地址
# VITE_MOBILE_URL = http://oa.onwall.cn/f/guanzong/front/
# VITE_MOBILE_URL = http://www.wxgzjs.cn/f/guanzong/front/
{
"globals": {
"Component": true,
"ComponentPublicInstance": true,
"ComputedRef": true,
"EffectScope": true,
"ExtractDefaultPropTypes": true,
"ExtractPropTypes": true,
"ExtractPublicPropTypes": true,
"InjectionKey": true,
"PropType": true,
"Ref": true,
"VNode": true,
"WritableComputedRef": true,
"computed": true,
"createApp": true,
"customRef": true,
"defineAsyncComponent": true,
"defineComponent": true,
"effectScope": true,
"getCurrentInstance": true,
"getCurrentScope": true,
"h": true,
"inject": true,
"isProxy": true,
"isReactive": true,
"isReadonly": true,
"isRef": true,
"markRaw": true,
"nextTick": true,
"onActivated": true,
"onBeforeMount": true,
"onBeforeRouteLeave": true,
"onBeforeRouteUpdate": true,
"onBeforeUnmount": true,
"onBeforeUpdate": true,
"onDeactivated": true,
"onErrorCaptured": true,
"onMounted": true,
"onRenderTracked": true,
"onRenderTriggered": true,
"onScopeDispose": true,
"onServerPrefetch": true,
"onUnmounted": true,
"onUpdated": true,
"provide": true,
"reactive": true,
"readonly": true,
"ref": true,
"resolveComponent": true,
"shallowReactive": true,
"shallowReadonly": true,
"shallowRef": true,
"toRaw": true,
"toRef": true,
"toRefs": true,
"toValue": true,
"triggerRef": true,
"unref": true,
"useAttrs": true,
"useCssModule": true,
"useCssVars": true,
"useLink": true,
"useRoute": true,
"useRouter": true,
"useSlots": true,
"watch": true,
"watchEffect": true,
"watchPostEffect": true,
"watchSyncEffect": true
}
}
node_modules
.history
custom_dashboard
export function createProxy(prefix, target) {
const ret = {};
ret[prefix] = {
target,
changeOrigin: true,
ws: true,
// rewrite: (path) => path.replace(/^\/api/, '')
// rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
}
return ret
}
export function setupCounter(element) {
let counter = 0
const setCounter = (count) => {
counter = count
element.innerHTML = `count is ${counter}`
}
element.addEventListener('click', () => setCounter(++counter))
setCounter(0)
}
<!--
* @Date: 2022-07-25 11:01:23
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-08 17:49:15
* @FilePath: /my-data-summary/index.html
* @Description: 文件描述
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="http://www.wxgzjs.cn/template/default/static/images/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>数据汇总</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path fill="#F7DF1E" d="M0 0h256v256H0V0Z"></path><path d="m67.312 213.932l19.59-11.856c3.78 6.701 7.218 12.371 15.465 12.371c7.905 0 12.89-3.092 12.89-15.12v-81.798h24.057v82.138c0 24.917-14.606 36.259-35.916 36.259c-19.245 0-30.416-9.967-36.087-21.996m85.07-2.576l19.588-11.341c5.157 8.421 11.859 14.607 23.715 14.607c9.969 0 16.325-4.984 16.325-11.858c0-8.248-6.53-11.17-17.528-15.98l-6.013-2.58c-17.357-7.387-28.87-16.667-28.87-36.257c0-18.044 13.747-31.792 35.228-31.792c15.294 0 26.292 5.328 34.196 19.247l-18.732 12.03c-4.125-7.389-8.591-10.31-15.465-10.31c-7.046 0-11.514 4.468-11.514 10.31c0 7.217 4.468 10.14 14.778 14.608l6.014 2.577c20.45 8.765 31.963 17.7 31.963 37.804c0 21.654-17.012 33.51-39.867 33.51c-22.339 0-36.774-10.654-43.819-24.574"></path></svg>
\ No newline at end of file
This diff could not be displayed because it is too large.
{
"name": "vue3-vite",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"tar": "tar -czvpf dist.tar.gz custom_dashboard",
"build_tar": "npm run build && npm run tar",
"scp-oa": "scp dist.tar.gz itomix@ipadbiz.cn:/opt/oa/f/",
"dec-oa": "ssh itomix@ipadbiz.cn 'cd /opt/oa/f/ && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
"scp-dev": "scp dist.tar.gz itomix@ipadbiz.cn:/opt/space-dev/admin/",
"dec-dev": "ssh itomix@ipadbiz.cn 'cd /opt/space-dev/admin/ && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
"remove_tar": "rm -rf dist.tar.gz",
"oa_upload": "npm run build_tar && npm run scp-oa && npm run dec-oa && npm run remove_tar",
"dev_upload": "npm run build_tar && npm run scp-dev && npm run dec-dev && npm run remove_tar"
},
"devDependencies": {
"@vitejs/plugin-legacy": "^2.0.0",
"@vitejs/plugin-vue": "^5.0.5",
"code-inspector-plugin": "^0.9.2",
"swiper": "^5.4.5",
"unplugin-auto-import": "^0.17.6",
"unplugin-vue-define-options": "^1.4.5",
"vite": "^3.0.0",
"vite-plugin-dynamic-import": "^1.0.0",
"vite-plugin-style-import": "1.4.1",
"vite-plugin-vue2": "^2.0.2",
"vue-awesome-swiper": "^4.1.1"
},
"dependencies": {
"@fortawesome/free-brands-svg-icons": "^6.5.2",
"@fortawesome/free-regular-svg-icons": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/vue-fontawesome": "^2.0.10",
"axios": "^0.27.2",
"dayjs": "^1.11.4",
"echarts": "^5.5.0",
"element-plus": "^2.7.6",
"element-ui": "^2.15.14",
"floating-vue": "^1.0.0-beta.19",
"jquery": "^3.6.0",
"js-cookie": "^3.0.1",
"less": "^4.1.3",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"mui-player": "^1.6.1",
"pinia": "^2.1.7",
"uuid": "^9.0.1",
"vant": "^2.12.48",
"vue": "^3.4.31",
"vue-grid-layout": "^2.4.0",
"vue-router": "^4.4.0",
"vue-template-compiler": "^2.7.16",
"vuex": "3.6.2",
"vxe-table": "^3.7.9",
"xe-utils": "^3.5.22"
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
\ No newline at end of file
#!/usr/bin/env sh
# -----------------------------------------------
# Filename: publish.sh
# Revision: 1.0
# Date: 2022年8月05日
# Author: Hooke
# Description: **** 根据php项目相应特征书写项目发布流程
# -----------------------------------------------
# 当发生错误时中止脚本
set -e
# 本地Git服务器目录路径
path=/Users/huyirui/program/itomix/git/isp/f/guanzong
# 编译输出文件夹
output=web
# 打包
npm run build
# 移除Git服务器目录下项目文件夹
rm -r $path"/${output:?}"
# 把本地编译输出文件夹添加到服务器目录
mv "${output:?}/" $path
# 提交到Git服务器
cd $path"/${output:?}"
git pull
git add -A
git commit -m '前端网页更新'
git push
# 更新SSH服务器上文件
ssh -p 22 itomix@ipadbiz.cn 'cd /opt/voice/f/guanzong/web && git pull'
<!--
* @Date: 2022-07-25 11:04:45
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-04-29 10:53:39
* @FilePath: /custom_dashboard/src/App.vue
* @Description: 文件描述
-->
<template>
<div>
<router-view />
</div>
</template>
<script>
import { wxInfo } from '@/utils/tools'
import { Updater } from '@/utils/versionUpdater'
export default {
components: { },
mounted () {
// 正式环境
// TAG:检查是否更新
if (import.meta.env.PROD) {
const upDater = new Updater({
time: 30000
})
upDater.on('no-update', () => {
// console.log('还没更新')
})
upDater.on('update', () => {
// console.log('已经更新了,请刷新页面')
this.$confirm('检测到新版本,是否刷新?', '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
window.location.reload();
}).catch(() => {
});
})
}
},
data () {
return {
}
}
}
</script>
<style lang="less">
* {
outline: none;
}
// 隐藏浏览器自带滚动条
// *::-webkit-scrollbar {
// display: none;
// }
// * {
// scrollbar-width: none;
// }
// * {
// -ms-overflow-style: none;
// }
//
html,
body {
font-size: 16px;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
p {
margin: 0;
padding: 0;
}
}
.global-center {
position: relative;
top: 50%;
transform: translateY(-50%);
}
.nav-bar {
background-color: #2B000C;
color: #D4D4D4;
}
</style>
/*
* @Date: 2022-06-17 14:54:29
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-08-18 10:52:55
* @FilePath: /web/src/api/common.js
* @Description: 公共接口
*/
import { fn, fetch } from '@/api/fn';
const Api = {
NAVI: '/srv/?a=navi_bar',
PUMING_INFO: '/srv/?a=puming_info',
CHANNEL_PAGE: '/srv/?a=channel_page',
CHANNEL_BAR: '/srv/?a=channel_bar',
FAHUI_LIST: '/srv/?a=fahui_list',
}
/**
* @description: 导航目录
* @returns
*/
export const naviAPI = (params) => fn(fetch.get(Api.NAVI, params));
/**
* @description: 普明慈善基金会
* @returns
*/
export const pumingInfoAPI = (params) => fn(fetch.get(Api.PUMING_INFO, params));
/**
* @description: 侧边频道页和导航相关信息
* @returns
*/
export const sideNaviAPI = (params) => fn(fetch.get(Api.CHANNEL_PAGE, params));
/**
* @description: 频道介绍和其他相关展示信息
* @returns
*/
export const channelInfoAPI = (params) => fn(fetch.get(Api.CHANNEL_BAR, params));
/**
* @description: 法会活动
* @returns
*/
export const fahuiListAPI = (params) => fn(fetch.get(Api.FAHUI_LIST, params));
/*
* @Date: 2022-05-18 22:56:08
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-07-28 17:46:42
* @FilePath: /web/src/api/fn.js
* @Description: 文件描述
*/
import axios from '@/utils/axios';
import { Message } from 'element-ui';
import qs from 'Qs'
/**
* 网络请求功能函数
* @param {*} api 请求axios接口
* @returns 请求成功后,获取数据
*/
export const fn = (api) => {
return api
.then(res => {
if (res.data.code === 1) {
return res.data || true;
} else {
console.warn(res);
if (!res.data.show) return false;
Message({
message: res.data.msg,
type: 'warning'
});
return false;
}
})
.catch(err => {
console.error(err);
return false;
})
.finally(() => { // 最终执行
})
}
/**
* 统一 GET/POST 不同传参形式
*/
export const fetch = {
get: function (api, params) {
return axios.get(api, { params })
},
post: function (api, params) {
return axios.post(api, params)
},
stringifyPost: function (api, params) {
return axios.post(api, qs.stringify(params))
},
basePost: function (url, data, config) {
return axios.post(url, data, config)
}
}
/*
* @Date: 2022-06-17 14:54:29
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-04-03 14:09:34
* @FilePath: /custom_dashboard/src/api/index.js
* @Description: 首页接口
*/
import { fn, fetch } from '@/api/fn';
const Api = {
CHART_SQL_LIST: '/admin/?a=chart_sql_list',
SAVE_CHART_SQL: '/admin/?a=save_chart_sql',
DEL_CHART_SQL: '/admin/?a=del_chart_sql',
CHART_SQL_SETTING_LIST: '/admin/?a=chart_sql_setting_list',
SAVE_CHART_SQL_SETTING: '/admin/?a=save_chart_sql_setting',
CHART_SQL_BOARD_LIST: '/admin/?a=chart_sql_board_list',
SAVE_CHART_SQL_BOARD: '/admin/?a=save_chart_sql_board',
DEL_CHART_SQL_BOARD: '/admin/?a=del_chart_sql_board',
DEL_CHART_SQL_SETTING: '/admin/?a=del_chart_sql_setting',
SAVE_CHART_SQL_LOCATION: '/admin/?a=save_chart_sql_location',
CHART_DATA_MIX_LINE_BAR: '/admin/?a=chart_data_mix_line_bar',
SHOW_CHART_SQL: '/admin/?a=show_chart_sql',
DUPLICATE_CHART_SQL: '/admin/?a=duplicate_chart_sql',
}
/**
* @description: sql数据源列表
*/
export const chartSqlListAPI = (params) => fn(fetch.get(Api.CHART_SQL_LIST, params));
/**
* @description: 保存sql数据源
* @param {*} id sql数据源id。为空表示新增,否则是更新。
* @param {*} name sql数据源名称
* @param {*} chart_mode 图表类型
* @param {*} sql_stat sql语句
* @param {*} sql_col sql语句输出的字段
* @param {*} sql_parm sql语句的执行参数
* @param {*} status 状态
* @param {*} note sql数据源的描述
*/
export const saveChartSqlAPI = (params) => fn(fetch.post(Api.SAVE_CHART_SQL, params))
/**
* @description: 删除sql数据源
* @param {*} id sql数据源id
*/
export const delChartSqlAPI = (params) => fn(fetch.post(Api.DEL_CHART_SQL, params))
/**
* @description: sql版图表列表
* @param {*} name 图表名称,模糊查询
* @param {*} chart_mode 图表类型,json数组,可以查询多个类型
* @param {*} status 状态,json数组,可以查询多个状态
* @param {*} row_num 每页行数,默认20
* @param {*} page 当前页数,默认1,从1开始,1表示第一页,2表示第二页,依次类推;
*/
export const chartSqlSettingListAPI = (params) => fn(fetch.get(Api.CHART_SQL_SETTING_LIST, params))
/**
* @description: 仪表盘内保存sql版图表
* @param {*}
*/
export const saveChartSqlSettingAPI = (params) => fn(fetch.post(Api.SAVE_CHART_SQL_SETTING, params))
/**
* @description: sql版仪表盘列表
*/
export const chartSqlBoardListAPI = (params) => fn(fetch.get(Api.CHART_SQL_BOARD_LIST, params));
/**
* @description: 保存sql版仪表盘
* @param {*} id sql版仪表盘id。为空表示新增,否则是更新。
* @param {*} name sql版仪表盘名称
* @param {*} note sql版仪表盘的描述
*/
export const saveChartSqlBoardAPI = (params) => fn(fetch.post(Api.SAVE_CHART_SQL_BOARD, params))
/**
* @description: 删除sql版仪表盘
* @param {*} id sql版仪表盘id。
*/
export const delChartSqlBoardAPI = (params) => fn(fetch.post(Api.DEL_CHART_SQL_BOARD, params))
/**
* @description: 仪表盘内删除sql版图表
* @param {*} id sql版仪表盘id。
*/
export const delChartSqlSettingAPI = (params) => fn(fetch.post(Api.DEL_CHART_SQL_SETTING, params))
/**
* @description: 仪表盘内保存sql版图表位置
* @param {*} board_id 仪表盘id
* @param {*} location 仪表盘内所有图表的位置,json数组格式
*/
export const saveChartSqlLocationAPI = (params) => fn(fetch.post(Api.SAVE_CHART_SQL_LOCATION, params))
/**
* @description: 双轴图的展示数据
* @param {*} data 左右轴的图表数据
*/
export const chartDataMixLineBarAPI = (params) => fn(fetch.get(Api.CHART_DATA_MIX_LINE_BAR, params))
/**
* @description: 展示一个sql版图表
* @param {*}
*/
export const showChartSqlAPI = (params) => fn(fetch.get(Api.SHOW_CHART_SQL, params))
/**
* @description: 复制sql数据源
* @param {*} sql_id sql数据源id
*/
export const duplicateChartSqlAPI = (params) => fn(fetch.get(Api.DUPLICATE_CHART_SQL, params))
/*
* @Date: 2022-06-17 14:54:29
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-08-04 14:49:05
* @FilePath: /web/src/api/temple.js
* @Description: 走进寺庙接口
*/
import { fn, fetch } from '@/api/fn';
const Api = {
TEMPLE_INFO: '/srv/?a=temple_info',
}
/**
* @description: 走进寺庙
* @returns
*/
export const templeInfoAPI = (params) => fn(fetch.get(Api.TEMPLE_INFO, params));
/* ============ 颜色 ============ */
// 文字颜色
@text-color: #333333;
// Hover颜色
@hover-color: #2B000C;
// Hover颜色
@hover-main-color: #F3BB66;
// 次要颜色
@sub-color: #2B000C;
// 文字附件颜色
@affix-color: #999999;
.multi-ellipsis--l1 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.multi-ellipsis--l2 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.multi-ellipsis--l3 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.multi-ellipsis--l4 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
}
.multi-ellipsis--l5 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
}
.multi-ellipsis--l6 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 6;
-webkit-box-orient: vertical;
}
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const effectScope: typeof import('vue')['effectScope']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useLink: typeof import('vue-router')['useLink']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useSlots: typeof import('vue')['useSlots']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
import('vue')
}
/*
* @Date: 2022-07-26 09:49:54
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-03-25 17:56:01
* @FilePath: /custom_dashboard/src/common/mixin.js
* @Description: 文件描述
*/
export default {
// 初始化设置
init: {
mounted () {
document.title = this.$route.meta.title;
},
methods: {
},
},
};
This diff is collapsed. Click to expand it.
<!--
* @Date: 2024-03-01 09:40:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-03-30 06:14:10
* @FilePath: /custom_dashboard/src/components/DynamicChart.vue
* @Description: 文件描述
-->
<template>
<div :ref="chartRef" class="dynamic-chart" :style="{ width: width, height: wrapper_height, marginTop: titleHeight + 'px'}"></div>
</template>
<script>
import * as echarts from 'echarts/core';
// 引入柱状图图表,图表后缀都为 Chart
import { BarChart, PieChart, LineChart, RadarChart, FunnelChart } from 'echarts/charts';
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
import {
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent,
DatasetComponent,
TransformComponent
} from 'echarts/components';
// 标签自动布局、全局过渡动画等特性
import { LabelLayout, UniversalTransition } from 'echarts/features';
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from 'echarts/renderers';
// 注册必须的组件
echarts.use([
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent,
DatasetComponent,
TransformComponent,
BarChart,
PieChart,
LineChart,
RadarChart,
FunnelChart,
LabelLayout,
UniversalTransition,
CanvasRenderer
]);
export default {
name: 'DynamicChart',
props: ['chartOptions', 'chartData', 'width', 'height', 'titleHeight'],
data() {
return {
chartRef: 'chartContainer',
chartInstance: null,
wrapper_height: '',
};
},
watch: {
height (val) {
if (val) {
this.wrapper_height = val;
}
}
},
mounted() {
this.wrapper_height = this.height;
setTimeout(() => {
this.initChart();
}, 200);
},
beforeDestroy() {
this.destroyChart();
},
methods: {
initChart() {
const chartContainer = this.$refs.chartContainer;
if (chartContainer) {
this.chartInstance = echarts.init(chartContainer);
this.chartInstance.setOption(this.chartOptions);
}
},
destroyChart() {
if (this.chartInstance) {
this.chartInstance.dispose();
this.chartInstance = null;
}
},
updateChart() {
this.chartInstance.setOption(this.chartOptions);
},
}
};
</script>
<style scoped>
.dynamic-chart {
padding: 10px;
}
</style>
<!--
* @Date: 2024-03-21 09:36:01
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-03-21 14:20:43
* @FilePath: /custom_dashboard/src/components/filterInput.vue
* @Description: 文件描述
-->
<template>
<div :class="['edit-tag-wrapper', hoverInFilter ? 'hover' : '']">
<p style="margin-bottom: 10px">过滤:</p>
<div id="filter" style="flex: 1; height: 100%; display: flex">
<!-- <el-tag
:key="index"
v-for="(item, index) in filter_list"
closable
effect="plain"
type="success"
:disable-transitions="false"
@close="handleFilterClose(item, index)">
{{ item.name }}<span style="font-size: 0.7rem;"> ( 求和 )</span>
</el-tag> -->
<div
:key="index"
v-for="(item, index) in filter_list"
class="filter-wrapper"
>
<VDropdown placement="bottom">
<span class="filter-item">
<i class="el-icon-arrow-down el-icon--right"></i>&nbsp;<span
style="font-size: 0.8rem"
>{{ item.name }}</span
>
</span>
<template #popper>
<!-- <VMenu v-for="n in 5" :key="n" placement="right-start" instant-move>
<div style="padding: 0.5rem">修改显示名</div>
<template #popper>
<VMenu v-for="n in 5" :key="n" placement="right-start" instant-move>
<div class="rounded hover:bg-green-100 px-4 py-2">Option {{ n }}</div>
</VMenu>
</template>
</VMenu> -->
<div style="padding: 0.5rem;">
<div class="filter-handle-item">修改筛选条件</div>
<div class="filter-handle-item">删除筛选条件</div>
</div>
</template>
</VDropdown>
</div>
</div>
<el-dialog
title="设置过滤条件"
:visible.sync="dialogVisible"
width="30%"
:append-to-body="true"
:before-close="handleClose">
<div>
<el-row :gutter="5">
<el-col :span="16">
<el-input v-model="field_input" :disabled="true">
</el-input>
</el-col>
<el-col :span="8">
<el-select v-model="op_value" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-col>
</el-row>
<el-row style="margin-top: 0.5rem;">
<el-col :span="24">
<el-input placeholder="请输入内容" v-model="filter_input">
</el-input>
</el-col>
</el-row>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import mixin from "common/mixin";
const TEXT_OPTIONS = [{
value: '1',
label: '等于'
}, {
value: '2',
label: '不等于'
}, {
value: '3',
label: '等于任意一个'
}, {
value: '4',
label: '不等于任意一个'
}, {
value: '5',
label: '包含'
}, {
value: '6',
label: '不包含'
}, {
value: '7',
label: '为空'
}, {
value: '8',
label: '不为空'
}];
const DATE_OPTIONS = [{
value: '1',
label: '等于'
}, {
value: '2',
label: '不等于'
}, {
value: '3',
label: '大于等于'
}, {
value: '4',
label: '小于等于'
}, {
value: '5',
label: '选择范围'
}, {
value: '6',
label: '动态筛选'
}, {
value: '7',
label: '为空'
}, {
value: '8',
label: '不为空'
}];
const NUM_OPTIONS = [{
value: '1',
label: '等于'
}, {
value: '2',
label: '不等于'
}, {
value: '3',
label: '大于'
}, {
value: '4',
label: '大于等于'
}, {
value: '5',
label: '小于'
}, {
value: '6',
label: '小于等于'
}, {
value: '7',
label: '选择范围'
}, {
value: '8',
label: '为空'
}, {
value: '9',
label: '不为空'
}];
export default {
mixins: [mixin.init],
props: {
hover: {
type: Boolean,
default: false,
},
list: {
type: Array,
default: () => {
return [];
},
},
filterItem: {
type: Object,
default: () => {
return {};
}
}
},
watch: {
hover(v) {
this.hoverInFilter = v;
},
list(v) {
this.filter_list = v;
},
filterItem(v) {
if (v) {
this.dialogVisible = true;
}
}
},
data() {
return {
filter_list: [],
hoverInFilter: false,
dialogVisible: false,
options: [],
op_value: '1',
field_input: '测试字段',
filter_input: '',
};
},
mounted() {
this.options = TEXT_OPTIONS;
},
methods: {
handleFilterClose() {
// this.filter_list.splice(index, 1);
},
handleClose(done) {
this.$confirm('确认关闭?')
.then(_ => {
done();
})
.catch(_ => {});
},
},
};
</script>
<style lang="less" scoped>
.edit-tag-wrapper {
border: 1px dashed #d7d9dc;
border-radius: 3px;
padding: 10px;
padding-bottom: 0;
height: auto;
min-height: 42px;
background: #fff;
display: flex;
align-items: center;
margin-bottom: 10px;
// width: 100%;
&.hover {
border: 1px dashed green;
background: rgb(208 249 208 / 34%);
}
.filter-wrapper {
margin-right: 10px;
margin-bottom: 10px;
.filter-item {
background-color: #fff;
border-color: #d9ecff;
height: 32px;
padding: 7px 10px 10px 0;
line-height: 1;
color: #409eff;
border-width: 1px;
border-style: solid;
border-radius: 4px;
box-sizing: border-box;
white-space: nowrap;
display: inline-block;
cursor: pointer;
}
}
}
.filter-handle-item {
padding: 0.5rem 1rem;
&:hover {
background-color: #f5f5f5;
cursor: pointer;
}
}
</style>
<!--
* @Date: 2024-05-17 16:31:55
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-05-17 17:33:08
* @FilePath: /custom_dashboard/src/components/GeoChart.vue
* @Description: 文件描述
-->
<template>
<div :ref="chartRef" id="chart-container" style="width: 100%; height: 800px;"></div>
</template>
<script>
import mixin from 'common/mixin';
import $ from 'jquery';
import * as echarts from 'echarts/core';
// 引入柱状图图表,图表后缀都为 Chart
import { BarChart, PieChart, LineChart, RadarChart, FunnelChart, LinesChart } from 'echarts/charts';
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
import {
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent,
DatasetComponent,
TransformComponent,
GeoComponent
} from 'echarts/components';
// 标签自动布局、全局过渡动画等特性
import { LabelLayout, UniversalTransition } from 'echarts/features';
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer, SVGRenderer } from 'echarts/renderers';
// 注册必须的组件
echarts.use([
TitleComponent,
TooltipComponent,
LegendComponent,
GridComponent,
DatasetComponent,
TransformComponent,
BarChart,
PieChart,
LineChart,
RadarChart,
FunnelChart,
LabelLayout,
UniversalTransition,
CanvasRenderer,
SVGRenderer,
GeoComponent,
LinesChart
]);
export default {
mixins: [mixin.init],
data () {
return {
chartRef: 'chartContainer',
chartInstance: null,
chartOptions: {
title: {
text: 'Visit Route',
left: 'center',
bottom: 10
},
tooltip: {},
geo: {
map: 'MacOdrum-LV5-floorplan-web',
roam: true,
emphasis: {
itemStyle: {
color: undefined
},
label: {
show: false
}
}
},
series: [
{
name: 'Route',
type: 'lines',
coordinateSystem: 'geo',
geoIndex: 0,
emphasis: {
label: {
show: false
}
},
polyline: true,
lineStyle: {
color: '#c46e54',
width: 5,
opacity: 1,
type: 'dotted'
},
effect: {
show: true,
period: 8,
color: '#a10000',
constantSpeed: 80,
trailLength: 0,
symbolSize: [20, 12],
symbol:
'path://M35.5 40.5c0-22.16 17.84-40 40-40s40 17.84 40 40c0 1.6939-.1042 3.3626-.3067 5H35.8067c-.2025-1.6374-.3067-3.3061-.3067-5zm90.9621-2.6663c-.62-1.4856-.9621-3.1182-.9621-4.8337 0-6.925 5.575-12.5 12.5-12.5s12.5 5.575 12.5 12.5a12.685 12.685 0 0 1-.1529 1.9691l.9537.5506-15.6454 27.0986-.1554-.0897V65.5h-28.7285c-7.318 9.1548-18.587 15-31.2715 15s-23.9535-5.8452-31.2715-15H15.5v-2.8059l-.0937.0437-8.8727-19.0274C2.912 41.5258.5 37.5549.5 33c0-6.925 5.575-12.5 12.5-12.5S25.5 26.075 25.5 33c0 .9035-.0949 1.784-.2753 2.6321L29.8262 45.5h92.2098z'
},
data: [
{
coords: [
[110.6189462165178, 456.64349563895087],
[124.10988522879458, 450.8570048730469],
[123.9272226116071, 389.9520693708147],
[61.58708083147317, 386.87942320312504],
[61.58708083147317, 72.8954315876116],
[258.29514854771196, 72.8954315876116],
[260.75457021484374, 336.8559607533482],
[280.5277985253906, 410.2406672084263],
[275.948185765904, 528.0254369698661],
[111.06907909458701, 552.795792593471],
[118.87138231445309, 701.365737015904],
[221.36468155133926, 758.7870354617745],
[307.86195445452006, 742.164737297712],
[366.8489324762834, 560.9895157073103],
[492.8750778390066, 560.9895157073103],
[492.8750778390066, 827.9639780566406],
[294.9255269587053, 827.9639780566406],
[282.79803391043527, 868.2476088113839]
]
}
]
}
]
}
}
},
mounted () {
setTimeout(() => {
this.initChart();
}, 500);
},
methods: {
initChart() {
var dom = document.getElementById('chart-container');
this.chartInstance = echarts.init(dom, null, {
renderer: 'svg',
useDirtyRect: false
});
$.get('https://cdn.ipadbiz.cn/tmp/MacOdrum-LV5-floorplan-web.svg', (svg) => {
echarts.registerMap('MacOdrum-LV5-floorplan-web', { svg: svg });
this.chartInstance.setOption(this.chartOptions);
this.chartInstance.on('click', { geoIndex: 0, name: 'seminar_room' }, function (params) {
console.log(params);
});
})
},
destroyChart() {
if (this.chartInstance) {
this.chartInstance.dispose();
this.chartInstance = null;
}
},
updateChart() {
this.chartInstance.setOption(this.chartOptions);
},
}
}
</script>
<style lang="less" scoped>
</style>
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
/*
* @Date: 2022-07-25 11:01:23
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-08 17:48:53
* @FilePath: /my-data-summary/src/main.js
* @Description: 文件描述
*/
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from './router';
import axios from '@/utils/axios';
import { createPinia } from 'pinia';
// router.afterEach((to, from, next) => {
// // window.scrollTo(0, 0);
// })
const pinia = createPinia();
const app = createApp(App);
app.config.globalProperties.$http = axios; // 关键语句
app.use(router).use(ElementPlus).use(pinia).mount('#app');
This diff is collapsed. Click to expand it.
/*
* @Date: 2022-07-18 12:57:31
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-07-21 17:03:02
* @FilePath: /front/src/mock/nav.js
* @Description: 文件描述
*/
const data = [{
title: '首页',
link: '/',
sub: []
}, {
title: '走进寺院',
link: '/temple',
sub: []
}, {
title: '寺院新闻',
link: '',
sub: [{
id: 'xxx',
title: '公告',
link: '/column'
}, {
title: '招聘',
link: ''
}, {
title: '新闻',
link: ''
}]
}, {
title: '智慧课堂',
link: '',
sub: [{
title: '活动与咨询',
link: ''
}, {
title: '福田功德',
link: ''
}, {
title: '广结善缘',
link: ''
}]
}, {
title: '弘法利生',
link: '',
sub: [{
title: '法务活动',
link: ''
}, {
title: '本源法师开示',
link: ''
}, {
title: '短期出家',
link: ''
}, {
title: '闻思修慧',
link: ''
}, {
title: '素食护生',
link: ''
}, {
title: '妙智学堂',
link: ''
}]
}, {
title: '义工之家',
link: '',
sub: [{
title: '义工之家',
link: ''
}]
}, {
title: '普明慈善基金会',
link: '/foundation',
sub: []
}, {
title: '生命关怀',
link: '',
sub: [{
title: '生命关怀',
link: ''
}]
}]
export default data
const routes = [{
path: '/image',
redirect: '',
name: 'html转图片',
component: 'html2canvas',
keepAlive: '',
meta: {
title: 'html转图片',
name: ''
},
children: [{
path: 'children',
redirect: '',
name: 'html转图片',
component: 'children-test',
keepAlive: '',
meta: {
title: 'html转图片',
name: ''
}
}]
}]
// const routes = []
export default routes
/*
* @Date: 2022-07-18 15:05:39
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-07-22 14:34:25
* @FilePath: /front/src/mock/swipe.js
* @Description: 文件描述
*/
const data = [{
id: '1',
src: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
title: '文章1',
link: '/detail'
}, {
id: '2',
src: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
title: '文章2',
link: '/detail'
}, {
id: '3',
src: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
title: '文章3',
link: '/detail'
}]
export default data
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
/*
* @Date: 2022-07-18 10:22:22
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-08 17:22:58
* @FilePath: /custom_dashboard/src/route.js
* @Description: 文件描述
*/
export default [{
path: '/',
component: () => import('@/views/index.vue'),
meta: {
title: '首页',
}
}];
/*
* @Date: 2022-05-26 13:57:28
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-29 21:36:59
* @FilePath: /tswj/src/router.js
* @Description: 文件描述
*/
import { createRouter, createWebHashHistory } from 'vue-router';
import RootRoute from './route.js';
import asyncRoutesArr from "./mock/routes"
import generateRoutes from './utils/generateRoute'
// TAG: 路由配置表
/**
* 把项目独有的路由配置到相应的路径,默认路由文件只放公用部分
* 但是 vue 文件内容还是要事先准备好
*/
const modules = import.meta.globEager('@/router/routes/modules/**/*.js'); // Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块
const routeModuleList = [];
Object.keys(modules).forEach((key) => {
const mod = modules[key].default || {};
const modList = Array.isArray(mod) ? [...mod] : [mod];
routeModuleList.push(...modList);
});
// 创建路由实例并传递 `routes` 配置
const router = createRouter({
history: createWebHashHistory('/index.html'),
routes: [...RootRoute, ...routeModuleList]
});
// TAG: 动态生成路由
/**
* generateRoute 负责把后台返回数据拼接成项目需要的路由结构,动态添加到路由表里面
*/
router.beforeEach((to, from, next) => {
// 使用404为中转页面,避免动态路由没有渲染出来,控制台报警告问题
if (to.path == '/404' && to.redirectedFrom != undefined) {
// 模拟异步操作
setTimeout(() => {
if (!asyncRoutesArr.length) return; // 没有动态路由避免报错
const arr = generateRoutes(asyncRoutesArr); // 在路由守卫处生成,避免有子路由时刷新白屏问题。
arr.forEach(item => {
router.addRoute(item) // 新增路由
})
// 重写被404覆盖路由信息
next({ ...to.redirectedFrom, replace: true });
}, 1000);
} else {
next()
}
})
router.afterEach(() => {
// console.warn(to);
// console.warn(wx);
// share(to)
})
export default router;
const index = [{
path: '/auth',
name: '授权跳转页',
component: () => import('@/views/auth.vue'),
meta: {
title: '微信授权'
},
children: []
}]
export default index;
/*
* @Date: 2022-06-15 17:09:03
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-07-18 10:54:32
* @FilePath: /front/src/router/routes/modules/common/index.js
* @Description: 文件描述
*/
const index = [{ // 配置404为动态路由中转页面
path: '/:pathMatch(.*)*',
redirect: '/404'
}, {
path: '/404',
name: '404',
component: () => import('@/views/404.vue'),
meta: {
icon: '',
title: '404',
},
children: [],
}];
export default index;
/*
* @Date: 2022-04-18 15:59:42
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-03-03 10:10:27
* @FilePath: /data-table/src/store/index.js
* @Description: 文件描述
*/
import { defineStore } from 'pinia';
// import { testStore } from './test'; // 另一个store
import _ from 'lodash';
import { useRouter } from 'vue-router'
export const mainStore = defineStore('main', {
state: () => {
return {
msg: 'Hello world',
count: 0,
auth: false,
comment_num: 0,
video_detail: {},
scrollTop: 0,
scrollTopCollection: 0,
scrollTopLike: 0,
scrollTopPerson: 0,
keepPages: ['default'], // 很坑爹,空值全部都缓存
fieldName: '',
formInfo: {}, // 表单字段信息
formSetting: {}, // 表单数据收集设置
successInfo: {}, // 表单提交返回值
};
},
getters: {
getKeepPages () {
return this.keepPages
},
// getTestStoreList () {
// return testStore().list // 返回另一个store的值
// }
},
actions: {
changeState (state) {
this.auth = state;
},
changeCommentNum (num) {
this.comment_num = num;
},
changeVideoDetail (v) {
this.video_detail = v;
},
changeScrollTop (v) {
this.scrollTop = v;
},
changeScrollTopCollection (v) {
this.scrollTopCollection = v;
},
changeScrollTopLike (v) {
this.scrollTopLike = v;
},
changeScrollTopPerson (v) {
this.scrollTopPerson = v;
},
changeKeepPages () { // 清空所有缓存,用一个不存在的值覆盖
this.keepPages = ['default'];
},
keepThisPage () { // 新增缓存页
const $router = useRouter();
const page = $router.currentRoute.value.meta.name;
this.keepPages.push(page);
},
removeThisPage () { // 删除缓存页
const $router = useRouter();
const page = $router.currentRoute.value.meta.name;
_.remove(this.keepPages, item => item === page)
},
changeFieldName (v) {
this.fieldName = v;
},
changeFormInfo (v) {
this.formInfo = v;
},
changeFormSetting (v) {
this.formSetting = v;
},
changeSuccessInfo (v) {
this.successInfo = v;
},
},
});
/*
* @Date: 2022-06-20 01:22:50
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-20 01:23:18
* @FilePath: /tswj/src/composables/useMonitorKeyboard.js
* @Description: 文件描述
*/
/**
* @class 监听虚拟键盘
* @classdesc 监听虚拟键盘弹出隐藏
* @public onEnd 结束监听虚拟键盘
* @public onShow 传递一个回调 监听虚拟键盘弹出
* @public onHidden 传递一个回调 监听虚拟键盘隐藏
*/
class MonitorKeyboard {
constructor() {
this.type = this.IsIA();
this.originalHeight = window.innerHeight;
}
/**
* @function IsIA 获取设备类型
* @param 1 Android 2 iOS
*/
IsIA = () => {
const userAgent = typeof window === 'object' ? window.navigator.userAgent : '';
if (/android/i.test(userAgent)) {
return 1;
} else if (/iPhone|iPod|iPad/i.test(userAgent)) {
return 2;
}
}
// Android系统
onResize = () => {
//键盘弹起与隐藏都会引起窗口的高度发生变化
const resizeHeight = window.innerHeight;
if (this.originalHeight - resizeHeight > 50) {
this.show('Android系统: 软键盘弹出');
} else {
this.hidden('Android系统: 软键盘收起');
}
}
// iOS获取焦点
onFocusin = () => {
this.show('iOS系统:软键盘弹出');
}
// iOS失去焦点
onFocusout = () => {
this.hidden('iOS系统:软键盘收起');
}
/**
* @function onStart 开始监听虚拟键盘
*/
onStart = () => {
if (this.type == 1) {
// 获取窗口的高度
window.addEventListener('resize', this.onResize);
}
if (this.type == 2) {
// iOS系统
window.addEventListener('focusin', this.onFocusin);
window.addEventListener('focusout', this.onFocusout);
}
}
/**
* @function onEnd 结束监听虚拟键盘
*/
onEnd = () => {
if (this.type == 1) {
//获取窗口的高度
window.removeEventListener('resize', this.onResize);
}
if (this.type == 2) {
window.removeEventListener('focusin', this.onFocusin);
window.removeEventListener('focusout', this.onFocusout);
}
}
/**
* @function onShow 传递一个回调函数
* @param 虚拟键盘弹出时触发
*/
onShow = (fn) => {
this.show = fn;
}
/**
* @function onHidden 传递一个回调函数
* @param 虚拟键盘隐藏时触发
*/
onHidden = (fn) => {
this.hidden = fn;
}
}
export default MonitorKeyboard
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-28 10:17:40
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-12-01 16:33:51
* @FilePath: /data-table/src/utils/axios.js
* @Description:
*/
import axios from 'axios';
import router from '@/router';
import qs from 'Qs'
import { strExist } from '@/utils/tools'
// import { parseQueryString } from '@/utils/tools'
axios.defaults.params = {
f: 'custom_form',
};
/**
* @description 请求拦截器
*/
axios.interceptors.request.use(
config => {
// const url_params = parseQueryString(location.href);
// GET请求默认打上时间戳,避免从缓存中拿数据。
const timestamp = config.method === 'get' ? (new Date()).valueOf() : '';
/**
* POST PHP需要修改数据格式
* 序列化POST请求时需要屏蔽上传相关接口,上传相关接口序列化后报错
*/
// config.data = config.method === 'post' && !strExist(['a=upload', 'upload.qiniup.com'], config.url) ? qs.stringify(config.data) : config.data;
// 绑定默认请求头
config.params = { ...config.params, timestamp }
return config;
},
error => {
// 请求错误处理
return Promise.reject(error);
});
/**
* @description 响应拦截器
*/
axios.interceptors.response.use(
response => {
return response;
},
error => {
return Promise.reject(error);
});
export default axios;
This diff is collapsed. Click to expand it.
/*
* @Date: 2022-07-18 10:22:22
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-08-22 18:23:07
* @FilePath: /front/src/utils/generateIcons.js
* @Description: 文件描述
*/
import icon_nav from '@images/icon/nav.png'
import icon_gz from '@images/icon/icon_gz.png'
export {
icon_nav,
icon_gz,
}
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-17 11:17:58
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-07-18 10:42:12
* @FilePath: /front/src/utils/generateModules.js
* @Description:
*/
import MuiVideo from '@/components/MuiVideo/index.vue'
export {
MuiVideo,
}
/*
* @Date: 2022-05-17 11:26:03
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-08-05 15:18:06
* @FilePath: /front/src/utils/generatePackage.js
* @Description: 文件描述
*/
import Cookies from 'js-cookie'
import $ from 'jquery'
import _ from 'lodash'
import dayjs from 'dayjs'
import axios from '@/utils/axios';
import { storeToRefs } from 'pinia'
import { mainStore } from '@/store'
import { Toast, Dialog } from 'vant';
import { wxInfo, hasEllipsis } from '@/utils/tools';
import { useTitle } from '@vueuse/core'
export {
Cookies,
$,
_,
axios,
storeToRefs,
mainStore,
Toast,
Dialog,
wxInfo,
hasEllipsis,
useTitle,
dayjs
}
/*
* @Date: 2022-05-16 17:21:45
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-29 17:00:15
* @FilePath: /tswj/src/utils/generateRoute.js
* @Description: 文件描述
*/
/**
* 根据后台返回的路径,生成页面的组件模版
* @param {*} component
* @returns 模版地址
*/
function loadView(component) {
return () => import(`../views/${component}.vue`)
}
/**
* 生成路由结构
* @param {*} routes
*/
const generateRoutes = (routes) => {
const arr = []
routes.forEach(route => {
const router = {}
const {
path,
redirect,
name,
component,
keepAlive,
meta,
children
} = route
router.path = path
redirect && (router.redirect = redirect)
name && (router.name = name)
router.component = loadView(component)
keepAlive && (router.keepAlive = keepAlive)
meta && (router.meta = meta)
router.children = !Array.isArray(children) || generateRoutes(children);
arr.push(router)
})
return arr
}
export default generateRoutes;
import sha1 from "js-sha1";
function getEtag(buffer, callback) {
// sha1算法
var shA1 = sha1.digest;
// 以4M为单位分割
var blockSize = 4 * 1024 * 1024;
var sha1String = [];
var prefix = 0x16;
var blockCount = 0;
var bufferSize = buffer.size || buffer.length || buffer.byteLength;
blockCount = Math.ceil(bufferSize / blockSize);
for (var i = 0; i < blockCount; i++) {
sha1String.push(shA1(buffer.slice(i * blockSize, (i + 1) * blockSize)));
}
function concatArr2Uint8(s) {//Array 2 Uint8Array
var tmp = [];
for (var i of s) tmp = tmp.concat(i);
return new Uint8Array(tmp);
}
function Uint8ToBase64(u8Arr, urisafe) {//Uint8Array 2 Base64
var CHUNK_SIZE = 0x8000; //arbitrary number
var index = 0;
var length = u8Arr.length;
var result = '';
var slice;
while (index < length) {
slice = u8Arr.subarray(index, Math.min(index + CHUNK_SIZE, length));
result += String.fromCharCode.apply(null, slice);
index += CHUNK_SIZE;
}
return urisafe ? btoa(result).replace(/\//g, '_').replace(/\+/g, '-') : btoa(result);
}
function calcEtag() {
if (!sha1String.length) return 'Fto5o-5ea0sNMlW_75VgGJCv2AcJ';
var sha1Buffer = concatArr2Uint8(sha1String);
// 如果大于4M,则对各个块的sha1结果再次sha1
if (blockCount > 1) {
prefix = 0x96;
sha1Buffer = shA1(sha1Buffer.buffer);
} else {
sha1Buffer = Array.apply([], sha1Buffer);
}
sha1Buffer = concatArr2Uint8([[prefix], sha1Buffer]);
return Uint8ToBase64(sha1Buffer, true);
}
return (calcEtag());
}
export { getEtag }
This diff is collapsed. Click to expand it.
/*
* @Date: 2022-04-18 15:59:42
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-02-24 16:13:06
* @FilePath: /data-table/src/utils/tools.js
* @Description: 文件描述
*/
import dayjs from 'dayjs';
// 格式化时间
const formatDate = (date) => {
return dayjs(date).format('YYYY-MM-DD HH:mm');
};
/**
* @description 判断浏览器属于平台
* @returns
*/
const wxInfo = () => {
let u = navigator.userAgent;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端或者uc浏览器
let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
let isMobile = u.indexOf('Android') > -1 || u.indexOf('iPhone') > -1 || u.indexOf('iPad') > -1; // 移动端平台
let isIpad = u.indexOf('iPad') > -1; // iPad平台
let uAgent = navigator.userAgent.toLowerCase();
let isWeiXin = (uAgent.match(/MicroMessenger/i) == 'micromessenger') ? true : false;
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;
return {
isAndroid,
isiOS,
isWeiXin,
isMobile,
isIpad,
isPC
};
};
/**
* @description 判断多行省略文本
* @param {*} id 目标dom标签
* @returns
*/
const hasEllipsis = (id) => {
let oDiv = document.getElementById(id);
let flag = false;
if (oDiv.scrollHeight > oDiv.clientHeight) {
flag = true
}
return flag
}
/**
* @description 解析URL参数
* @param {*} url
* @returns
*/
const parseQueryString = url => {
var json = {};
var arr = url.indexOf('?') >= 0 ? url.substr(url.indexOf('?') + 1).split('&') : [];
arr.forEach(item => {
var tmp = item.split('=');
json[tmp[0]] = decodeURIComponent(tmp[1]);
});
return json;
}
/**
* 字符串包含字符数组中字符的状态
* @param {*} array 字符数组
* @param {*} str 字符串
* @returns 包含状态
*/
const strExist = (array, str) => {
const exist = array.filter(arr => {
if (str.indexOf(arr) >= 0) return str;
})
return exist.length > 0
}
/**
* 自定义替换参数
* @param {*} url
* @param {*} arg
* @param {*} arg_val
* @returns
*/
const changeURLArg = (url, arg, arg_val) => {
var pattern = arg + '=([^&]*)';
var replaceText = arg + '=' + arg_val;
if (url.match(pattern)) {
var tmp = '/(' + arg + '=)([^&]*)/gi';
tmp = url.replace(eval(tmp), replaceText);
return tmp;
} else {
if (url.match('[\?]')) {
return url + '&' + replaceText;
} else {
return url + '?' + replaceText;
}
}
return url + '\n' + arg + '\n' + arg_val;
}
// 获取参数key/value值对
const getUrlParams = (url) => {
// 没有参数处理
if (url.split('?').length === 1) return false;
let arr = url.split('?');
let res = arr[1].split('&');
let items = {};
for (let i = 0; i < res.length; i++) {
let [key, value] = res[i].split('=');
items[key] = value;
}
return items
}
// 格式化URL参数为字符串
const stringifyQuery = (params) => {
const queryString = [];
Object.keys(params || {}).forEach((k) => {
queryString.push(k + '=' + params[k]);
});
return '?' + queryString.join('&');
};
export {
formatDate,
wxInfo,
hasEllipsis,
parseQueryString,
strExist,
changeURLArg,
getUrlParams,
stringifyQuery,
};
import VConsole from 'vconsole';
// const vConsole = new VConsole();
let vConsole = '';
// 或者使用配置参数来初始化,详情见文档
if (+import.meta.env.VITE_CONSOLE) {
vConsole = new VConsole({ theme: 'dark' });
}
export default vConsole
/*
* @Date: 2024-02-06 11:38:13
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-02-06 13:04:25
* @FilePath: /xysBooking/src/utils/versionUpdater.js
* @Description:
*/
/* eslint-disable */
/**
* @description: 版本更新检查
* @param {*} time 阈值
* @return {*}
*/
export class Updater {
constructor(options = {}) {
this.oldScript = [];
this.newScript = [];
this.dispatch = {};
this.init(); //初始化
this.timing(options.time); //轮询
}
async init() {
const html = await this.getHtml();
this.oldScript = this.parserScript(html);
}
async getHtml() {
// TAG: html的位置需要动态修改
const html = await fetch(import.meta.env.VITE_BASE).then((res) => res.text()); //读取index html
return html;
}
parserScript(html) {
const reg = new RegExp(/<script(?:\s+[^>]*)?>(.*?)<\/script\s*>/gi); //script正则
return html.match(reg); //匹配script标签
}
//发布订阅通知
on(key, fn) {
(this.dispatch[key] || (this.dispatch[key] = [])).push(fn);
return this;
}
compare(oldArr, newArr) {
const base = oldArr.length;
// 去重
const arr = Array.from(new Set(oldArr.concat(newArr)));
//如果新旧length 一样无更新
if (arr.length === base) {
this.dispatch['no-update'].forEach((fn) => {
fn();
});
} else {
//否则通知更新
this.dispatch['update'].forEach((fn) => {
fn();
});
}
}
timing(time = 10000) {
//轮询
setInterval(async () => {
const newHtml = await this.getHtml();
this.newScript = this.parserScript(newHtml);
this.compare(this.oldScript, this.newScript);
}, time);
}
}
<!--
* @Date: 2022-06-29 18:18:02
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-08 17:25:42
* @FilePath: /custom_dashboard/src/views/404.vue
* @Description: 文件描述
-->
<template>
<div class="">404</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
</script>
<style lang="less" scoped>
</style>
<!--
* @Date: 2022-08-29 13:55:31
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-12-06 20:56:54
* @FilePath: /data-table/src/views/auth.vue
* @Description: 授权模块
-->
<template>
<div />
</template>
<script setup>
import { onMounted } from 'vue'
import { useRoute } from 'vue-router'
const $route = useRoute();
onMounted(() => {
// php需要先跳转链接获取openid
/**
* encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。
* 该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。
* 其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。
*/
let raw_url = encodeURIComponent(location.origin + location.pathname + $route.query.href); // 未授权的地址
// TAG: 开发环境测试数据
const short_url = `/srv/?f=custom_form&a=openid&res=${raw_url}&form_code=${$route.query.code}`;
location.href = import.meta.env.DEV
? `${short_url}&openid=${import.meta.env.VITE_OPENID}`
: `${short_url}`;
})
</script>
<!--
* @Date: 2024-07-08 17:06:30
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-08 17:37:15
* @FilePath: /custom_dashboard/src/views/index.vue
* @Description: 文件描述
-->
<template>
<div class="mb-4">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
onMounted(() => {
console.warn('onMounted');
})
</script>
<style lang="less" scoped>
</style>
<!--
* @Date: 2024-04-02 17:03:26
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-05-17 16:37:21
* @FilePath: /custom_dashboard/src/views/test.vue
* @Description: 文件描述
-->
<template>
<div style="">
<!--<svg width="500" height="500" viewBox="0 0 900 900">
<!~~ 定义裁剪路径 ~~>
<defs>
<clipPath id="clippath">
<!~~ 使用有效的路径来定义裁剪形状 ~~>
<path d="M0 0 L300 0 L300 110 A40 40 180 0 1 300 190 L300 300 L190 300 A40 40 180 0 0 110 300 L0 300 Z" />
</clipPath>
</defs>
<!~~ 应用遮罩和裁剪路径到图像 ~~>
<image width="900" height="900" :href="imageSrc" style="clip-path: url(#clippath); filter: grayscale(100%);" mask="url(#mask)" />
</svg>-->
<!--<div style="width: 100%; height: 100%;" class="boxer" >
<!~~ <div style="width: 100%; height: 100%;" > ~~>
<svg width="100%" height="100%" viewBox="0 0 100 100">
<!~~ 图像 ~~>
<!~~ <image style="width: 100%; height: 100%;" :href="imageSrc" /> ~~>
<!~~ 第一个格子的遮罩层 ~~>
<polygon points="0,0 20,0 20,20 0,20" fill="black" opacity="0.5" />
<!~~ 第二个格子的遮罩层 ~~>
<polygon points="10,10 30,10 30,30 10,30 10,20 20,20 20,10 10,10" fill="black" opacity="0.5" />
</svg>
</div>-->
<!-- <button @click="changeColor">改变颜色</button> -->
<!-- <div class="container-t"> -->
<!-- <div class="shape shape-t">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Corrupti recusandae fugiat dicta ipsam ex non sunt maiores, nisi animi repellendus fugit facilis. Vitae pariatur cupiditate totam laboriosam optio! Qui, enim.
</div> -->
<!-- <div class="shape shape1"></div>
<div class="shape shape2"></div>
<div class="shape shape3"></div>
<div class="shape shape4"></div> -->
<!-- </div> -->
<!-- <div class="container">
<img src="https://cdn.ipadbiz.cn/tmp/fx_park/s1.png" class="img">
</div>
<div class="container">
<img src="https://cdn.ipadbiz.cn/tmp/fx_park/s2.png" class="img">
</div>
<div class="container">
<img src="https://cdn.ipadbiz.cn/tmp/fx_park/s3.png" class="img">
</div>
<div class="container">
<img src="https://cdn.ipadbiz.cn/tmp/fx_park/s4.png" class="img">
</div>
<div class="container">
<img src="https://cdn.ipadbiz.cn/tmp/fx_park/s5.png" class="img">
</div>
<div class="container">
<img src="https://cdn.ipadbiz.cn/tmp/fx_park/s6.png" class="img">
</div> -->
<geo-chart></geo-chart>
</div>
</template>
<script>
import mixin from 'common/mixin';
import GeoChart from '@/components/GeoChart.vue';
/*
如果希望 <polygon> 的位置和形状能够相对于图片保持不变,
可以考虑使用 viewBox 和 viewBox 中的坐标系来定义 <polygon> 的顶点坐标。
这样,无论图片大小如何改变,<polygon> 的位置和形状都会相对于图片保持不变。
使用 viewBox 和 viewBox 中的坐标系来定义 <polygon> 的顶点坐标:
*/
export default {
components: {
GeoChart
},
mixins: [mixin.init],
data () {
return {
imageSrc: 'https://picsum.photos/500/500',
svg_color: 'black',
}
},
mounted () {
},
methods: {
changeColor () {
this.svg_color = this.svg_color === 'black' ? 'white' : 'black';
}
}
}
</script>
<style lang="less" scoped>
.boxer {
background-image: url('https://picsum.photos/375/729');
background-repeat: no-repeat;
background-size: cover;
background-position: center;
}
.container-t {
width: 100%;
height: 100vh;
background-image: url('https://picsum.photos/375/729');
background-size: cover;
position: relative;
overflow: hidden; /* 确保超出容器部分被隐藏 */
}
.container {
width: 100%;
height: 100%;
background-size: contain;
position: absolute;
z-index: 1;
top: 0;
left: 0;
background-repeat: no-repeat;
}
.container1 {
width: 100%;
height: 100%;
background-size: contain;
position: absolute;
z-index: 1;
top: 0;
left: 0;
background-repeat: no-repeat;
}
.container2 {
width: 100%;
height: 100%;
background-size: contain;
position: absolute;
z-index: 10;
top: 0;
right: 0;
background-repeat: no-repeat;
}
.container3 {
width: 100%;
height: 100%;
// background-image: url('https://cdn.ipadbiz.cn/tmp/fx_park/s3.png');
background-size: contain;
position: absolute;
// overflow: hidden; /* 确保超出容器部分被隐藏 */
z-index: 10;
top: 0;
right: 0;
background-repeat: no-repeat;
}
.container4 {
width: 100%;
height: 100%;
// background-image: url('https://cdn.ipadbiz.cn/tmp/fx_park/s4.png');
background-size: contain;
position: absolute;
// overflow: hidden; /* 确保超出容器部分被隐藏 */
z-index: 10;
top: 0;
right: 0;
background-repeat: no-repeat;
}
.container5 {
width: 100%;
height: 100%;
// background-image: url('https://cdn.ipadbiz.cn/tmp/fx_park/s5.png');
background-size: contain;
position: absolute;
// overflow: hidden; /* 确保超出容器部分被隐藏 */
z-index: 10;
top: 0;
right: 0;
background-repeat: no-repeat;
background-position: left;
}
.container6 {
width: 100%;
height: 100%;
// background-image: url('https://cdn.ipadbiz.cn/tmp/fx_park/s6.png');
background-size: contain;
position: absolute;
// overflow: hidden; /* 确保超出容器部分被隐藏 */
z-index: 10;
bottom: 0;
right: 0;
background-repeat: no-repeat;
background-position: right;
}
.img {
position: absolute; top: 0; left: 0; width: 100%; object-fit: cover;
}
.mask {
mask: linear-gradient(to right, transparent, rgb(0, 0, 0));
}
.shape {
position: absolute;
}
.shape-t {
clip-path: polygon(52% 6.67%, 77.67% 10.67%, 90% 28.33%, 94% 54.67%, 86.33% 91%, 51.67% 94%, 22.67% 88.67%, 16.67% 64%, 13.33% 32.33%, 26% 11%);
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba(119, 119, 119, 0.5);
border: 1px solid rgba(119, 119, 119, 0.5);
}
.shape1 {
clip-path: polygon(50% 0%, 74% 31%, 54% 82%, 33% 100%, 0 100%, 0% 60%, 0 0);
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba(119, 119, 119, 0.5);
border: 1px solid rgba(119, 119, 119, 0.5);
}
.shape2 {
clip-path: polygon(50% 0%, 74% 31%, 54% 82%, 33% 100%, 100% 100%, 100% 54%, 100% 0);
width: 100%;
height: 100%;
top: 0;
right: 0;
background-color: rgba(20, 120, 119, 0.5);
}
</style>
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vanilla:hover {
filter: drop-shadow(0 0 2em #f7df1eaa);
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
{
"compilerOptions": {
/* 基本选项 */
"target": "esnext", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
"module": "CommonJS", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
"lib": [ // 指定要包含在编译中的库文件
"esnext",
"dom",
"dom.iterable",
"scripthost"
],
"allowJs": true, // 允许编译 javascript 文件
// "checkJs": true, // 报告 javascript 文件中的错误
"jsx": "preserve", // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
// "declaration": true, // 生成相应的 '.d.ts' 文件
// "sourceMap": true, // 生成相应的 '.map' 文件
// "outFile": "./", // 将输出文件合并为一个文件
"outDir": "./", // 指定输出目录
// "rootDir": "./", // 用来控制输出目录结构 --outDir.
"removeComments": true, // 删除编译后的所有的注释
// "noEmit": true, // 不生成输出文件
"importHelpers": true, // tslib 导入辅助工具函数
"isolatedModules": false, // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似)
/* 严格的类型检查选项 */
"strict": true, // 启用所有严格类型检查选项
// "noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错
// "strictNullChecks": true, // 启用严格的 null 检查
// "noImplicitThis": true, // this 表达式值为 any 类型的时候,生成一个错误
// "alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict'
/* 额外的检查 */
"noUnusedLocals": true, // 有未使用的变量时,抛出错误
"noUnusedParameters": true, // 有未使用的参数时,抛出错误
"noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时,抛出错误
"noFallthroughCasesInSwitch": true, // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch case 语句贯穿)
/* 模块解析选项 */
"moduleResolution": "node", // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
"baseUrl": ".", // 用于解析非相对模块名称的基目录
"paths": { // 模块名到基于 baseUrl 的路径映射的列表
"@/*": [
"src/*"
]
},
// "rootDirs": [], // 根文件夹列表,其组合内容表示项目运行时的结构内容
// "typeRoots": [], // 包含类型声明的文件列表
"types": [ // 需要包含的类型声明文件名列表
// "webpack-env",
"vite/client",
"lodash",
"moment",
"node",
"jquery",
"element-plus/global"
],
"allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。
/* Source Map Options */
// "sourceRoot": "./", // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
// "mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置
// "inlineSourceMap": true, // 生成单个 sourcemaps 文件,而不是将 sourcemaps 生成不同的文件
// "inlineSources": true, // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap --sourceMap 属性
/* 其他选项 */
"experimentalDecorators": true, // 启用装饰器
// "emitDecoratorMetadata": true, // 为装饰器提供元数据的支持
"esModuleInterop": true, // 可以在es6中导入commonjs
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist"
],
"vueCompilerOptions": {
"target": 2,
"experimentalSuppressInvalidJsxElementTypeErrors": true
}
}
import vue from '@vitejs/plugin-vue';
import dynamicImport from 'vite-plugin-dynamic-import';
// import legacy from '@vitejs/plugin-legacy';
// import styleImport, { VantResolve } from 'vite-plugin-style-import';
import { defineConfig, loadEnv } from 'vite';
import { createProxy } from './build/proxy'
// import { codeInspectorPlugin } from 'code-inspector-plugin';
import DefineOptions from 'unplugin-vue-define-options/vite';
import AutoImport from 'unplugin-auto-import/vite';
var path = require('path');
// const { createVuePlugin } = require('vite-plugin-vue2')
export default ({ command, mode }) => {
const root = process.cwd();
const viteEnv = loadEnv(mode, root);
// let isProd = (command === 'serve'); // 情景配置是否为开发模式 serve 或 build
return defineConfig({
// root: '',
// root: './src/packages', // 多页面应用配置入口根目录
base: viteEnv.VITE_BASE, // 开发或生产环境服务的公共基础路径。
// base: isProd ? '/' : '/f/voice/', // 开发或生产环境服务的公共基础路径。
// mode: '', // 在配置中指明将会把 serve 和 build 时的模式 都 覆盖掉。也可以通过命令行 --mode 选项来重写。
// define: '', // 定义全局常量替换方式。其中每项在开发环境下会被定义在全局,而在构建时被静态替换。
plugins: [ // 将要用到的插件数组。Falsy 虚值的插件将被忽略,插件数组将被扁平化(flatten)。查看 插件 API 获取 Vite 插件的更多细节。
// createVuePlugin(),
vue(),
// styleImport({
// resolves: [VantResolve()],
// libs: [
// {
// libraryName: 'vant',
// esModule: true,
// resolveStyle: name => `../es/${name}/style`
// }
// ]
// }), // 按需引入 vant 位置报错问题
dynamicImport(), // 增强 Vite 内置的 dynamic import, 支持在 import() 中使用别名
// legacy({
// targets: ['defaults', 'not IE 11']
// }), // Vite 的默认旧版浏览器支持时提供此插件本机ESM的支持。
// codeInspectorPlugin({
// bundler: 'vite',
// }), // 点击页面上的元素,能够自动打开你的代码编辑器并将光标定位到元素对应的代码位置。
DefineOptions(), // TAG: 插件来对组件名进行注册的, 解决setup没法写name的问题
AutoImport({ // API 自动导入
// 可以自定义文件生成的位置,默认是根目录下,使用ts的建议放src目录下
dts: 'src/auto-imports.d.ts',
imports: ['vue', 'vue-router'],
// 解决eslint报错问题
eslintrc: {
enabled: true
}
}),
],
publicDir: 'public', // 作为静态资源服务的文件夹。这个目录中的文件会在开发中被服务于 /,在开发模式时,会被拷贝到 outDir 的根目录,并没有转换,永远只是复制到这里。该值可以是文件系统的绝对路径,也可以是相对于项目的根目录路径。
// cacheDir: '', // 存储缓存文件的目录。此目录下会存储预打包的依赖项或 vite 生成的某些缓存文件,使用缓存可以提高性能。如需重新生成缓存文件,你可以使用 --force 命令行选项或手动删除目录。此选项的值可以是文件的绝对路径,也可以是以项目根目录为基准的相对路径。
resolve: {
alias: { // 将会被传递到 @rollup/plugin-alias 作为 entries 的选项。也可以是一个对象,或一个 { find, replacement } 的数组. 当使用文件系统路径的别名时,请始终使用绝对路径。相对路径的别名值会被原封不动地使用,因此无法被正常解析。 更高级的自定义解析方法可以通过 插件 实现。
"@": path.resolve(__dirname, "src"),
"@components": path.resolve(__dirname, "src/components"),
"@utils": path.resolve(__dirname, "src/utils"),
"@images": path.resolve(__dirname, "src/assets/images"),
"@css": path.resolve(__dirname, "src/assets/css"),
"@mock": path.resolve(__dirname, "src/assets/mock"),
"common": path.resolve(__dirname, "src/common"),
"@api": path.resolve(__dirname, "src/api"),
},
// dedupe: [''], // 如果你在你的应用程序中有相同依赖的副本(比如 monorepos),使用这个选项来强制 Vite 总是将列出的依赖关系解析到相同的副本(从项目根目录)。
// conditions: [''], // 在解析包的 情景导出 时允许的附加条件。
// mainFields: [''], // package.json 中,在解析包的入口点时尝试的字段列表。注意,这比从 exports 字段解析的情景导出优先级低:如果一个入口点从 exports 成功解析,主字段将被忽略。
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], // 导入时想要省略的扩展名列表。注意,不 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会干扰 IDE 和类型支持。
},
css: {
modules: '', // 配置 CSS modules 的行为。选项将被传递给 postcss-modules。
postcss: { // 内联的 PostCSS 配置(格式同 postcss.config.js),或者一个(默认基于项目根目录的)自定义的 PostCSS 配置路径。其路径搜索是通过 postcss-load-config 实现的。 注意,如果提供了该内联配置,Vite 将不会搜索其他 PostCSS 配置源。
plugins: []
},
preprocessorOptions: {
less: {
javascriptEnabled: true,
additionalData: `@import "${path.resolve(__dirname, 'src/assets/styles/base.less')}";`
}
} // 指定传递给 CSS 预处理器的选项。
},
// json: {
// namedExports: true, // 是否支持从 .json 文件中进行按名导入。
// stringify: false, // 若设置为 true,导入的 JSON 会被转换为 export default JSON.parse("...") 会比转译成对象字面量性能更好,尤其是当 JSON 文件较大的时候。 开启此项,则会禁用按名导入。
// },
// esbuild: false, //
// assetsInclude: '', // 指定其他文件类型作为静态资源处理
logLevel: 'info', // 调整控制台输出的级别,默认为 'info'。
// clearScreen: true, // 设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息。命令行模式下请通过 --clearScreen false 设置。
server: {
host: '0.0.0.0',
port: viteEnv.VITE_PORT, // 本地服务端口
// strictPort: true, // 设为true时若端口已被占用则会直接退出, 而不是尝试下一个可用端口
// https: '',
// open: false, // 在服务器启动时自动在浏览器中打开应用程序. 当此值为字符串时, 会被当作URL的路径名.
// proxy: { // 代理
// '/srv/': {
// // target: 'http://voice.onwall.cn',
// target: viteEnv.VITE_PROXY_TARGET,
// changeOrigin: true,
// // rewrite: (path) => path.replace(/^\/api/, '')
// },
// },
proxy: createProxy(viteEnv.VITE_PROXY_PREFIX, viteEnv.VITE_PROXY_TARGET),
// cors: '', // 为开发服务器配置 CORS。默认启用并允许任何源,传递一个 选项对象 来调整行为或设为 false 表示禁用。
// force: '', // 设置为 true 强制使依赖预构建。
// hmr: '', // 禁用或配置 HMR 连接(用于 HMR websocket 必须使用不同的 http 服务器地址的情况)。 设置 server.hmr.overlay 为 false 可以禁用服务器错误遮罩层。
// watch: '', // 传递给 chokidar 的文件系统监视器选项。
},
build: {
// outDir: 'voice', // 指定输出路径(相对于项目根目录).
outDir: viteEnv.VITE_OUTDIR, // 指定输出路径(相对于项目根目录).
assetsDir: 'static',
rollupOptions: {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
},
input: { // 多页面应用模式, 打包时配置,运行配置要处理root
main: path.resolve(__dirname, 'index.html'),
// mono1: path.resolve(__dirname, 'src/packages/mono1/index.html'),
// mono2: path.resolve(__dirname, 'src/packages/mono2/index.html'),
}
},
},
optimizeDeps: {
// entries: '',
// exclude: [],
include: ['jquery', 'lodash', 'moment', 'axios', 'vue-router'], // 默认情况下,不在 node_modules 中的,链接的包不会被预构建。使用此选项可强制预构建链接的包。
// keepNames: false, // 打包器有时需要重命名符号以避免冲突。 设置此项为 true 可以在函数和类上保留 name 属性。 若想获取更多详情,请参阅 keepNames
}
});
};
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.