hookehuyr

项目初始化

Showing 69 changed files with 2795 additions and 0 deletions
1 +# port
2 +VITE_PORT = 5173
3 +
4 +# API请求前缀
5 +VITE_PROXY_PREFIX = /admin/
6 +
7 +# 打包输出文件夹名称
8 +VITE_OUTDIR = custom_dashboard
1 +# 资源公共路径
2 +VITE_BASE = /
3 +
4 +# 反向代理服务器地址
5 +VITE_PROXY_TARGET = http://oa-dev.onwall.cn
6 +# VITE_PROXY_TARGET = http://www.wxgzjs.cn/
7 +
8 +# 移动端地址
9 +VITE_MOBILE_URL = http://localhost:8108/
1 +# 资源公共路径
2 +VITE_BASE = /admin/custom_dashboard
3 +
4 +# 反向代理服务器地址
5 +VITE_PROXY_TARGET = http://oa.onwall.cn
6 +# VITE_PROXY_TARGET = http://www.wxgzjs.cn/
7 +
8 +# 移动端地址
9 +# VITE_MOBILE_URL = http://oa.onwall.cn/f/guanzong/front/
10 +# VITE_MOBILE_URL = http://www.wxgzjs.cn/f/guanzong/front/
1 +{
2 + "globals": {
3 + "Component": true,
4 + "ComponentPublicInstance": true,
5 + "ComputedRef": true,
6 + "EffectScope": true,
7 + "ExtractDefaultPropTypes": true,
8 + "ExtractPropTypes": true,
9 + "ExtractPublicPropTypes": true,
10 + "InjectionKey": true,
11 + "PropType": true,
12 + "Ref": true,
13 + "VNode": true,
14 + "WritableComputedRef": true,
15 + "computed": true,
16 + "createApp": true,
17 + "customRef": true,
18 + "defineAsyncComponent": true,
19 + "defineComponent": true,
20 + "effectScope": true,
21 + "getCurrentInstance": true,
22 + "getCurrentScope": true,
23 + "h": true,
24 + "inject": true,
25 + "isProxy": true,
26 + "isReactive": true,
27 + "isReadonly": true,
28 + "isRef": true,
29 + "markRaw": true,
30 + "nextTick": true,
31 + "onActivated": true,
32 + "onBeforeMount": true,
33 + "onBeforeRouteLeave": true,
34 + "onBeforeRouteUpdate": true,
35 + "onBeforeUnmount": true,
36 + "onBeforeUpdate": true,
37 + "onDeactivated": true,
38 + "onErrorCaptured": true,
39 + "onMounted": true,
40 + "onRenderTracked": true,
41 + "onRenderTriggered": true,
42 + "onScopeDispose": true,
43 + "onServerPrefetch": true,
44 + "onUnmounted": true,
45 + "onUpdated": true,
46 + "provide": true,
47 + "reactive": true,
48 + "readonly": true,
49 + "ref": true,
50 + "resolveComponent": true,
51 + "shallowReactive": true,
52 + "shallowReadonly": true,
53 + "shallowRef": true,
54 + "toRaw": true,
55 + "toRef": true,
56 + "toRefs": true,
57 + "toValue": true,
58 + "triggerRef": true,
59 + "unref": true,
60 + "useAttrs": true,
61 + "useCssModule": true,
62 + "useCssVars": true,
63 + "useLink": true,
64 + "useRoute": true,
65 + "useRouter": true,
66 + "useSlots": true,
67 + "watch": true,
68 + "watchEffect": true,
69 + "watchPostEffect": true,
70 + "watchSyncEffect": true
71 + }
72 +}
1 +node_modules
2 +.history
3 +custom_dashboard
1 +export function createProxy(prefix, target) {
2 + const ret = {};
3 + ret[prefix] = {
4 + target,
5 + changeOrigin: true,
6 + ws: true,
7 + // rewrite: (path) => path.replace(/^\/api/, '')
8 + // rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
9 + }
10 + return ret
11 +}
1 +export function setupCounter(element) {
2 + let counter = 0
3 + const setCounter = (count) => {
4 + counter = count
5 + element.innerHTML = `count is ${counter}`
6 + }
7 + element.addEventListener('click', () => setCounter(++counter))
8 + setCounter(0)
9 +}
1 +<!--
2 + * @Date: 2022-07-25 11:01:23
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-07-08 17:49:15
5 + * @FilePath: /my-data-summary/index.html
6 + * @Description: 文件描述
7 +-->
8 +<!DOCTYPE html>
9 +<html lang="en">
10 + <head>
11 + <meta charset="UTF-8" />
12 + <link rel="icon" type="image/svg+xml" href="http://www.wxgzjs.cn/template/default/static/images/favicon.ico" />
13 + <meta name="viewport" content="width=device-width, initial-scale=1.0" />
14 + <title>数据汇总</title>
15 + </head>
16 + <body>
17 + <div id="app"></div>
18 + <script type="module" src="/src/main.js"></script>
19 + </body>
20 +</html>
1 +<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 ...\ No newline at end of file
This diff could not be displayed because it is too large.
1 +{
2 + "name": "vue3-vite",
3 + "private": true,
4 + "version": "0.0.0",
5 + "scripts": {
6 + "dev": "vite",
7 + "build": "vite build",
8 + "preview": "vite preview",
9 + "tar": "tar -czvpf dist.tar.gz custom_dashboard",
10 + "build_tar": "npm run build && npm run tar",
11 + "scp-oa": "scp dist.tar.gz itomix@ipadbiz.cn:/opt/oa/f/",
12 + "dec-oa": "ssh itomix@ipadbiz.cn 'cd /opt/oa/f/ && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
13 + "scp-dev": "scp dist.tar.gz itomix@ipadbiz.cn:/opt/space-dev/admin/",
14 + "dec-dev": "ssh itomix@ipadbiz.cn 'cd /opt/space-dev/admin/ && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
15 + "remove_tar": "rm -rf dist.tar.gz",
16 + "oa_upload": "npm run build_tar && npm run scp-oa && npm run dec-oa && npm run remove_tar",
17 + "dev_upload": "npm run build_tar && npm run scp-dev && npm run dec-dev && npm run remove_tar"
18 + },
19 + "devDependencies": {
20 + "@vitejs/plugin-legacy": "^2.0.0",
21 + "@vitejs/plugin-vue": "^5.0.5",
22 + "code-inspector-plugin": "^0.9.2",
23 + "swiper": "^5.4.5",
24 + "unplugin-auto-import": "^0.17.6",
25 + "unplugin-vue-define-options": "^1.4.5",
26 + "vite": "^3.0.0",
27 + "vite-plugin-dynamic-import": "^1.0.0",
28 + "vite-plugin-style-import": "1.4.1",
29 + "vite-plugin-vue2": "^2.0.2",
30 + "vue-awesome-swiper": "^4.1.1"
31 + },
32 + "dependencies": {
33 + "@fortawesome/free-brands-svg-icons": "^6.5.2",
34 + "@fortawesome/free-regular-svg-icons": "^6.5.2",
35 + "@fortawesome/free-solid-svg-icons": "^6.5.2",
36 + "@fortawesome/vue-fontawesome": "^2.0.10",
37 + "axios": "^0.27.2",
38 + "dayjs": "^1.11.4",
39 + "echarts": "^5.5.0",
40 + "element-plus": "^2.7.6",
41 + "element-ui": "^2.15.14",
42 + "floating-vue": "^1.0.0-beta.19",
43 + "jquery": "^3.6.0",
44 + "js-cookie": "^3.0.1",
45 + "less": "^4.1.3",
46 + "lodash": "^4.17.21",
47 + "moment": "^2.29.4",
48 + "mui-player": "^1.6.1",
49 + "pinia": "^2.1.7",
50 + "uuid": "^9.0.1",
51 + "vant": "^2.12.48",
52 + "vue": "^3.4.31",
53 + "vue-grid-layout": "^2.4.0",
54 + "vue-router": "^4.4.0",
55 + "vue-template-compiler": "^2.7.16",
56 + "vuex": "3.6.2",
57 + "vxe-table": "^3.7.9",
58 + "xe-utils": "^3.5.22"
59 + }
60 +}
1 +<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 ...\ No newline at end of file
1 +#!/usr/bin/env sh
2 +# -----------------------------------------------
3 +# Filename: publish.sh
4 +# Revision: 1.0
5 +# Date: 2022年8月05日
6 +# Author: Hooke
7 +# Description: **** 根据php项目相应特征书写项目发布流程
8 +# -----------------------------------------------
9 +
10 +# 当发生错误时中止脚本
11 +set -e
12 +
13 +# 本地Git服务器目录路径
14 +path=/Users/huyirui/program/itomix/git/isp/f/guanzong
15 +
16 +# 编译输出文件夹
17 +output=web
18 +
19 +# 打包
20 +npm run build
21 +
22 +# 移除Git服务器目录下项目文件夹
23 +rm -r $path"/${output:?}"
24 +
25 +# 把本地编译输出文件夹添加到服务器目录
26 +mv "${output:?}/" $path
27 +
28 +# 提交到Git服务器
29 +cd $path"/${output:?}"
30 +git pull
31 +git add -A
32 +git commit -m '前端网页更新'
33 +git push
34 +
35 +# 更新SSH服务器上文件
36 +ssh -p 22 itomix@ipadbiz.cn 'cd /opt/voice/f/guanzong/web && git pull'
1 +<!--
2 + * @Date: 2022-07-25 11:04:45
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-04-29 10:53:39
5 + * @FilePath: /custom_dashboard/src/App.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div>
10 + <router-view />
11 + </div>
12 +</template>
13 +
14 +<script>
15 +import { wxInfo } from '@/utils/tools'
16 +import { Updater } from '@/utils/versionUpdater'
17 +
18 +export default {
19 + components: { },
20 + mounted () {
21 + // 正式环境
22 + // TAG:检查是否更新
23 + if (import.meta.env.PROD) {
24 + const upDater = new Updater({
25 + time: 30000
26 + })
27 + upDater.on('no-update', () => {
28 + // console.log('还没更新')
29 + })
30 + upDater.on('update', () => {
31 + // console.log('已经更新了,请刷新页面')
32 + this.$confirm('检测到新版本,是否刷新?', '温馨提示', {
33 + confirmButtonText: '确定',
34 + cancelButtonText: '取消',
35 + type: 'warning'
36 + }).then(() => {
37 + window.location.reload();
38 + }).catch(() => {
39 + });
40 + })
41 + }
42 + },
43 + data () {
44 + return {
45 + }
46 + }
47 +}
48 +</script>
49 +
50 +
51 +<style lang="less">
52 +* {
53 + outline: none;
54 +}
55 +
56 +// 隐藏浏览器自带滚动条
57 +// *::-webkit-scrollbar {
58 +// display: none;
59 +// }
60 +// * {
61 +// scrollbar-width: none;
62 +// }
63 +// * {
64 +// -ms-overflow-style: none;
65 +// }
66 +//
67 +
68 +html,
69 +body {
70 + font-size: 16px;
71 + width: 100%;
72 + height: 100%;
73 + margin: 0;
74 + padding: 0;
75 + p {
76 + margin: 0;
77 + padding: 0;
78 + }
79 +}
80 +
81 +.global-center {
82 + position: relative;
83 + top: 50%;
84 + transform: translateY(-50%);
85 +}
86 +
87 +.nav-bar {
88 + background-color: #2B000C;
89 + color: #D4D4D4;
90 +}
91 +
92 +</style>
1 +/*
2 + * @Date: 2022-06-17 14:54:29
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-08-18 10:52:55
5 + * @FilePath: /web/src/api/common.js
6 + * @Description: 公共接口
7 + */
8 +import { fn, fetch } from '@/api/fn';
9 +
10 +const Api = {
11 + NAVI: '/srv/?a=navi_bar',
12 + PUMING_INFO: '/srv/?a=puming_info',
13 + CHANNEL_PAGE: '/srv/?a=channel_page',
14 + CHANNEL_BAR: '/srv/?a=channel_bar',
15 + FAHUI_LIST: '/srv/?a=fahui_list',
16 +}
17 +
18 +/**
19 + * @description: 导航目录
20 + * @returns
21 + */
22 +export const naviAPI = (params) => fn(fetch.get(Api.NAVI, params));
23 +
24 +/**
25 + * @description: 普明慈善基金会
26 + * @returns
27 + */
28 +export const pumingInfoAPI = (params) => fn(fetch.get(Api.PUMING_INFO, params));
29 +
30 +/**
31 + * @description: 侧边频道页和导航相关信息
32 + * @returns
33 + */
34 +export const sideNaviAPI = (params) => fn(fetch.get(Api.CHANNEL_PAGE, params));
35 +
36 +/**
37 + * @description: 频道介绍和其他相关展示信息
38 + * @returns
39 + */
40 +export const channelInfoAPI = (params) => fn(fetch.get(Api.CHANNEL_BAR, params));
41 +
42 +/**
43 + * @description: 法会活动
44 + * @returns
45 + */
46 +export const fahuiListAPI = (params) => fn(fetch.get(Api.FAHUI_LIST, params));
1 +/*
2 + * @Date: 2022-05-18 22:56:08
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-07-28 17:46:42
5 + * @FilePath: /web/src/api/fn.js
6 + * @Description: 文件描述
7 + */
8 +import axios from '@/utils/axios';
9 +import { Message } from 'element-ui';
10 +import qs from 'Qs'
11 +
12 +/**
13 + * 网络请求功能函数
14 + * @param {*} api 请求axios接口
15 + * @returns 请求成功后,获取数据
16 + */
17 +export const fn = (api) => {
18 + return api
19 + .then(res => {
20 + if (res.data.code === 1) {
21 + return res.data || true;
22 + } else {
23 + console.warn(res);
24 + if (!res.data.show) return false;
25 + Message({
26 + message: res.data.msg,
27 + type: 'warning'
28 + });
29 + return false;
30 + }
31 + })
32 + .catch(err => {
33 + console.error(err);
34 + return false;
35 + })
36 + .finally(() => { // 最终执行
37 + })
38 +}
39 +
40 +/**
41 + * 统一 GET/POST 不同传参形式
42 + */
43 +export const fetch = {
44 + get: function (api, params) {
45 + return axios.get(api, { params })
46 + },
47 + post: function (api, params) {
48 + return axios.post(api, params)
49 + },
50 + stringifyPost: function (api, params) {
51 + return axios.post(api, qs.stringify(params))
52 + },
53 + basePost: function (url, data, config) {
54 + return axios.post(url, data, config)
55 + }
56 +}
1 +/*
2 + * @Date: 2022-06-17 14:54:29
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-04-03 14:09:34
5 + * @FilePath: /custom_dashboard/src/api/index.js
6 + * @Description: 首页接口
7 + */
8 +import { fn, fetch } from '@/api/fn';
9 +
10 +const Api = {
11 + CHART_SQL_LIST: '/admin/?a=chart_sql_list',
12 + SAVE_CHART_SQL: '/admin/?a=save_chart_sql',
13 + DEL_CHART_SQL: '/admin/?a=del_chart_sql',
14 + CHART_SQL_SETTING_LIST: '/admin/?a=chart_sql_setting_list',
15 + SAVE_CHART_SQL_SETTING: '/admin/?a=save_chart_sql_setting',
16 + CHART_SQL_BOARD_LIST: '/admin/?a=chart_sql_board_list',
17 + SAVE_CHART_SQL_BOARD: '/admin/?a=save_chart_sql_board',
18 + DEL_CHART_SQL_BOARD: '/admin/?a=del_chart_sql_board',
19 + DEL_CHART_SQL_SETTING: '/admin/?a=del_chart_sql_setting',
20 + SAVE_CHART_SQL_LOCATION: '/admin/?a=save_chart_sql_location',
21 + CHART_DATA_MIX_LINE_BAR: '/admin/?a=chart_data_mix_line_bar',
22 + SHOW_CHART_SQL: '/admin/?a=show_chart_sql',
23 + DUPLICATE_CHART_SQL: '/admin/?a=duplicate_chart_sql',
24 +}
25 +
26 +/**
27 + * @description: sql数据源列表
28 + */
29 +export const chartSqlListAPI = (params) => fn(fetch.get(Api.CHART_SQL_LIST, params));
30 +
31 +/**
32 + * @description: 保存sql数据源
33 + * @param {*} id sql数据源id。为空表示新增,否则是更新。
34 + * @param {*} name sql数据源名称
35 + * @param {*} chart_mode 图表类型
36 + * @param {*} sql_stat sql语句
37 + * @param {*} sql_col sql语句输出的字段
38 + * @param {*} sql_parm sql语句的执行参数
39 + * @param {*} status 状态
40 + * @param {*} note sql数据源的描述
41 + */
42 +export const saveChartSqlAPI = (params) => fn(fetch.post(Api.SAVE_CHART_SQL, params))
43 +
44 +/**
45 + * @description: 删除sql数据源
46 + * @param {*} id sql数据源id
47 + */
48 +export const delChartSqlAPI = (params) => fn(fetch.post(Api.DEL_CHART_SQL, params))
49 +
50 +/**
51 + * @description: sql版图表列表
52 + * @param {*} name 图表名称,模糊查询
53 + * @param {*} chart_mode 图表类型,json数组,可以查询多个类型
54 + * @param {*} status 状态,json数组,可以查询多个状态
55 + * @param {*} row_num 每页行数,默认20
56 + * @param {*} page 当前页数,默认1,从1开始,1表示第一页,2表示第二页,依次类推;
57 + */
58 +export const chartSqlSettingListAPI = (params) => fn(fetch.get(Api.CHART_SQL_SETTING_LIST, params))
59 +
60 +/**
61 + * @description: 仪表盘内保存sql版图表
62 + * @param {*}
63 + */
64 +export const saveChartSqlSettingAPI = (params) => fn(fetch.post(Api.SAVE_CHART_SQL_SETTING, params))
65 +
66 +/**
67 + * @description: sql版仪表盘列表
68 + */
69 +export const chartSqlBoardListAPI = (params) => fn(fetch.get(Api.CHART_SQL_BOARD_LIST, params));
70 +
71 +/**
72 + * @description: 保存sql版仪表盘
73 + * @param {*} id sql版仪表盘id。为空表示新增,否则是更新。
74 + * @param {*} name sql版仪表盘名称
75 + * @param {*} note sql版仪表盘的描述
76 + */
77 +export const saveChartSqlBoardAPI = (params) => fn(fetch.post(Api.SAVE_CHART_SQL_BOARD, params))
78 +
79 +/**
80 + * @description: 删除sql版仪表盘
81 + * @param {*} id sql版仪表盘id。
82 + */
83 +export const delChartSqlBoardAPI = (params) => fn(fetch.post(Api.DEL_CHART_SQL_BOARD, params))
84 +
85 +/**
86 + * @description: 仪表盘内删除sql版图表
87 + * @param {*} id sql版仪表盘id。
88 + */
89 +export const delChartSqlSettingAPI = (params) => fn(fetch.post(Api.DEL_CHART_SQL_SETTING, params))
90 +
91 +/**
92 + * @description: 仪表盘内保存sql版图表位置
93 + * @param {*} board_id 仪表盘id
94 + * @param {*} location 仪表盘内所有图表的位置,json数组格式
95 + */
96 +export const saveChartSqlLocationAPI = (params) => fn(fetch.post(Api.SAVE_CHART_SQL_LOCATION, params))
97 +
98 +/**
99 + * @description: 双轴图的展示数据
100 + * @param {*} data 左右轴的图表数据
101 + */
102 +export const chartDataMixLineBarAPI = (params) => fn(fetch.get(Api.CHART_DATA_MIX_LINE_BAR, params))
103 +
104 +/**
105 + * @description: 展示一个sql版图表
106 + * @param {*}
107 + */
108 +export const showChartSqlAPI = (params) => fn(fetch.get(Api.SHOW_CHART_SQL, params))
109 +
110 +/**
111 + * @description: 复制sql数据源
112 + * @param {*} sql_id sql数据源id
113 + */
114 +export const duplicateChartSqlAPI = (params) => fn(fetch.get(Api.DUPLICATE_CHART_SQL, params))
1 +/*
2 + * @Date: 2022-06-17 14:54:29
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-08-04 14:49:05
5 + * @FilePath: /web/src/api/temple.js
6 + * @Description: 走进寺庙接口
7 + */
8 +import { fn, fetch } from '@/api/fn';
9 +
10 +const Api = {
11 + TEMPLE_INFO: '/srv/?a=temple_info',
12 +}
13 +
14 +/**
15 + * @description: 走进寺庙
16 + * @returns
17 + */
18 +export const templeInfoAPI = (params) => fn(fetch.get(Api.TEMPLE_INFO, params));
1 +/* ============ 颜色 ============ */
2 +
3 +// 文字颜色
4 +@text-color: #333333;
5 +// Hover颜色
6 +@hover-color: #2B000C;
7 +// Hover颜色
8 +@hover-main-color: #F3BB66;
9 +// 次要颜色
10 +@sub-color: #2B000C;
11 +// 文字附件颜色
12 +@affix-color: #999999;
13 +
14 +.multi-ellipsis--l1 {
15 + display: -webkit-box;
16 + overflow: hidden;
17 + text-overflow: ellipsis;
18 + -webkit-line-clamp: 1;
19 + -webkit-box-orient: vertical;
20 +}
21 +
22 +.multi-ellipsis--l2 {
23 + display: -webkit-box;
24 + overflow: hidden;
25 + text-overflow: ellipsis;
26 + -webkit-line-clamp: 2;
27 + -webkit-box-orient: vertical;
28 +}
29 +
30 +.multi-ellipsis--l3 {
31 + display: -webkit-box;
32 + overflow: hidden;
33 + text-overflow: ellipsis;
34 + -webkit-line-clamp: 3;
35 + -webkit-box-orient: vertical;
36 +}
37 +
38 +.multi-ellipsis--l4 {
39 + display: -webkit-box;
40 + overflow: hidden;
41 + text-overflow: ellipsis;
42 + -webkit-line-clamp: 4;
43 + -webkit-box-orient: vertical;
44 +}
45 +
46 +.multi-ellipsis--l5 {
47 + display: -webkit-box;
48 + overflow: hidden;
49 + text-overflow: ellipsis;
50 + -webkit-line-clamp: 5;
51 + -webkit-box-orient: vertical;
52 +}
53 +
54 +.multi-ellipsis--l6 {
55 + display: -webkit-box;
56 + overflow: hidden;
57 + text-overflow: ellipsis;
58 + -webkit-line-clamp: 6;
59 + -webkit-box-orient: vertical;
60 +}
1 +/* eslint-disable */
2 +/* prettier-ignore */
3 +// @ts-nocheck
4 +// noinspection JSUnusedGlobalSymbols
5 +// Generated by unplugin-auto-import
6 +export {}
7 +declare global {
8 + const EffectScope: typeof import('vue')['EffectScope']
9 + const computed: typeof import('vue')['computed']
10 + const createApp: typeof import('vue')['createApp']
11 + const customRef: typeof import('vue')['customRef']
12 + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
13 + const defineComponent: typeof import('vue')['defineComponent']
14 + const effectScope: typeof import('vue')['effectScope']
15 + const getCurrentInstance: typeof import('vue')['getCurrentInstance']
16 + const getCurrentScope: typeof import('vue')['getCurrentScope']
17 + const h: typeof import('vue')['h']
18 + const inject: typeof import('vue')['inject']
19 + const isProxy: typeof import('vue')['isProxy']
20 + const isReactive: typeof import('vue')['isReactive']
21 + const isReadonly: typeof import('vue')['isReadonly']
22 + const isRef: typeof import('vue')['isRef']
23 + const markRaw: typeof import('vue')['markRaw']
24 + const nextTick: typeof import('vue')['nextTick']
25 + const onActivated: typeof import('vue')['onActivated']
26 + const onBeforeMount: typeof import('vue')['onBeforeMount']
27 + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
28 + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
29 + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
30 + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
31 + const onDeactivated: typeof import('vue')['onDeactivated']
32 + const onErrorCaptured: typeof import('vue')['onErrorCaptured']
33 + const onMounted: typeof import('vue')['onMounted']
34 + const onRenderTracked: typeof import('vue')['onRenderTracked']
35 + const onRenderTriggered: typeof import('vue')['onRenderTriggered']
36 + const onScopeDispose: typeof import('vue')['onScopeDispose']
37 + const onServerPrefetch: typeof import('vue')['onServerPrefetch']
38 + const onUnmounted: typeof import('vue')['onUnmounted']
39 + const onUpdated: typeof import('vue')['onUpdated']
40 + const provide: typeof import('vue')['provide']
41 + const reactive: typeof import('vue')['reactive']
42 + const readonly: typeof import('vue')['readonly']
43 + const ref: typeof import('vue')['ref']
44 + const resolveComponent: typeof import('vue')['resolveComponent']
45 + const shallowReactive: typeof import('vue')['shallowReactive']
46 + const shallowReadonly: typeof import('vue')['shallowReadonly']
47 + const shallowRef: typeof import('vue')['shallowRef']
48 + const toRaw: typeof import('vue')['toRaw']
49 + const toRef: typeof import('vue')['toRef']
50 + const toRefs: typeof import('vue')['toRefs']
51 + const toValue: typeof import('vue')['toValue']
52 + const triggerRef: typeof import('vue')['triggerRef']
53 + const unref: typeof import('vue')['unref']
54 + const useAttrs: typeof import('vue')['useAttrs']
55 + const useCssModule: typeof import('vue')['useCssModule']
56 + const useCssVars: typeof import('vue')['useCssVars']
57 + const useLink: typeof import('vue-router')['useLink']
58 + const useRoute: typeof import('vue-router')['useRoute']
59 + const useRouter: typeof import('vue-router')['useRouter']
60 + const useSlots: typeof import('vue')['useSlots']
61 + const watch: typeof import('vue')['watch']
62 + const watchEffect: typeof import('vue')['watchEffect']
63 + const watchPostEffect: typeof import('vue')['watchPostEffect']
64 + const watchSyncEffect: typeof import('vue')['watchSyncEffect']
65 +}
66 +// for type re-export
67 +declare global {
68 + // @ts-ignore
69 + export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
70 + import('vue')
71 +}
1 +/*
2 + * @Date: 2022-07-26 09:49:54
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-03-25 17:56:01
5 + * @FilePath: /custom_dashboard/src/common/mixin.js
6 + * @Description: 文件描述
7 + */
8 +
9 +export default {
10 + // 初始化设置
11 + init: {
12 + mounted () {
13 + document.title = this.$route.meta.title;
14 + },
15 + methods: {
16 + },
17 + },
18 +};
This diff is collapsed. Click to expand it.
1 +<!--
2 + * @Date: 2024-03-01 09:40:27
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-03-30 06:14:10
5 + * @FilePath: /custom_dashboard/src/components/DynamicChart.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div :ref="chartRef" class="dynamic-chart" :style="{ width: width, height: wrapper_height, marginTop: titleHeight + 'px'}"></div>
10 +</template>
11 +
12 +<script>
13 +import * as echarts from 'echarts/core';
14 +// 引入柱状图图表,图表后缀都为 Chart
15 +import { BarChart, PieChart, LineChart, RadarChart, FunnelChart } from 'echarts/charts';
16 +// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
17 +import {
18 + TitleComponent,
19 + TooltipComponent,
20 + LegendComponent,
21 + GridComponent,
22 + DatasetComponent,
23 + TransformComponent
24 +} from 'echarts/components';
25 +// 标签自动布局、全局过渡动画等特性
26 +import { LabelLayout, UniversalTransition } from 'echarts/features';
27 +// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
28 +import { CanvasRenderer } from 'echarts/renderers';
29 +
30 +// 注册必须的组件
31 +echarts.use([
32 + TitleComponent,
33 + TooltipComponent,
34 + LegendComponent,
35 + GridComponent,
36 + DatasetComponent,
37 + TransformComponent,
38 + BarChart,
39 + PieChart,
40 + LineChart,
41 + RadarChart,
42 + FunnelChart,
43 + LabelLayout,
44 + UniversalTransition,
45 + CanvasRenderer
46 +]);
47 +
48 +export default {
49 + name: 'DynamicChart',
50 + props: ['chartOptions', 'chartData', 'width', 'height', 'titleHeight'],
51 + data() {
52 + return {
53 + chartRef: 'chartContainer',
54 + chartInstance: null,
55 + wrapper_height: '',
56 + };
57 + },
58 + watch: {
59 + height (val) {
60 + if (val) {
61 + this.wrapper_height = val;
62 + }
63 + }
64 + },
65 + mounted() {
66 + this.wrapper_height = this.height;
67 + setTimeout(() => {
68 + this.initChart();
69 + }, 200);
70 + },
71 + beforeDestroy() {
72 + this.destroyChart();
73 + },
74 + methods: {
75 + initChart() {
76 + const chartContainer = this.$refs.chartContainer;
77 + if (chartContainer) {
78 + this.chartInstance = echarts.init(chartContainer);
79 + this.chartInstance.setOption(this.chartOptions);
80 + }
81 + },
82 + destroyChart() {
83 + if (this.chartInstance) {
84 + this.chartInstance.dispose();
85 + this.chartInstance = null;
86 + }
87 + },
88 + updateChart() {
89 + this.chartInstance.setOption(this.chartOptions);
90 + },
91 + }
92 +};
93 +</script>
94 +
95 +<style scoped>
96 +.dynamic-chart {
97 + padding: 10px;
98 +}
99 +</style>
1 +<!--
2 + * @Date: 2024-03-21 09:36:01
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-03-21 14:20:43
5 + * @FilePath: /custom_dashboard/src/components/filterInput.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div :class="['edit-tag-wrapper', hoverInFilter ? 'hover' : '']">
10 + <p style="margin-bottom: 10px">过滤:</p>
11 + <div id="filter" style="flex: 1; height: 100%; display: flex">
12 + <!-- <el-tag
13 + :key="index"
14 + v-for="(item, index) in filter_list"
15 + closable
16 + effect="plain"
17 + type="success"
18 + :disable-transitions="false"
19 + @close="handleFilterClose(item, index)">
20 + {{ item.name }}<span style="font-size: 0.7rem;"> ( 求和 )</span>
21 + </el-tag> -->
22 + <div
23 + :key="index"
24 + v-for="(item, index) in filter_list"
25 + class="filter-wrapper"
26 + >
27 + <VDropdown placement="bottom">
28 + <span class="filter-item">
29 + <i class="el-icon-arrow-down el-icon--right"></i>&nbsp;<span
30 + style="font-size: 0.8rem"
31 + >{{ item.name }}</span
32 + >
33 + </span>
34 +
35 + <template #popper>
36 + <!-- <VMenu v-for="n in 5" :key="n" placement="right-start" instant-move>
37 + <div style="padding: 0.5rem">修改显示名</div>
38 +
39 + <template #popper>
40 + <VMenu v-for="n in 5" :key="n" placement="right-start" instant-move>
41 + <div class="rounded hover:bg-green-100 px-4 py-2">Option {{ n }}</div>
42 + </VMenu>
43 + </template>
44 + </VMenu> -->
45 + <div style="padding: 0.5rem;">
46 + <div class="filter-handle-item">修改筛选条件</div>
47 + <div class="filter-handle-item">删除筛选条件</div>
48 + </div>
49 + </template>
50 + </VDropdown>
51 + </div>
52 + </div>
53 +
54 + <el-dialog
55 + title="设置过滤条件"
56 + :visible.sync="dialogVisible"
57 + width="30%"
58 + :append-to-body="true"
59 + :before-close="handleClose">
60 + <div>
61 + <el-row :gutter="5">
62 + <el-col :span="16">
63 + <el-input v-model="field_input" :disabled="true">
64 + </el-input>
65 + </el-col>
66 + <el-col :span="8">
67 + <el-select v-model="op_value" placeholder="请选择">
68 + <el-option
69 + v-for="item in options"
70 + :key="item.value"
71 + :label="item.label"
72 + :value="item.value">
73 + </el-option>
74 + </el-select>
75 + </el-col>
76 + </el-row>
77 + <el-row style="margin-top: 0.5rem;">
78 + <el-col :span="24">
79 + <el-input placeholder="请输入内容" v-model="filter_input">
80 + </el-input>
81 + </el-col>
82 + </el-row>
83 + </div>
84 + <span slot="footer" class="dialog-footer">
85 + <el-button @click="dialogVisible = false">取 消</el-button>
86 + <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
87 + </span>
88 + </el-dialog>
89 + </div>
90 +</template>
91 +
92 +<script>
93 +import mixin from "common/mixin";
94 +
95 +const TEXT_OPTIONS = [{
96 + value: '1',
97 + label: '等于'
98 +}, {
99 + value: '2',
100 + label: '不等于'
101 +}, {
102 + value: '3',
103 + label: '等于任意一个'
104 +}, {
105 + value: '4',
106 + label: '不等于任意一个'
107 +}, {
108 + value: '5',
109 + label: '包含'
110 +}, {
111 + value: '6',
112 + label: '不包含'
113 +}, {
114 + value: '7',
115 + label: '为空'
116 +}, {
117 + value: '8',
118 + label: '不为空'
119 +}];
120 +
121 +const DATE_OPTIONS = [{
122 + value: '1',
123 + label: '等于'
124 +}, {
125 + value: '2',
126 + label: '不等于'
127 +}, {
128 + value: '3',
129 + label: '大于等于'
130 +}, {
131 + value: '4',
132 + label: '小于等于'
133 +}, {
134 + value: '5',
135 + label: '选择范围'
136 +}, {
137 + value: '6',
138 + label: '动态筛选'
139 +}, {
140 + value: '7',
141 + label: '为空'
142 +}, {
143 + value: '8',
144 + label: '不为空'
145 +}];
146 +
147 +const NUM_OPTIONS = [{
148 + value: '1',
149 + label: '等于'
150 +}, {
151 + value: '2',
152 + label: '不等于'
153 +}, {
154 + value: '3',
155 + label: '大于'
156 +}, {
157 + value: '4',
158 + label: '大于等于'
159 +}, {
160 + value: '5',
161 + label: '小于'
162 +}, {
163 + value: '6',
164 + label: '小于等于'
165 +}, {
166 + value: '7',
167 + label: '选择范围'
168 +}, {
169 + value: '8',
170 + label: '为空'
171 +}, {
172 + value: '9',
173 + label: '不为空'
174 +}];
175 +
176 +export default {
177 + mixins: [mixin.init],
178 + props: {
179 + hover: {
180 + type: Boolean,
181 + default: false,
182 + },
183 + list: {
184 + type: Array,
185 + default: () => {
186 + return [];
187 + },
188 + },
189 + filterItem: {
190 + type: Object,
191 + default: () => {
192 + return {};
193 + }
194 + }
195 + },
196 + watch: {
197 + hover(v) {
198 + this.hoverInFilter = v;
199 + },
200 + list(v) {
201 + this.filter_list = v;
202 + },
203 + filterItem(v) {
204 + if (v) {
205 + this.dialogVisible = true;
206 + }
207 + }
208 + },
209 + data() {
210 + return {
211 + filter_list: [],
212 + hoverInFilter: false,
213 + dialogVisible: false,
214 + options: [],
215 + op_value: '1',
216 + field_input: '测试字段',
217 + filter_input: '',
218 + };
219 + },
220 + mounted() {
221 + this.options = TEXT_OPTIONS;
222 + },
223 + methods: {
224 + handleFilterClose() {
225 + // this.filter_list.splice(index, 1);
226 + },
227 + handleClose(done) {
228 + this.$confirm('确认关闭?')
229 + .then(_ => {
230 + done();
231 + })
232 + .catch(_ => {});
233 + },
234 + },
235 +};
236 +</script>
237 +
238 +<style lang="less" scoped>
239 +.edit-tag-wrapper {
240 + border: 1px dashed #d7d9dc;
241 + border-radius: 3px;
242 + padding: 10px;
243 + padding-bottom: 0;
244 + height: auto;
245 + min-height: 42px;
246 + background: #fff;
247 + display: flex;
248 + align-items: center;
249 + margin-bottom: 10px;
250 + // width: 100%;
251 + &.hover {
252 + border: 1px dashed green;
253 + background: rgb(208 249 208 / 34%);
254 + }
255 +
256 + .filter-wrapper {
257 + margin-right: 10px;
258 + margin-bottom: 10px;
259 + .filter-item {
260 + background-color: #fff;
261 + border-color: #d9ecff;
262 + height: 32px;
263 + padding: 7px 10px 10px 0;
264 + line-height: 1;
265 + color: #409eff;
266 + border-width: 1px;
267 + border-style: solid;
268 + border-radius: 4px;
269 + box-sizing: border-box;
270 + white-space: nowrap;
271 + display: inline-block;
272 + cursor: pointer;
273 + }
274 + }
275 +}
276 +
277 +.filter-handle-item {
278 + padding: 0.5rem 1rem;
279 + &:hover {
280 + background-color: #f5f5f5;
281 + cursor: pointer;
282 + }
283 +}
284 +</style>
1 +<!--
2 + * @Date: 2024-05-17 16:31:55
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-05-17 17:33:08
5 + * @FilePath: /custom_dashboard/src/components/GeoChart.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div :ref="chartRef" id="chart-container" style="width: 100%; height: 800px;"></div>
10 +</template>
11 +
12 +<script>
13 +import mixin from 'common/mixin';
14 +import $ from 'jquery';
15 +import * as echarts from 'echarts/core';
16 +// 引入柱状图图表,图表后缀都为 Chart
17 +import { BarChart, PieChart, LineChart, RadarChart, FunnelChart, LinesChart } from 'echarts/charts';
18 +// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
19 +import {
20 + TitleComponent,
21 + TooltipComponent,
22 + LegendComponent,
23 + GridComponent,
24 + DatasetComponent,
25 + TransformComponent,
26 + GeoComponent
27 +} from 'echarts/components';
28 +// 标签自动布局、全局过渡动画等特性
29 +import { LabelLayout, UniversalTransition } from 'echarts/features';
30 +// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
31 +import { CanvasRenderer, SVGRenderer } from 'echarts/renderers';
32 +
33 +// 注册必须的组件
34 +echarts.use([
35 + TitleComponent,
36 + TooltipComponent,
37 + LegendComponent,
38 + GridComponent,
39 + DatasetComponent,
40 + TransformComponent,
41 + BarChart,
42 + PieChart,
43 + LineChart,
44 + RadarChart,
45 + FunnelChart,
46 + LabelLayout,
47 + UniversalTransition,
48 + CanvasRenderer,
49 + SVGRenderer,
50 + GeoComponent,
51 + LinesChart
52 +]);
53 +
54 +export default {
55 + mixins: [mixin.init],
56 + data () {
57 + return {
58 + chartRef: 'chartContainer',
59 + chartInstance: null,
60 + chartOptions: {
61 + title: {
62 + text: 'Visit Route',
63 + left: 'center',
64 + bottom: 10
65 + },
66 + tooltip: {},
67 + geo: {
68 + map: 'MacOdrum-LV5-floorplan-web',
69 + roam: true,
70 + emphasis: {
71 + itemStyle: {
72 + color: undefined
73 + },
74 + label: {
75 + show: false
76 + }
77 + }
78 + },
79 + series: [
80 + {
81 + name: 'Route',
82 + type: 'lines',
83 + coordinateSystem: 'geo',
84 + geoIndex: 0,
85 + emphasis: {
86 + label: {
87 + show: false
88 + }
89 + },
90 + polyline: true,
91 + lineStyle: {
92 + color: '#c46e54',
93 + width: 5,
94 + opacity: 1,
95 + type: 'dotted'
96 + },
97 + effect: {
98 + show: true,
99 + period: 8,
100 + color: '#a10000',
101 + constantSpeed: 80,
102 + trailLength: 0,
103 + symbolSize: [20, 12],
104 + symbol:
105 + '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'
106 + },
107 + data: [
108 + {
109 + coords: [
110 + [110.6189462165178, 456.64349563895087],
111 + [124.10988522879458, 450.8570048730469],
112 + [123.9272226116071, 389.9520693708147],
113 + [61.58708083147317, 386.87942320312504],
114 + [61.58708083147317, 72.8954315876116],
115 + [258.29514854771196, 72.8954315876116],
116 + [260.75457021484374, 336.8559607533482],
117 + [280.5277985253906, 410.2406672084263],
118 + [275.948185765904, 528.0254369698661],
119 + [111.06907909458701, 552.795792593471],
120 + [118.87138231445309, 701.365737015904],
121 + [221.36468155133926, 758.7870354617745],
122 + [307.86195445452006, 742.164737297712],
123 + [366.8489324762834, 560.9895157073103],
124 + [492.8750778390066, 560.9895157073103],
125 + [492.8750778390066, 827.9639780566406],
126 + [294.9255269587053, 827.9639780566406],
127 + [282.79803391043527, 868.2476088113839]
128 + ]
129 + }
130 + ]
131 + }
132 + ]
133 + }
134 + }
135 + },
136 + mounted () {
137 + setTimeout(() => {
138 + this.initChart();
139 + }, 500);
140 + },
141 + methods: {
142 + initChart() {
143 + var dom = document.getElementById('chart-container');
144 + this.chartInstance = echarts.init(dom, null, {
145 + renderer: 'svg',
146 + useDirtyRect: false
147 + });
148 + $.get('https://cdn.ipadbiz.cn/tmp/MacOdrum-LV5-floorplan-web.svg', (svg) => {
149 + echarts.registerMap('MacOdrum-LV5-floorplan-web', { svg: svg });
150 + this.chartInstance.setOption(this.chartOptions);
151 + this.chartInstance.on('click', { geoIndex: 0, name: 'seminar_room' }, function (params) {
152 + console.log(params);
153 + });
154 + })
155 + },
156 + destroyChart() {
157 + if (this.chartInstance) {
158 + this.chartInstance.dispose();
159 + this.chartInstance = null;
160 + }
161 + },
162 + updateChart() {
163 + this.chartInstance.setOption(this.chartOptions);
164 + },
165 + }
166 +}
167 +</script>
168 +
169 +<style lang="less" scoped>
170 +
171 +</style>
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
1 +/*
2 + * @Date: 2022-07-25 11:01:23
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-07-08 17:48:53
5 + * @FilePath: /my-data-summary/src/main.js
6 + * @Description: 文件描述
7 + */
8 +import { createApp } from 'vue'
9 +import ElementPlus from 'element-plus'
10 +import 'element-plus/dist/index.css'
11 +import App from './App.vue'
12 +import router from './router';
13 +import axios from '@/utils/axios';
14 +
15 +import { createPinia } from 'pinia';
16 +// router.afterEach((to, from, next) => {
17 +// // window.scrollTo(0, 0);
18 +// })
19 +
20 +const pinia = createPinia();
21 +const app = createApp(App);
22 +
23 +app.config.globalProperties.$http = axios; // 关键语句
24 +
25 +app.use(router).use(ElementPlus).use(pinia).mount('#app');
This diff is collapsed. Click to expand it.
1 +/*
2 + * @Date: 2022-07-18 12:57:31
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-07-21 17:03:02
5 + * @FilePath: /front/src/mock/nav.js
6 + * @Description: 文件描述
7 + */
8 +const data = [{
9 + title: '首页',
10 + link: '/',
11 + sub: []
12 +}, {
13 + title: '走进寺院',
14 + link: '/temple',
15 + sub: []
16 +}, {
17 + title: '寺院新闻',
18 + link: '',
19 + sub: [{
20 + id: 'xxx',
21 + title: '公告',
22 + link: '/column'
23 + }, {
24 + title: '招聘',
25 + link: ''
26 + }, {
27 + title: '新闻',
28 + link: ''
29 + }]
30 +}, {
31 + title: '智慧课堂',
32 + link: '',
33 + sub: [{
34 + title: '活动与咨询',
35 + link: ''
36 + }, {
37 + title: '福田功德',
38 + link: ''
39 + }, {
40 + title: '广结善缘',
41 + link: ''
42 + }]
43 +}, {
44 + title: '弘法利生',
45 + link: '',
46 + sub: [{
47 + title: '法务活动',
48 + link: ''
49 + }, {
50 + title: '本源法师开示',
51 + link: ''
52 + }, {
53 + title: '短期出家',
54 + link: ''
55 + }, {
56 + title: '闻思修慧',
57 + link: ''
58 + }, {
59 + title: '素食护生',
60 + link: ''
61 + }, {
62 + title: '妙智学堂',
63 + link: ''
64 + }]
65 +}, {
66 + title: '义工之家',
67 + link: '',
68 + sub: [{
69 + title: '义工之家',
70 + link: ''
71 + }]
72 +}, {
73 + title: '普明慈善基金会',
74 + link: '/foundation',
75 + sub: []
76 +}, {
77 + title: '生命关怀',
78 + link: '',
79 + sub: [{
80 + title: '生命关怀',
81 + link: ''
82 + }]
83 +}]
84 +
85 +export default data
1 +const routes = [{
2 + path: '/image',
3 + redirect: '',
4 + name: 'html转图片',
5 + component: 'html2canvas',
6 + keepAlive: '',
7 + meta: {
8 + title: 'html转图片',
9 + name: ''
10 + },
11 + children: [{
12 + path: 'children',
13 + redirect: '',
14 + name: 'html转图片',
15 + component: 'children-test',
16 + keepAlive: '',
17 + meta: {
18 + title: 'html转图片',
19 + name: ''
20 + }
21 + }]
22 +}]
23 +// const routes = []
24 +
25 +export default routes
1 +/*
2 + * @Date: 2022-07-18 15:05:39
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-07-22 14:34:25
5 + * @FilePath: /front/src/mock/swipe.js
6 + * @Description: 文件描述
7 + */
8 +const data = [{
9 + id: '1',
10 + src: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
11 + title: '文章1',
12 + link: '/detail'
13 +}, {
14 + id: '2',
15 + src: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
16 + title: '文章2',
17 + link: '/detail'
18 +}, {
19 + id: '3',
20 + src: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
21 + title: '文章3',
22 + link: '/detail'
23 +}]
24 +export default data
This diff is collapsed. Click to expand it.
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: 2024-07-08 17:22:58
5 + * @FilePath: /custom_dashboard/src/route.js
6 + * @Description: 文件描述
7 + */
8 +export default [{
9 + path: '/',
10 + component: () => import('@/views/index.vue'),
11 + meta: {
12 + title: '首页',
13 + }
14 +}];
1 +/*
2 + * @Date: 2022-05-26 13:57:28
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-06-29 21:36:59
5 + * @FilePath: /tswj/src/router.js
6 + * @Description: 文件描述
7 + */
8 +import { createRouter, createWebHashHistory } from 'vue-router';
9 +import RootRoute from './route.js';
10 +import asyncRoutesArr from "./mock/routes"
11 +import generateRoutes from './utils/generateRoute'
12 +
13 +// TAG: 路由配置表
14 +/**
15 + * 把项目独有的路由配置到相应的路径,默认路由文件只放公用部分
16 + * 但是 vue 文件内容还是要事先准备好
17 + */
18 +const modules = import.meta.globEager('@/router/routes/modules/**/*.js'); // Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块
19 +const routeModuleList = [];
20 +
21 +Object.keys(modules).forEach((key) => {
22 + const mod = modules[key].default || {};
23 + const modList = Array.isArray(mod) ? [...mod] : [mod];
24 + routeModuleList.push(...modList);
25 +});
26 +
27 +// 创建路由实例并传递 `routes` 配置
28 +const router = createRouter({
29 + history: createWebHashHistory('/index.html'),
30 + routes: [...RootRoute, ...routeModuleList]
31 +});
32 +
33 +// TAG: 动态生成路由
34 +/**
35 + * generateRoute 负责把后台返回数据拼接成项目需要的路由结构,动态添加到路由表里面
36 + */
37 +router.beforeEach((to, from, next) => {
38 + // 使用404为中转页面,避免动态路由没有渲染出来,控制台报警告问题
39 + if (to.path == '/404' && to.redirectedFrom != undefined) {
40 + // 模拟异步操作
41 + setTimeout(() => {
42 + if (!asyncRoutesArr.length) return; // 没有动态路由避免报错
43 + const arr = generateRoutes(asyncRoutesArr); // 在路由守卫处生成,避免有子路由时刷新白屏问题。
44 + arr.forEach(item => {
45 + router.addRoute(item) // 新增路由
46 + })
47 + // 重写被404覆盖路由信息
48 + next({ ...to.redirectedFrom, replace: true });
49 + }, 1000);
50 + } else {
51 + next()
52 + }
53 +})
54 +
55 +router.afterEach(() => {
56 + // console.warn(to);
57 + // console.warn(wx);
58 + // share(to)
59 +})
60 +
61 +export default router;
1 +const index = [{
2 + path: '/auth',
3 + name: '授权跳转页',
4 + component: () => import('@/views/auth.vue'),
5 + meta: {
6 + title: '微信授权'
7 + },
8 + children: []
9 +}]
10 +
11 +export default index;
1 +/*
2 + * @Date: 2022-06-15 17:09:03
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-07-18 10:54:32
5 + * @FilePath: /front/src/router/routes/modules/common/index.js
6 + * @Description: 文件描述
7 + */
8 +const index = [{ // 配置404为动态路由中转页面
9 + path: '/:pathMatch(.*)*',
10 + redirect: '/404'
11 +}, {
12 + path: '/404',
13 + name: '404',
14 + component: () => import('@/views/404.vue'),
15 + meta: {
16 + icon: '',
17 + title: '404',
18 + },
19 + children: [],
20 +}];
21 +
22 +export default index;
1 +/*
2 + * @Date: 2022-04-18 15:59:42
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2023-03-03 10:10:27
5 + * @FilePath: /data-table/src/store/index.js
6 + * @Description: 文件描述
7 + */
8 +import { defineStore } from 'pinia';
9 +// import { testStore } from './test'; // 另一个store
10 +import _ from 'lodash';
11 +import { useRouter } from 'vue-router'
12 +
13 +export const mainStore = defineStore('main', {
14 + state: () => {
15 + return {
16 + msg: 'Hello world',
17 + count: 0,
18 + auth: false,
19 + comment_num: 0,
20 + video_detail: {},
21 + scrollTop: 0,
22 + scrollTopCollection: 0,
23 + scrollTopLike: 0,
24 + scrollTopPerson: 0,
25 + keepPages: ['default'], // 很坑爹,空值全部都缓存
26 + fieldName: '',
27 + formInfo: {}, // 表单字段信息
28 + formSetting: {}, // 表单数据收集设置
29 + successInfo: {}, // 表单提交返回值
30 + };
31 + },
32 + getters: {
33 + getKeepPages () {
34 + return this.keepPages
35 + },
36 + // getTestStoreList () {
37 + // return testStore().list // 返回另一个store的值
38 + // }
39 + },
40 + actions: {
41 + changeState (state) {
42 + this.auth = state;
43 + },
44 + changeCommentNum (num) {
45 + this.comment_num = num;
46 + },
47 + changeVideoDetail (v) {
48 + this.video_detail = v;
49 + },
50 + changeScrollTop (v) {
51 + this.scrollTop = v;
52 + },
53 + changeScrollTopCollection (v) {
54 + this.scrollTopCollection = v;
55 + },
56 + changeScrollTopLike (v) {
57 + this.scrollTopLike = v;
58 + },
59 + changeScrollTopPerson (v) {
60 + this.scrollTopPerson = v;
61 + },
62 + changeKeepPages () { // 清空所有缓存,用一个不存在的值覆盖
63 + this.keepPages = ['default'];
64 + },
65 + keepThisPage () { // 新增缓存页
66 + const $router = useRouter();
67 + const page = $router.currentRoute.value.meta.name;
68 + this.keepPages.push(page);
69 + },
70 + removeThisPage () { // 删除缓存页
71 + const $router = useRouter();
72 + const page = $router.currentRoute.value.meta.name;
73 + _.remove(this.keepPages, item => item === page)
74 + },
75 + changeFieldName (v) {
76 + this.fieldName = v;
77 + },
78 + changeFormInfo (v) {
79 + this.formInfo = v;
80 + },
81 + changeFormSetting (v) {
82 + this.formSetting = v;
83 + },
84 + changeSuccessInfo (v) {
85 + this.successInfo = v;
86 + },
87 + },
88 +});
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
1 +/*
2 + * @Date: 2024-02-06 11:38:13
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-02-06 13:04:25
5 + * @FilePath: /xysBooking/src/utils/versionUpdater.js
6 + * @Description:
7 + */
8 +/* eslint-disable */
9 +/**
10 + * @description: 版本更新检查
11 + * @param {*} time 阈值
12 + * @return {*}
13 + */
14 +export class Updater {
15 + constructor(options = {}) {
16 + this.oldScript = [];
17 + this.newScript = [];
18 + this.dispatch = {};
19 + this.init(); //初始化
20 + this.timing(options.time); //轮询
21 + }
22 +
23 + async init() {
24 + const html = await this.getHtml();
25 + this.oldScript = this.parserScript(html);
26 + }
27 +
28 + async getHtml() {
29 + // TAG: html的位置需要动态修改
30 + const html = await fetch(import.meta.env.VITE_BASE).then((res) => res.text()); //读取index html
31 + return html;
32 + }
33 +
34 + parserScript(html) {
35 + const reg = new RegExp(/<script(?:\s+[^>]*)?>(.*?)<\/script\s*>/gi); //script正则
36 + return html.match(reg); //匹配script标签
37 + }
38 +
39 + //发布订阅通知
40 + on(key, fn) {
41 + (this.dispatch[key] || (this.dispatch[key] = [])).push(fn);
42 + return this;
43 + }
44 +
45 + compare(oldArr, newArr) {
46 + const base = oldArr.length;
47 + // 去重
48 + const arr = Array.from(new Set(oldArr.concat(newArr)));
49 + //如果新旧length 一样无更新
50 + if (arr.length === base) {
51 + this.dispatch['no-update'].forEach((fn) => {
52 + fn();
53 + });
54 + } else {
55 + //否则通知更新
56 + this.dispatch['update'].forEach((fn) => {
57 + fn();
58 + });
59 + }
60 + }
61 +
62 + timing(time = 10000) {
63 + //轮询
64 + setInterval(async () => {
65 + const newHtml = await this.getHtml();
66 + this.newScript = this.parserScript(newHtml);
67 + this.compare(this.oldScript, this.newScript);
68 + }, time);
69 + }
70 +}
1 +<!--
2 + * @Date: 2022-06-29 18:18:02
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-07-08 17:25:42
5 + * @FilePath: /custom_dashboard/src/views/404.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div class="">404</div>
10 +</template>
11 +
12 +<script setup>
13 +import { ref } from 'vue'
14 +import { useRoute, useRouter } from 'vue-router'
15 +
16 +</script>
17 +
18 +<style lang="less" scoped>
19 +
20 +</style>
1 +<!--
2 + * @Date: 2022-08-29 13:55:31
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-12-06 20:56:54
5 + * @FilePath: /data-table/src/views/auth.vue
6 + * @Description: 授权模块
7 +-->
8 +<template>
9 + <div />
10 +</template>
11 +
12 +<script setup>
13 +import { onMounted } from 'vue'
14 +import { useRoute } from 'vue-router'
15 +
16 +const $route = useRoute();
17 +
18 +onMounted(() => {
19 + // php需要先跳转链接获取openid
20 + /**
21 + * encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。
22 + * 该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。
23 + * 其他字符(比如 :;/?:@&=+$,# 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。
24 + */
25 + let raw_url = encodeURIComponent(location.origin + location.pathname + $route.query.href); // 未授权的地址
26 + // TAG: 开发环境测试数据
27 + const short_url = `/srv/?f=custom_form&a=openid&res=${raw_url}&form_code=${$route.query.code}`;
28 + location.href = import.meta.env.DEV
29 + ? `${short_url}&openid=${import.meta.env.VITE_OPENID}`
30 + : `${short_url}`;
31 +})
32 +</script>
1 +<!--
2 + * @Date: 2024-07-08 17:06:30
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-07-08 17:37:15
5 + * @FilePath: /custom_dashboard/src/views/index.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div class="mb-4">
10 + <el-button>Default</el-button>
11 + <el-button type="primary">Primary</el-button>
12 + <el-button type="success">Success</el-button>
13 + <el-button type="info">Info</el-button>
14 + <el-button type="warning">Warning</el-button>
15 + <el-button type="danger">Danger</el-button>
16 + </div>
17 +</template>
18 +
19 +<script setup>
20 +import { ref, onMounted } from 'vue'
21 +import { useRoute, useRouter } from 'vue-router'
22 +
23 +onMounted(() => {
24 + console.warn('onMounted');
25 +})
26 +
27 +</script>
28 +
29 +<style lang="less" scoped>
30 +
31 +</style>
1 +<!--
2 + * @Date: 2024-04-02 17:03:26
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2024-05-17 16:37:21
5 + * @FilePath: /custom_dashboard/src/views/test.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div style="">
10 + <!--<svg width="500" height="500" viewBox="0 0 900 900">
11 + <!~~ 定义裁剪路径 ~~>
12 + <defs>
13 + <clipPath id="clippath">
14 + <!~~ 使用有效的路径来定义裁剪形状 ~~>
15 + <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" />
16 + </clipPath>
17 + </defs>
18 +
19 + <!~~ 应用遮罩和裁剪路径到图像 ~~>
20 + <image width="900" height="900" :href="imageSrc" style="clip-path: url(#clippath); filter: grayscale(100%);" mask="url(#mask)" />
21 + </svg>-->
22 + <!--<div style="width: 100%; height: 100%;" class="boxer" >
23 + <!~~ <div style="width: 100%; height: 100%;" > ~~>
24 + <svg width="100%" height="100%" viewBox="0 0 100 100">
25 + <!~~ 图像 ~~>
26 + <!~~ <image style="width: 100%; height: 100%;" :href="imageSrc" /> ~~>
27 +
28 + <!~~ 第一个格子的遮罩层 ~~>
29 + <polygon points="0,0 20,0 20,20 0,20" fill="black" opacity="0.5" />
30 +
31 + <!~~ 第二个格子的遮罩层 ~~>
32 + <polygon points="10,10 30,10 30,30 10,30 10,20 20,20 20,10 10,10" fill="black" opacity="0.5" />
33 + </svg>
34 + </div>-->
35 +
36 + <!-- <button @click="changeColor">改变颜色</button> -->
37 +
38 + <!-- <div class="container-t"> -->
39 + <!-- <div class="shape shape-t">
40 + 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.
41 + </div> -->
42 + <!-- <div class="shape shape1"></div>
43 + <div class="shape shape2"></div>
44 + <div class="shape shape3"></div>
45 + <div class="shape shape4"></div> -->
46 + <!-- </div> -->
47 + <!-- <div class="container">
48 + <img src="https://cdn.ipadbiz.cn/tmp/fx_park/s1.png" class="img">
49 + </div>
50 + <div class="container">
51 + <img src="https://cdn.ipadbiz.cn/tmp/fx_park/s2.png" class="img">
52 + </div>
53 + <div class="container">
54 + <img src="https://cdn.ipadbiz.cn/tmp/fx_park/s3.png" class="img">
55 + </div>
56 + <div class="container">
57 + <img src="https://cdn.ipadbiz.cn/tmp/fx_park/s4.png" class="img">
58 + </div>
59 + <div class="container">
60 + <img src="https://cdn.ipadbiz.cn/tmp/fx_park/s5.png" class="img">
61 + </div>
62 + <div class="container">
63 + <img src="https://cdn.ipadbiz.cn/tmp/fx_park/s6.png" class="img">
64 + </div> -->
65 + <geo-chart></geo-chart>
66 +
67 + </div>
68 +</template>
69 +
70 +<script>
71 +import mixin from 'common/mixin';
72 +import GeoChart from '@/components/GeoChart.vue';
73 +/*
74 +如果希望 <polygon> 的位置和形状能够相对于图片保持不变,
75 +可以考虑使用 viewBox 和 viewBox 中的坐标系来定义 <polygon> 的顶点坐标。
76 +这样,无论图片大小如何改变,<polygon> 的位置和形状都会相对于图片保持不变。
77 +使用 viewBox 和 viewBox 中的坐标系来定义 <polygon> 的顶点坐标:
78 +*/
79 +
80 +export default {
81 + components: {
82 + GeoChart
83 + },
84 + mixins: [mixin.init],
85 + data () {
86 + return {
87 + imageSrc: 'https://picsum.photos/500/500',
88 + svg_color: 'black',
89 + }
90 + },
91 + mounted () {
92 + },
93 + methods: {
94 + changeColor () {
95 + this.svg_color = this.svg_color === 'black' ? 'white' : 'black';
96 + }
97 + }
98 +}
99 +</script>
100 +
101 +<style lang="less" scoped>
102 +.boxer {
103 + background-image: url('https://picsum.photos/375/729');
104 + background-repeat: no-repeat;
105 + background-size: cover;
106 + background-position: center;
107 +}
108 +
109 +.container-t {
110 + width: 100%;
111 + height: 100vh;
112 + background-image: url('https://picsum.photos/375/729');
113 + background-size: cover;
114 + position: relative;
115 + overflow: hidden; /* 确保超出容器部分被隐藏 */
116 +}
117 +.container {
118 + width: 100%;
119 + height: 100%;
120 + background-size: contain;
121 + position: absolute;
122 + z-index: 1;
123 + top: 0;
124 + left: 0;
125 + background-repeat: no-repeat;
126 +}
127 +.container1 {
128 + width: 100%;
129 + height: 100%;
130 + background-size: contain;
131 + position: absolute;
132 + z-index: 1;
133 + top: 0;
134 + left: 0;
135 + background-repeat: no-repeat;
136 +}
137 +.container2 {
138 + width: 100%;
139 + height: 100%;
140 + background-size: contain;
141 + position: absolute;
142 + z-index: 10;
143 + top: 0;
144 + right: 0;
145 + background-repeat: no-repeat;
146 +}
147 +.container3 {
148 + width: 100%;
149 + height: 100%;
150 + // background-image: url('https://cdn.ipadbiz.cn/tmp/fx_park/s3.png');
151 + background-size: contain;
152 + position: absolute;
153 + // overflow: hidden; /* 确保超出容器部分被隐藏 */
154 + z-index: 10;
155 + top: 0;
156 + right: 0;
157 + background-repeat: no-repeat;
158 +}
159 +.container4 {
160 + width: 100%;
161 + height: 100%;
162 + // background-image: url('https://cdn.ipadbiz.cn/tmp/fx_park/s4.png');
163 + background-size: contain;
164 + position: absolute;
165 + // overflow: hidden; /* 确保超出容器部分被隐藏 */
166 + z-index: 10;
167 + top: 0;
168 + right: 0;
169 + background-repeat: no-repeat;
170 +}
171 +.container5 {
172 + width: 100%;
173 + height: 100%;
174 + // background-image: url('https://cdn.ipadbiz.cn/tmp/fx_park/s5.png');
175 + background-size: contain;
176 + position: absolute;
177 + // overflow: hidden; /* 确保超出容器部分被隐藏 */
178 + z-index: 10;
179 + top: 0;
180 + right: 0;
181 + background-repeat: no-repeat;
182 + background-position: left;
183 +}
184 +.container6 {
185 + width: 100%;
186 + height: 100%;
187 + // background-image: url('https://cdn.ipadbiz.cn/tmp/fx_park/s6.png');
188 + background-size: contain;
189 + position: absolute;
190 + // overflow: hidden; /* 确保超出容器部分被隐藏 */
191 + z-index: 10;
192 + bottom: 0;
193 + right: 0;
194 + background-repeat: no-repeat;
195 + background-position: right;
196 +}
197 +
198 +.img {
199 + position: absolute; top: 0; left: 0; width: 100%; object-fit: cover;
200 +}
201 +
202 +.mask {
203 + mask: linear-gradient(to right, transparent, rgb(0, 0, 0));
204 +}
205 +
206 +.shape {
207 + position: absolute;
208 +}
209 +
210 +.shape-t {
211 + 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%);
212 + width: 100%;
213 + height: 100%;
214 + top: 0;
215 + left: 0;
216 + background-color: rgba(119, 119, 119, 0.5);
217 + border: 1px solid rgba(119, 119, 119, 0.5);
218 +}
219 +
220 +.shape1 {
221 + clip-path: polygon(50% 0%, 74% 31%, 54% 82%, 33% 100%, 0 100%, 0% 60%, 0 0);
222 + width: 100%;
223 + height: 100%;
224 + top: 0;
225 + left: 0;
226 + background-color: rgba(119, 119, 119, 0.5);
227 + border: 1px solid rgba(119, 119, 119, 0.5);
228 +}
229 +
230 +.shape2 {
231 + clip-path: polygon(50% 0%, 74% 31%, 54% 82%, 33% 100%, 100% 100%, 100% 54%, 100% 0);
232 + width: 100%;
233 + height: 100%;
234 + top: 0;
235 + right: 0;
236 + background-color: rgba(20, 120, 119, 0.5);
237 +}
238 +</style>
1 +:root {
2 + font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
3 + font-size: 16px;
4 + line-height: 24px;
5 + font-weight: 400;
6 +
7 + color-scheme: light dark;
8 + color: rgba(255, 255, 255, 0.87);
9 + background-color: #242424;
10 +
11 + font-synthesis: none;
12 + text-rendering: optimizeLegibility;
13 + -webkit-font-smoothing: antialiased;
14 + -moz-osx-font-smoothing: grayscale;
15 + -webkit-text-size-adjust: 100%;
16 +}
17 +
18 +a {
19 + font-weight: 500;
20 + color: #646cff;
21 + text-decoration: inherit;
22 +}
23 +a:hover {
24 + color: #535bf2;
25 +}
26 +
27 +body {
28 + margin: 0;
29 + display: flex;
30 + place-items: center;
31 + min-width: 320px;
32 + min-height: 100vh;
33 +}
34 +
35 +h1 {
36 + font-size: 3.2em;
37 + line-height: 1.1;
38 +}
39 +
40 +#app {
41 + max-width: 1280px;
42 + margin: 0 auto;
43 + padding: 2rem;
44 + text-align: center;
45 +}
46 +
47 +.logo {
48 + height: 6em;
49 + padding: 1.5em;
50 + will-change: filter;
51 +}
52 +.logo:hover {
53 + filter: drop-shadow(0 0 2em #646cffaa);
54 +}
55 +.logo.vanilla:hover {
56 + filter: drop-shadow(0 0 2em #f7df1eaa);
57 +}
58 +
59 +.card {
60 + padding: 2em;
61 +}
62 +
63 +.read-the-docs {
64 + color: #888;
65 +}
66 +
67 +button {
68 + border-radius: 8px;
69 + border: 1px solid transparent;
70 + padding: 0.6em 1.2em;
71 + font-size: 1em;
72 + font-weight: 500;
73 + font-family: inherit;
74 + background-color: #1a1a1a;
75 + cursor: pointer;
76 + transition: border-color 0.25s;
77 +}
78 +button:hover {
79 + border-color: #646cff;
80 +}
81 +button:focus,
82 +button:focus-visible {
83 + outline: 4px auto -webkit-focus-ring-color;
84 +}
85 +
86 +@media (prefers-color-scheme: light) {
87 + :root {
88 + color: #213547;
89 + background-color: #ffffff;
90 + }
91 + a:hover {
92 + color: #747bff;
93 + }
94 + button {
95 + background-color: #f9f9f9;
96 + }
97 +}
1 +{
2 + "compilerOptions": {
3 + /* 基本选项 */
4 + "target": "esnext", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
5 + "module": "CommonJS", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
6 + "lib": [ // 指定要包含在编译中的库文件
7 + "esnext",
8 + "dom",
9 + "dom.iterable",
10 + "scripthost"
11 + ],
12 + "allowJs": true, // 允许编译 javascript 文件
13 + // "checkJs": true, // 报告 javascript 文件中的错误
14 + "jsx": "preserve", // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
15 + // "declaration": true, // 生成相应的 '.d.ts' 文件
16 + // "sourceMap": true, // 生成相应的 '.map' 文件
17 + // "outFile": "./", // 将输出文件合并为一个文件
18 + "outDir": "./", // 指定输出目录
19 + // "rootDir": "./", // 用来控制输出目录结构 --outDir.
20 + "removeComments": true, // 删除编译后的所有的注释
21 + // "noEmit": true, // 不生成输出文件
22 + "importHelpers": true, // tslib 导入辅助工具函数
23 + "isolatedModules": false, // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似)
24 +
25 + /* 严格的类型检查选项 */
26 + "strict": true, // 启用所有严格类型检查选项
27 + // "noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错
28 + // "strictNullChecks": true, // 启用严格的 null 检查
29 + // "noImplicitThis": true, // this 表达式值为 any 类型的时候,生成一个错误
30 + // "alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict'
31 +
32 + /* 额外的检查 */
33 + "noUnusedLocals": true, // 有未使用的变量时,抛出错误
34 + "noUnusedParameters": true, // 有未使用的参数时,抛出错误
35 + "noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时,抛出错误
36 + "noFallthroughCasesInSwitch": true, // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch case 语句贯穿)
37 +
38 + /* 模块解析选项 */
39 + "moduleResolution": "node", // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
40 + "baseUrl": ".", // 用于解析非相对模块名称的基目录
41 + "paths": { // 模块名到基于 baseUrl 的路径映射的列表
42 + "@/*": [
43 + "src/*"
44 + ]
45 + },
46 + // "rootDirs": [], // 根文件夹列表,其组合内容表示项目运行时的结构内容
47 + // "typeRoots": [], // 包含类型声明的文件列表
48 + "types": [ // 需要包含的类型声明文件名列表
49 + // "webpack-env",
50 + "vite/client",
51 + "lodash",
52 + "moment",
53 + "node",
54 + "jquery",
55 + "element-plus/global"
56 + ],
57 + "allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。
58 +
59 + /* Source Map Options */
60 + // "sourceRoot": "./", // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
61 + // "mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置
62 + // "inlineSourceMap": true, // 生成单个 sourcemaps 文件,而不是将 sourcemaps 生成不同的文件
63 + // "inlineSources": true, // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap --sourceMap 属性
64 +
65 + /* 其他选项 */
66 + "experimentalDecorators": true, // 启用装饰器
67 + // "emitDecoratorMetadata": true, // 为装饰器提供元数据的支持
68 +
69 + "esModuleInterop": true, // 可以在es6中导入commonjs
70 + },
71 + "include": [
72 + "src/**/*"
73 + ],
74 + "exclude": [
75 + "node_modules",
76 + "dist"
77 + ],
78 + "vueCompilerOptions": {
79 + "target": 2,
80 + "experimentalSuppressInvalidJsxElementTypeErrors": true
81 + }
82 +}
1 +import vue from '@vitejs/plugin-vue';
2 +import dynamicImport from 'vite-plugin-dynamic-import';
3 +// import legacy from '@vitejs/plugin-legacy';
4 +// import styleImport, { VantResolve } from 'vite-plugin-style-import';
5 +import { defineConfig, loadEnv } from 'vite';
6 +import { createProxy } from './build/proxy'
7 +// import { codeInspectorPlugin } from 'code-inspector-plugin';
8 +import DefineOptions from 'unplugin-vue-define-options/vite';
9 +import AutoImport from 'unplugin-auto-import/vite';
10 +
11 +var path = require('path');
12 +// const { createVuePlugin } = require('vite-plugin-vue2')
13 +
14 +export default ({ command, mode }) => {
15 + const root = process.cwd();
16 +
17 + const viteEnv = loadEnv(mode, root);
18 + // let isProd = (command === 'serve'); // 情景配置是否为开发模式 serve 或 build
19 +
20 + return defineConfig({
21 + // root: '',
22 + // root: './src/packages', // 多页面应用配置入口根目录
23 + base: viteEnv.VITE_BASE, // 开发或生产环境服务的公共基础路径。
24 + // base: isProd ? '/' : '/f/voice/', // 开发或生产环境服务的公共基础路径。
25 + // mode: '', // 在配置中指明将会把 serve 和 build 时的模式 都 覆盖掉。也可以通过命令行 --mode 选项来重写。
26 + // define: '', // 定义全局常量替换方式。其中每项在开发环境下会被定义在全局,而在构建时被静态替换。
27 + plugins: [ // 将要用到的插件数组。Falsy 虚值的插件将被忽略,插件数组将被扁平化(flatten)。查看 插件 API 获取 Vite 插件的更多细节。
28 + // createVuePlugin(),
29 + vue(),
30 + // styleImport({
31 + // resolves: [VantResolve()],
32 + // libs: [
33 + // {
34 + // libraryName: 'vant',
35 + // esModule: true,
36 + // resolveStyle: name => `../es/${name}/style`
37 + // }
38 + // ]
39 + // }), // 按需引入 vant 位置报错问题
40 + dynamicImport(), // 增强 Vite 内置的 dynamic import, 支持在 import() 中使用别名
41 + // legacy({
42 + // targets: ['defaults', 'not IE 11']
43 + // }), // Vite 的默认旧版浏览器支持时提供此插件本机ESM的支持。
44 + // codeInspectorPlugin({
45 + // bundler: 'vite',
46 + // }), // 点击页面上的元素,能够自动打开你的代码编辑器并将光标定位到元素对应的代码位置。
47 + DefineOptions(), // TAG: 插件来对组件名进行注册的, 解决setup没法写name的问题
48 + AutoImport({ // API 自动导入
49 + // 可以自定义文件生成的位置,默认是根目录下,使用ts的建议放src目录下
50 + dts: 'src/auto-imports.d.ts',
51 + imports: ['vue', 'vue-router'],
52 + // 解决eslint报错问题
53 + eslintrc: {
54 + enabled: true
55 + }
56 + }),
57 + ],
58 + publicDir: 'public', // 作为静态资源服务的文件夹。这个目录中的文件会在开发中被服务于 /,在开发模式时,会被拷贝到 outDir 的根目录,并没有转换,永远只是复制到这里。该值可以是文件系统的绝对路径,也可以是相对于项目的根目录路径。
59 + // cacheDir: '', // 存储缓存文件的目录。此目录下会存储预打包的依赖项或 vite 生成的某些缓存文件,使用缓存可以提高性能。如需重新生成缓存文件,你可以使用 --force 命令行选项或手动删除目录。此选项的值可以是文件的绝对路径,也可以是以项目根目录为基准的相对路径。
60 + resolve: {
61 + alias: { // 将会被传递到 @rollup/plugin-alias 作为 entries 的选项。也可以是一个对象,或一个 { find, replacement } 的数组. 当使用文件系统路径的别名时,请始终使用绝对路径。相对路径的别名值会被原封不动地使用,因此无法被正常解析。 更高级的自定义解析方法可以通过 插件 实现。
62 + "@": path.resolve(__dirname, "src"),
63 + "@components": path.resolve(__dirname, "src/components"),
64 + "@utils": path.resolve(__dirname, "src/utils"),
65 + "@images": path.resolve(__dirname, "src/assets/images"),
66 + "@css": path.resolve(__dirname, "src/assets/css"),
67 + "@mock": path.resolve(__dirname, "src/assets/mock"),
68 + "common": path.resolve(__dirname, "src/common"),
69 + "@api": path.resolve(__dirname, "src/api"),
70 + },
71 + // dedupe: [''], // 如果你在你的应用程序中有相同依赖的副本(比如 monorepos),使用这个选项来强制 Vite 总是将列出的依赖关系解析到相同的副本(从项目根目录)。
72 + // conditions: [''], // 在解析包的 情景导出 时允许的附加条件。
73 + // mainFields: [''], // package.json 中,在解析包的入口点时尝试的字段列表。注意,这比从 exports 字段解析的情景导出优先级低:如果一个入口点从 exports 成功解析,主字段将被忽略。
74 + extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], // 导入时想要省略的扩展名列表。注意,不 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会干扰 IDE 和类型支持。
75 + },
76 + css: {
77 + modules: '', // 配置 CSS modules 的行为。选项将被传递给 postcss-modules。
78 + postcss: { // 内联的 PostCSS 配置(格式同 postcss.config.js),或者一个(默认基于项目根目录的)自定义的 PostCSS 配置路径。其路径搜索是通过 postcss-load-config 实现的。 注意,如果提供了该内联配置,Vite 将不会搜索其他 PostCSS 配置源。
79 + plugins: []
80 + },
81 + preprocessorOptions: {
82 + less: {
83 + javascriptEnabled: true,
84 + additionalData: `@import "${path.resolve(__dirname, 'src/assets/styles/base.less')}";`
85 + }
86 + } // 指定传递给 CSS 预处理器的选项。
87 + },
88 + // json: {
89 + // namedExports: true, // 是否支持从 .json 文件中进行按名导入。
90 + // stringify: false, // 若设置为 true,导入的 JSON 会被转换为 export default JSON.parse("...") 会比转译成对象字面量性能更好,尤其是当 JSON 文件较大的时候。 开启此项,则会禁用按名导入。
91 + // },
92 + // esbuild: false, //
93 + // assetsInclude: '', // 指定其他文件类型作为静态资源处理
94 + logLevel: 'info', // 调整控制台输出的级别,默认为 'info'。
95 + // clearScreen: true, // 设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息。命令行模式下请通过 --clearScreen false 设置。
96 + server: {
97 + host: '0.0.0.0',
98 + port: viteEnv.VITE_PORT, // 本地服务端口
99 + // strictPort: true, // 设为true时若端口已被占用则会直接退出, 而不是尝试下一个可用端口
100 + // https: '',
101 + // open: false, // 在服务器启动时自动在浏览器中打开应用程序. 当此值为字符串时, 会被当作URL的路径名.
102 + // proxy: { // 代理
103 + // '/srv/': {
104 + // // target: 'http://voice.onwall.cn',
105 + // target: viteEnv.VITE_PROXY_TARGET,
106 + // changeOrigin: true,
107 + // // rewrite: (path) => path.replace(/^\/api/, '')
108 + // },
109 + // },
110 + proxy: createProxy(viteEnv.VITE_PROXY_PREFIX, viteEnv.VITE_PROXY_TARGET),
111 + // cors: '', // 为开发服务器配置 CORS。默认启用并允许任何源,传递一个 选项对象 来调整行为或设为 false 表示禁用。
112 + // force: '', // 设置为 true 强制使依赖预构建。
113 + // hmr: '', // 禁用或配置 HMR 连接(用于 HMR websocket 必须使用不同的 http 服务器地址的情况)。 设置 server.hmr.overlay 为 false 可以禁用服务器错误遮罩层。
114 + // watch: '', // 传递给 chokidar 的文件系统监视器选项。
115 + },
116 + build: {
117 + // outDir: 'voice', // 指定输出路径(相对于项目根目录).
118 + outDir: viteEnv.VITE_OUTDIR, // 指定输出路径(相对于项目根目录).
119 + assetsDir: 'static',
120 + rollupOptions: {
121 + output: {
122 + chunkFileNames: 'static/js/[name]-[hash].js',
123 + entryFileNames: 'static/js/[name]-[hash].js',
124 + assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
125 + },
126 + input: { // 多页面应用模式, 打包时配置,运行配置要处理root
127 + main: path.resolve(__dirname, 'index.html'),
128 + // mono1: path.resolve(__dirname, 'src/packages/mono1/index.html'),
129 + // mono2: path.resolve(__dirname, 'src/packages/mono2/index.html'),
130 + }
131 + },
132 + },
133 + optimizeDeps: {
134 + // entries: '',
135 + // exclude: [],
136 + include: ['jquery', 'lodash', 'moment', 'axios', 'vue-router'], // 默认情况下,不在 node_modules 中的,链接的包不会被预构建。使用此选项可强制预构建链接的包。
137 + // keepNames: false, // 打包器有时需要重命名符号以避免冲突。 设置此项为 true 可以在函数和类上保留 name 属性。 若想获取更多详情,请参阅 keepNames
138 + }
139 + });
140 +};
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.