hookehuyr

初始化

Showing 98 changed files with 3741 additions and 0 deletions
# port
VITE_PORT = 8208
# 反向代理服务器地址
VITE_PROXY_TARGET = https://oa.onwall.cn
# API请求前缀
VITE_PROXY_PREFIX = /srv/
# 打包输出文件夹名称
VITE_OUTDIR = front
# 是否开启调试
VITE_CONSOLE = 0
# appID相关
VITE_APPID=微信appID
# 资源公共路径
VITE_BASE = /
# 测试open-id
# VITE_OPENID = api-test-openid
# VITE_OPENID = o8BRf1gLDWieH3Y3JvbrI_4IjaME
# VITE_OPENID = oJLZq5t9PIKLW9tm1oSUNAuPwssA
# VITE_OPENID = oJLZq5uT_6GwIh2tQWh1F9IoHZ3U
VITE_OPENID =
# B端账号
VITE_ID = 13761653761
# 验证码
VITE_PIN =
# 反向代理服务器地址
# VITE_PROXY_TARGET = https://oa.anxinchashi.com/
VITE_PROXY_TARGET = http://oa-dev.onwall.cn
# VITE_PROXY_TARGET = https://www.wxgzjs.cn/
# PC端地址
VITE_MOBILE_URL = http://localhost:5173/
# 资源公共路径
VITE_BASE = /f/custom_form/front/
# 测试open-id
VITE_APP_OPENID =
# B端账号
VITE_APP_ID =
# 验证码
VITE_APP_PIN =
# 反向代理服务器地址
VITE_PROXY_TARGET = http://oa.onwall.cn
# PC端地址
# VITE_MOBILE_URL = http://oa.onwall.cn/f/guanzong/web/
# VITE_MOBILE_URL = http://guanzong.onwall.cn/f/guanzong/web/
{
"globals": {
"EffectScope": 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,
"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,
"triggerRef": true,
"unref": true,
"useAttrs": true,
"useCssModule": true,
"useCssVars": true,
"useRoute": true,
"useRouter": true,
"useSlots": true,
"watch": true,
"watchEffect": true,
"watchPostEffect": true,
"watchSyncEffect": true
}
}
\ No newline at end of file
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-27 08:59:09
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-07-08 18:15:20
* @FilePath: /tswj/.eslintrc.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
module.exports = {
// parser: '@typescript-eslint/parser',
parser: 'vue-eslint-parser',
parserOptions: {
parser: 'babel-eslint',
// parser: '@typescript-eslint/parser',
},
extends: [
// add more generic rule sets here, such as:
// 'eslint:recommended',
'plugin:vue/vue3-recommended',
'./.eslintrc-auto-import.json'
// 'plugin:vue/recommended' // Use this if you are using Vue.js 2.x.
],
rules: {
// override/add rules settings here, such as:
// 'vue/no-unused-vars': 'error'
"vue/max-attributes-per-line": ["error", {
"singleline": {
"max": 20
},
"multiline": {
"max": 10
}
}],
"vue/singleline-html-element-content-newline": 0, // 在单行元素的内容之前和之后需要换行符
"vue/first-attribute-linebreak": 0, // 强制第一个属性需要换行
"vue/multi-word-component-names": 0, // 要求组件名称始终为多字
"vue/html-indent": 0, // 执行一致的缩进
"vue/html-closing-bracket-newline": 0, // 在标签的右括号之前要求或禁止换行
},
overrides: [
{
files: ['*.ts'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: ['plugin:@typescript-eslint/recommended'],
},
],
}
node_modules
.DS_Store
dist
dist-ssr
*.local
.history
doc
.vscode
publish.sh
src/views/test/*
src/store/test.js
cypress
src/test/mocha/test.js
cypress.json
src/test
.idea
front
{
"esversion": 11,
"asi": true
}
\ No newline at end of file
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
}
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AppointmentField: typeof import('./src/components/AppointmentField/index.vue')['default']
AreaPickerField: typeof import('./src/components/AreaPickerField/index.vue')['default']
ButtonField: typeof import('./src/components/ButtonField/index.vue')['default']
CalendarField: typeof import('./src/components/CalendarField/index.vue')['default']
CheckboxField: typeof import('./src/components/CheckboxField/index.vue')['default']
ContactField: typeof import('./src/components/ContactField/index.vue')['default']
CustomField: typeof import('./src/components/CustomField/index.vue')['default']
DatePickerField: typeof import('./src/components/DatePickerField/index.vue')['default']
DateTimePickerField: typeof import('./src/components/DateTimePickerField/index.vue')['default']
DesField: typeof import('./src/components/DesField/index.vue')['default']
DividerField: typeof import('./src/components/DividerField/index.vue')['default']
EmailField: typeof import('./src/components/EmailField/index.vue')['default']
FileUploaderField: typeof import('./src/components/FileUploaderField/index.vue')['default']
GenderField: typeof import('./src/components/GenderField/index.vue')['default']
GroupField: typeof import('./src/components/GroupField/index.vue')['default']
IdentityField: typeof import('./src/components/IdentityField/index.vue')['default']
ImageUploaderField: typeof import('./src/components/ImageUploaderField/index.vue')['default']
LoginBox: typeof import('./src/components/LoginBox/index.vue')['default']
MarqueeField: typeof import('./src/components/MarqueeField/index.vue')['default']
MultiRuleField: typeof import('./src/components/MultiRuleField/index.vue')['default']
MyComponent: typeof import('./src/components/AppointmentField/MyComponent.vue')['default']
NameField: typeof import('./src/components/NameField/index.vue')['default']
NoteField: typeof import('./src/components/NoteField/index.vue')['default']
NumberField: typeof import('./src/components/NumberField/index.vue')['default']
OrgPickerField: typeof import('./src/components/OrgPickerField/index.vue')['default']
PhoneField: typeof import('./src/components/PhoneField/index.vue')['default']
PickerField: typeof import('./src/components/PickerField/index.vue')['default']
RadioField: typeof import('./src/components/RadioField/index.vue')['default']
RatePickerField: typeof import('./src/components/RatePickerField/index.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
RuleField: typeof import('./src/components/RuleField/index.vue')['default']
SignField: typeof import('./src/components/SignField/index.vue')['default']
TableField: typeof import('./src/components/TableField/index.vue')['default']
Test: typeof import('./src/components/LoginBox/test.vue')['default']
TextareaField: typeof import('./src/components/TextareaField/index.vue')['default']
TextField: typeof import('./src/components/TextField/index.vue')['default']
TimePickerField: typeof import('./src/components/TimePickerField/index.vue')['default']
VideoField: typeof import('./src/components/VideoField/index.vue')['default']
VolunteerGroupField: typeof import('./src/components/VolunteerGroupField/index.vue')['default']
}
}
<!--
* @Date: 2023-02-13 14:56:34
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-16 16:12:12
* @FilePath: /data-table/index.html
* @Description: 文件描述
-->
<!DOCTYPE html>
<html lang='zh'>
<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, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" />
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<title></title>
<!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.compat.css" /> -->
</head>
<body>
<div id="app"></div>
<script src="https://cdn.ipadbiz.cn/custom_form/tinymce/tinymce.min.js"></script>
<script type="module" src="/src/main.js"></script>
</body>
</html>
This diff could not be displayed because it is too large.
{
"name": "temple_material_request",
"description": "西园寺物资申请系统",
"version": "1.0.0",
"scripts": {
"dev": "vite",
"start": "vite --host 0.0.0.0",
"build": "vite build",
"build-watch": "vite build --watch",
"build-ts": "vue-tsc --noEmit && vite build",
"serve": "vite preview",
"cypress:open": "cypress open",
"tar": "tar -czvpf dist.tar.gz front",
"build_tar": "npm run build && npm run tar",
"scp-dev": "scp dist.tar.gz ipadbiz-inner:/opt/space-dev/f/custom_form",
"dec-dev": "ssh ipadbiz-inner 'cd /opt/space-dev/f/custom_form && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
"scp-oa": "scp dist.tar.gz ipadbiz-inner:/opt/oa/f/custom_form",
"dec-oa": "ssh ipadbiz-inner 'cd /opt/oa/f/custom_form && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
"scp-mituo": "scp dist.tar.gz itomix@ipadbiz.cn:/opt/mituo/f/custom_form",
"dec-mituo": "ssh itomix@ipadbiz.cn 'cd /opt/mituo/f/custom_form && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
"scp-guanzong": "scp dist.tar.gz itomix@ipadbiz.cn:/opt/guanzong/f/custom_form",
"dec-guanzong": "ssh itomix@ipadbiz.cn 'cd /opt/guanzong/f/custom_form && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
"scp-xys": "scp -P 12101 dist.tar.gz zhsy@oa.jcedu.org:/home/www/f/custom_form",
"dec-xys": "ssh -p 12101 zhsy@oa.jcedu.org 'cd /home/www/f/custom_form && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
"scp-zentea": "scp dist.tar.gz zentea@anxinchashi.com:/data/www/zentea/f/custom_form",
"dec-zentea": "ssh zentea@anxinchashi.com 'cd /data/www/zentea/f/custom_form && tar -xzvf dist.tar.gz && rm -rf dist.tar.gz'",
"remove_tar": "rm -rf dist.tar.gz",
"remove_dist": "rm -rf front",
"dev_upload": "npm run build_tar && npm run scp-dev && npm run dec-dev && npm run remove_tar && npm run remove_dist",
"oa_upload": "npm run build_tar && npm run scp-oa && npm run dec-oa && npm run remove_tar",
"mituo_upload": "npm run build_tar && npm run scp-mituo && npm run dec-mituo && npm run remove_tar",
"guanzong_upload": "npm run build_tar && npm run scp-guanzong && npm run dec-guanzong && npm run remove_tar",
"xys_upload": "npm run build_tar && npm run scp-xys && npm run dec-xys && npm run remove_tar",
"zentea_upload": "npm run build_tar && npm run scp-zentea && npm run dec-zentea && npm run remove_tar",
"all_upload": "npm run dev_upload && npm run oa_upload && npm run mituo_upload && npm run guanzong_upload && npm run xys_upload"
},
"dependencies": {
"@dedisuryadi/json-form-data": "^0.1.1",
"@tinymce/tinymce-vue": "4.0.7",
"@vant/area-data": "^1.3.1",
"@vant/touch-emulator": "^1.4.0",
"@vitejs/plugin-legacy": "^1.8.2",
"@vueuse/core": "^8.5.0",
"@wsfe/vue-tree": "^3.2.0",
"animate.css": "^4.1.1",
"browser-md5-file": "^1.1.1",
"dayjs": "^1.11.3",
"default-passive-events": "^2.0.0",
"global": "^4.4.0",
"html2canvas": "^1.4.1",
"idcard": "^4.2.0",
"jquery": "^3.6.0",
"js-cookie": "^3.0.1",
"js-sha1": "^0.6.0",
"lodash": "^4.17.21",
"moment": "^2.29.3",
"mui-player": "^1.7.0",
"sha1": "^1.1.1",
"tinymce": "5.10.9",
"typescript": "^4.7.3",
"uuid": "^8.3.2",
"vant": "^4.9.1",
"vconsole": "^3.14.6",
"vite-plugin-dynamic-import": "^0.9.6",
"vite-plugin-mp": "^1.6.1",
"vue": "^3.2.36",
"weixin-js-sdk": "^1.6.0"
},
"devDependencies": {
"@types/jquery": "^3.5.14",
"@types/lodash": "^4.14.182",
"@types/moment": "^2.13.0",
"@typescript-eslint/parser": "^5.27.1",
"@vitejs/plugin-vue": "^2.3.3",
"@vue/compiler-sfc": "^3.2.36",
"axios": "^0.27.2",
"chai": "^4.3.6",
"cypress": "^9.7.0",
"eslint-plugin-vue": "^9.0.1",
"less": "^4.1.2",
"mocha": "^10.0.0",
"pinia": "^2.0.14",
"postcss-px-to-viewport": "^1.1.1",
"qs": "^6.10.3",
"tslint": "^6.1.3",
"unplugin-auto-import": "^0.8.8",
"unplugin-vue-components": "^0.23.0",
"unplugin-vue-define-options": "^0.6.1",
"vite": "^2.9.9",
"vite-plugin-style-import": "1.4.1",
"vue-esign": "^1.1.4",
"vue-router": "^4.0.15"
}
}
module.exports = {
printWidth: 100, // 代码行的宽度,通用建议每行最大长度建议为100/120,但最好不超过这两个数。
tabWidth: 2, // 指定每次缩进的空格数。
semi: true, // 是否在代码语句结尾添加分号。
vueIndentScriptAndStyle: true,
singleQuote: true, // 是否使用单引号,JSX单独设置。
trailingComma: 'all', // 在多行以逗号分割的句法中尽可能补充尾行逗号。
bracketSpacing: true, // 是否在对象属性与大括号之间填充空格。
bracketSameLine: false, // 开始标签的右尖括号是否跟随在最后一行属性末尾。
proseWrap: 'never',
htmlWhitespaceSensitivity: 'strict',
endOfLine: 'auto', // 设置换行风格,避免不同操作系统造成的大量代码diff。
singleAttributePerLine: false // 在Html,Vue,JSX中是否强制每条属性占用一行。
};
#!/usr/bin/env sh
# -----------------------------------------------
# Filename: publish.sh
# Revision: 1.0
# Date: 2022年5月20日
# Author: Hooke
# Description: **** 根据php项目相应特征书写项目发布流程
# -----------------------------------------------
# 当发生错误时中止脚本
set -e
# 本地Git服务器目录路径
PHP_PATH=/Users/huyirui/program/itomix/git/isp/f/custom_form
# 编译输出文件夹
OUTPUT=front
# 打包
npm run build
# 移除Git服务器目录下项目文件夹
rm -r $PHP_PATH"/${OUTPUT:?}"
# 把本地编译输出文件夹添加到服务器目录
mv "${OUTPUT:?}/" $PHP_PATH
# 提交到Git服务器
cd $PHP_PATH"/${OUTPUT:?}"
git checkout custom_form
git pull
git add -A
git commit -m '自定义表单-前端网页更新'
git push
git checkout develop;
git pull origin develop;
git merge --no-edit custom_form;
git push origin develop;
# 更新SSH服务器上文件
ssh -p 22 itomix@ipadbiz.cn '
cd /opt/space-dev/;
git pull origin develop;
'
git checkout custom_form;
#!/usr/bin/env sh
# -----------------------------------------------
# Filename: publish.sh
# Revision: 1.0
# Date: 2022年5月20日
# Author: Hooke
# Description: **** 根据php项目相应特征书写项目发布流程
# -----------------------------------------------
# 当发生错误时中止脚本
set -e
# 记录当前开发的绝对路径
CURR_PATH=$(pwd)
# 本地Git服务器目录路径
PHP_PATH=/Users/huyirui/program/itomix/git/isp/f/custom_form
# 编译输出文件夹
output=front
# 打包
rm -rf front
npm run build
# 删除 PHP 项目里的编译产物
cd $PHP_PATH
git checkout custom_form
rm -rf $PHP_PATH"/${output:?}"
# 把编译产物复制到 PHP 项目
cd $CURR_PATH
cp -r "${output:?}/" $PHP_PATH"/${output:?}"
# PHP 项目的编译产物提交到 Git 服务器
cd $PHP_PATH
git pull
git add -A
git commit -m '自定义表单-前端网页更新'
git push
# 更新其他分支数据
# git checkout master
# git pull origin master
# git merge --no-edit custom_form
# git push origin master
# git checkout guanzong
# git pull origin guanzong
# git merge --no-edit custom_form
# git push origin guanzong
git checkout mituo
git pull origin mituo
git merge --no-edit custom_form
git push origin mituo
# ssh -p 22 itomix@ipadbiz.cn '
# cd /opt/oa;
# git pull origin master;
# cd /opt/guanzong;
# git pull origin guanzong;
# cd /opt/mituo;
# git pull origin mituo;
# '
ssh -p 22 itomix@ipadbiz.cn '
cd /opt/mituo;
git pull origin mituo;
'
git checkout custom_form;
#!/usr/bin/env sh
# -----------------------------------------------
# Filename: publish.sh
# Revision: 1.0
# Date: 2022年5月20日
# Author: Hooke
# Description: DEV环境已经打包推送后,编译产物存在。
# -----------------------------------------------
# 当发生错误时中止脚本
set -e
# 本地Git服务器目录路径
PHP_PATH=/Users/huyirui/program/itomix/git/isp/f/custom_form
# 更新其他分支数据
cd $PHP_PATH
git checkout master
git pull origin master
git merge --no-edit custom_form
git push origin master
git checkout guanzong
git pull origin guanzong
git merge --no-edit custom_form
git push origin guanzong
git checkout mituo
git pull origin mituo
git merge --no-edit custom_form
git push origin mituo
ssh -p 22 itomix@ipadbiz.cn '
cd /opt/oa;
git pull origin master;
cd /opt/guanzong;
git pull origin guanzong;
cd /opt/mituo;
git pull origin mituo;
'
git checkout custom_form;
export interface commentListType {
id: string;
avatar: string;
name: string;
kg_name: string;
comment_time: string;
note: string;
c_action: string;
c_name: string;
cover: string;
prod_id: string;
perf_id: string;
book_id: string;
perf_name: string;
book_name: string;
localism_type: string;
is_new: number;
}
<!--
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-26 23:52:36
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-23 10:33:45
* @FilePath: /temple_material_request/src/App.vue
* @Description:
-->
<template>
<van-row v-if="is_pc">
<van-col span="22" offset="1">
<router-view></router-view>
</van-col>
</van-row>
<router-view v-else></router-view>
</template>
<script setup>
import { mainStore, useTitle } from "@/utils/generatePackage";
import { computed, watchEffect, onMounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import { Toast } from "vant";
// 会根据配置判断是否显示调试控件
// eslint-disable-next-line no-unused-vars
import vConsole from "@/utils/vconsole";
// 初始化WX环境
import wx from 'weixin-js-sdk'
import { wxJsAPI } from '@/api/wx/config'
import { apiList } from '@/api/wx/jsApiList.js'
import { wxInfo, getUrlParams, stringifyQuery } from "@/utils/tools";
import { styleColor } from "@/constant.js";
import { getFormSettingAPI } from "@/api/form.js";
import { showDialog, showConfirmDialog } from 'vant';
import fp3 from '@/utils/fp3';
import { Updater } from '@/utils/versionUpdater';
// 使用 include + pinia 状态管理动态缓存页面
const store = mainStore();
const keepPages = computed(() => store.getKeepPages);
const $route = useRoute();
// watchEffect(() => useTitle("表单标题"));
// 监听路由变化
// 切换路由页面返回顶部
const $router = useRouter();
// web端判断
const is_pc = computed(() => wxInfo().isPC);
// 微信端判断
const is_wx = computed(() => wxInfo().isWeiXin);
// iframe模式判断
const is_iframe = computed(() => window.self !== window.top);
onMounted(async () => {
// // 跳转未授权页
// if (form_setting.auth_error) { // 权限报错信息存在
// $router.replace({
// path: '/no_auth',
// query: {
// code,
// data_id
// }
// });
// }
// // 没有授权判断
// let open_auth = form_setting.wxzq_enable && !form_setting.x_field_weixin_openid;
// // iframe传值openid
// const iframe_openid = getUrlParams(location.href) ? getUrlParams(location.href).openid : '';
// if (iframe_openid) { // 如果获取到iframe传值openid 不再校验授权
// open_auth = false;
// }
// const no_preview_model = model !== 'preview';
// let record_openid = false; // 是否记录open_id
// 需要网页授权-必须要域名相同,需要上传到线上测试
/**
* wxzq_scope 微信公众号授权模式
* 空字符串=不授权,snsapi_base=静默授权,snsapi_userinfo=显式授权
*/
// 非测试环境,没有openid信息,需要授权
// if (!import.meta.env.DEV && open_auth && form_setting.wxzq_scope && record_openid) {
// // 预览模式不开启
// if (no_preview_model) {
// $router.replace({
// path: '/auth',
// query: {
// href: location.hash,
// code
// }
// });
// }
// } else {
// // 启用微信增强,非预览模式
// if (form_setting.wxzq_enable && no_preview_model) {
// const wxJs = await wxJsAPI({ form_code: code, url: raw_url });
// wxJs.data.jsApiList = apiList;
// wx.config(wxJs.data);
// wx.ready(() => {
// wx.showAllNonBaseMenuItem();
// });
// wx.error((err) => {
// console.warn(err);
// });
// }
// }
// TAG:检查是否更新
if (import.meta.env.PROD) {
const upDater = new Updater({
time: 30000
})
upDater.on('no-update', () => {
// console.log('还没更新')
})
upDater.on('update', () => {
showConfirmDialog({
title: '温馨提示',
message: '检测到新版本,是否刷新页面!',
confirmButtonColor: styleColor.baseColor
}).then(() => {
window.location.reload();
});
})
}
});
</script>
<style lang="less">
@prefix: ~"@{namespace}-x";
html,
body {
width: 100%;
// height: 100%;
color: @base-font-color;
// background-color: #f7f8fa;
// background-color: #fff9ef;
padding: 0;
margin: 0;
}
body {
position: relative;
display: flex;
justify-content: center;
p {
margin: 0;
padding: 0;
}
}
#app {
min-height: calc(100vh);
max-width: 800px;
position: relative;
}
.@{prefix} {
color: red;
}
.global-center {
position: relative;
top: 50%;
transform: translateY(-50%);
}
.zIndex {
z-index: 4500 !important;
}
</style>
/*
* @Date: 2022-06-17 14:54:29
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-12-01 16:26:27
* @FilePath: /data-table/src/api/common.js
* @Description: 通用接口
*/
import { fn, fetch, uploadFn } from '@/api/fn';
const Api = {
SMS: '/srv/?a=sms',
TOKEN: '/srv/?a=upload',
SAVE_FILE: '/srv/?a=upload&t=save_file',
}
/**
* @description: 发送验证码
* @param {*} phone 手机号码
* @returns
*/
export const smsAPI = (params) => fn(fetch.post(Api.SMS, params));
/**
* @description: 获取七牛token
* @returns
*/
export const qiniuTokenAPI = (params) => fn(fetch.stringifyPost(Api.TOKEN, params));
/**
* @description: 上传七牛
* @param {*}
* @returns
*/
export const qiniuUploadAPI = (url, data, config) => uploadFn(fetch.basePost(url, data, config));
/**
* @description: 保存图片
* @param {*} format
* @param {*} hash
* @param {*} height
* @param {*} width
* @param {*} filekey
* @returns
*/
export const saveFileAPI = (params) => fn(fetch.stringifyPost(Api.SAVE_FILE, params));
/*
* @Date: 2022-06-17 14:54:29
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-06-05 10:12:06
* @FilePath: /data-table/src/api/component.js
* @Description: 组件接口
*/
import { fn, fetch } from '@/api/fn';
const Api = {
QUERY_COMPONENT: '/srv/?a=query_component',
FLOW_DEPT_LIST: '/srv/?a=flow_setting&t=flow_dept_list',
FLOW_ROLE_LIST: '/srv/?a=flow_setting&t=flow_role_list',
SEARCH_USER_DEPT_ROLE: '/srv/?a=flow_setting&t=search_user_dept_role',
}
/**
* @description: 查询组件
* @param: group_code 分组标识
* @param: component_code 组件标识
* @param: name 组件名称;条件:模糊查询;
*/
export const getComponentAPI = (params) => fn(fetch.get(Api.QUERY_COMPONENT, params));
/**
* @description: 查询部门列表
* @param: form_code 表单code
*/
export const getFlowDeptListAPI = (params) => fn(fetch.get(Api.FLOW_DEPT_LIST, params));
/**
* @description: 查询角色列表
* @param: form_code 表单code
*/
export const getFlowRoleListAPI = (params) => fn(fetch.get(Api.FLOW_ROLE_LIST, params));
/**
* @description: 查询用户部门角色
* @param: form_code 表单code
* @param: word 搜索内容
*/
export const searchUserDeptRoleAPI = (params) => fn(fetch.get(Api.SEARCH_USER_DEPT_ROLE, params));
/*
* @Date: 2022-06-17 14:54:29
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-04 17:05:30
* @FilePath: /data-table/src/api/data.js
* @Description: 表单数据接口
*/
import { fn, fetch } from '@/api/fn';
const Api = {
ADD_FORM_DATA: '/srv/?a=add_formdata',
QUERY_FORM_DATA: '/srv/?a=query_formdata',
MODI_FORM_DATA: '/srv/?a=modi_formdata',
FLOW_FORM_DATA: '/srv/?a=flow_formdata',
}
/**
* @description: 添加表单数据
* @param: form_code 表单唯一标识
* @param: data 待添加的数据,json对象结构;键值对记录变更的字段和值;
*/
export const addFormDataAPI = (params) => fn(fetch.post(Api.ADD_FORM_DATA, params));
/**
* @description: 查询表单数据
* @param: form_code 表单唯一标识
* @param: id 数据ID
*/
export const queryFormDataAPI = (params) => fn(fetch.get(Api.QUERY_FORM_DATA, params));
/**
* @description: 修改表单数据
* @param: form_code 表单唯一标识
* @param: id 数据ID
* @param: data 待添加的数据,json对象结构;键值对记录变更的字段和值;
*/
export const modiFormDataAPI = (params) => fn(fetch.post(Api.MODI_FORM_DATA, params));
/**
* @description: 流程表单数据
* @param: form_code 表单唯一标识
* @param: data_id 数据ID
* @param: data 待添加的数据,json对象结构;键值对记录变更的字段和值;
* @param: flow_node_code 流程节点
* @param: flow_node_action_id 用户点击的流程节点按钮ID
* @param: flow_content 流程审批的文本意见
*/
export const flowFormDataAPI = (params) => fn(fetch.post(Api.FLOW_FORM_DATA, params));
/*
* @Date: 2022-05-18 22:56:08
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-02-10 15:13:01
* @FilePath: /data-table/src/api/fn.js
* @Description: 文件描述
*/
import axios from '@/utils/axios';
import qs from 'Qs'
import { showSuccessToast, showFailToast } from 'vant';
/**
* 网络请求功能函数
* @param {*} api 请求axios接口
* @returns 请求成功后,获取数据
*/
export const fn = (api) => {
return api
.then(res => {
if (res.data.code === 1) {
return res.data || true;
} else {
// tslint:disable-next-line: no-console
// if (!res.data.show) return false;
showFailToast(res.data.msg);
return false;
}
})
.catch(err => {
// tslint:disable-next-line: no-console
console.error(err);
return false;
})
.finally(() => { // 最终执行
})
}
/**
* 七牛返回格式
* @param {*} api
* @returns
*/
export const uploadFn = (api) => {
return api
.then(res => {
if (res.status === 200) {
return res.data || true;
} else {
// tslint:disable-next-line: no-console
console.warn(res);
if (!res.data.show) return false;
Toast({
icon: 'close',
message: res.data.msg,
});
return false;
}
})
.catch(err => {
// tslint:disable-next-line: no-console
console.error(err);
return false;
})
}
/**
* 统一 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: 2023-02-07 13:23:19
* @FilePath: /data-table/src/api/form.js
* @Description: 表单接口
*/
import { fn, fetch } from '@/api/fn';
const Api = {
FORM_ADD: '/srv/?a=add_form',
FORM_QUERY: '/srv/?a=query_form_all_field',
ADD_FORM_FIELD: '/srv/?a=add_form_field',
ADD_FORM_SETTING: '/srv/?a=add_form_setting',
QUERY_FORM_SETTING: '/srv/?a=query_form_setting',
VERIFY_PASSWORD: '/srv/?a=verify_password',
};
/**
* @description: 新增表单
* @param: client_id 主体客户id
* @param: name 表单名称
* @param: note 表单描述
*/
export const addFormAPI = (params) => fn(fetch.post(Api.FORM_ADD, params));
/**
* @description: 查询表单
* @param: client_id 主体客户id
* @param: form_code 表单唯一标识
* @param: name 表单名称,模糊查询
*/
export const queryFormAPI = (params) => fn(fetch.get(Api.FORM_QUERY, params));
/**
* @description: 添加表单字段
* @param: form_code 表单唯一标识
* @param: component_code 组件标识
*/
export const addFormFieldAPI = (params) => fn(fetch.post(Api.ADD_FORM_FIELD, params));
/**
* @description: 添加或修改表单字段属性设置
* @param: form_code 表单唯一标识
* @param: field_name 表单字段名。如果设置表单级(非字段级)的属性,可为空。
* @param: component_code 组件标识
* @param: property_code 属性标识
* @param: setting_value 待设置的属性值。json数组,内部必须双引号。如果属性值是单值,数组只有一个元素。
*/
export const addFormSettingAPI = (params) => fn(fetch.post(Api.ADD_FORM_SETTING, params));
/**
* @description: 查询表单的设置类组件的属性值
* @param: form_code 表单唯一标识
* @returns: enable 开启/停止表单 0=停止表单,1=开启表单
* @returns: is_time_range 是否设定开启/停止时间 0=不设定,1=设定
* @returns: is_count_down 是否显示停止倒计时 0=不显示,1-显示
* @returns: begin_time 开启时间
* @returns: end_time 停止时间
*/
export const getFormSettingAPI = (params) => fn(fetch.get(Api.QUERY_FORM_SETTING, params));
/**
* @description: 验证便当密码
* @param: form_code 表单唯一标识
* @param: mmtx_password 用户输入的密码
* @returns:
*/
export const postVerifyPasswordAPI = (params) => fn(fetch.post(Api.VERIFY_PASSWORD, params));
/*
* @Date: 2022-06-17 14:54:29
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-11-17 13:46:01
* @FilePath: /data-table/src/api/index.js
* @Description: 首页接口
*/
import { fn, fetch } from '@/api/fn';
const Api = {
INDEX: '/srv/?a=home_page',
}
/**
* @description: 首页接口
* @returns HOMEBANNER 轮播区
* @returns HOMEZIXUN 观宗资讯
* @returns HOMEVIDEO 视频展示
* @returns HOMEKAISHI 本源法师开示
* @returns spec_list 专题报告
*/
export const indexAPI = (params) => fn(fetch.get(Api.INDEX, params));
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-06-09 13:32:44
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-02-23 18:42:57
* @FilePath: /data-table/src/api/wx/config.js
* @Description:
*/
import { fn, fetch } from '@/api/fn';
const Api = {
WX_JSAPI: '/srv/?a=wx_share',
}
/**
* @description 获取微信CONFIG配置文件
* @param {*} url
* @returns {*} cfg
*/
export const wxJsAPI = (params) => fn(fetch.get(Api.WX_JSAPI, params));
/*
* @Date: 2022-06-13 14:18:57
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-13 14:27:21
* @FilePath: /tswj/src/api/wx/jsApiList.js
* @Description: 文件描述
*/
export const apiList = [
// "updateAppMessageShareData",
// "updateTimelineShareData",
"onMenuShareTimeline",
"onMenuShareAppMessage",
"onMenuShareQQ",
"onMenuShareWeibo",
"onMenuShareQZone",
"startRecord",
"stopRecord",
"onVoiceRecordEnd",
"playVoice",
"pauseVoice",
"stopVoice",
"onVoicePlayEnd",
"uploadVoice",
"downloadVoice",
"chooseImage",
"previewImage",
"uploadImage",
"downloadImage",
"translateVoice",
"getNetworkType",
"openLocation",
"getLocation",
"hideOptionMenu",
"showOptionMenu",
"hideMenuItems",
"showMenuItems",
"hideAllNonBaseMenuItem",
"showAllNonBaseMenuItem",
"closeWindow",
"scanQRCode",
"chooseWXPay",
"openProductSpecificView",
"addCard",
"chooseCard",
"openCard"
]
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-06-09 13:32:44
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-09 13:42:06
* @FilePath: /tswj/src/api/wx/config.js
* @Description:
*/
import { fn, fetch } from '@/api/fn';
const Api = {
WX_PAY: 'c/bill_paymentForBill.do',
}
/**
* @description 微信支付接口
* @param {*}
* @returns {*}
*/
export const wxPayAPI = (params) => fn(fetch.get(Api.WX_PAY, params));
.modify-top {
z-index: 36;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 10px;
background-image: url('http://gyzs.onwall.cn/top-xian%402x.png');
background-size: contain;
}
.content-bg {
/**
* background-color and background-image 共存,不能使用渐变色
* 图片铺平当时精度提高看看效果
* 直接用渐变色
* 不使用渐变色背景
*/
height: 100%;
min-height: 100vh;
// background-image: url('@images/bg-yellow-duan@2x.png');
background-image: url('http://gyzs.onwall.cn/bg-yellow-duan%402x.png');
// background-size: cover;
// background: linear-gradient(360deg, #FDD347 0%, #FFED6D 100%) ;
}
@namespace: 'wxggzs';
/* ============ 颜色 ============ */
// 主色调
@base-color: #8F652E;
// 文字颜色
@base-font-color: #333333;
@sub-font-color: #999999;
// 定义一个映射
#colors() {
base-color: @base-color;
base-font-color: @base-font-color;
}
// 混合
.width100 {
width: 100%;
}
.van-multi-ellipsis--l4 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
}
.van-multi-ellipsis--l5 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
}
.van-multi-ellipsis--l6 {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 6;
-webkit-box-orient: vertical;
}
// 自定义图片显示
:deep(.van-image.custom-image) {
img {
border-radius: 5px;
}
}
.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;
}
// 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 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 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 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']
}
/**
* 判断多行省略文本
* @param {*} id 目标dom标签
* @returns
*/
const hasEllipsis = (id) => {
let oDiv = document.getElementById(id);
let flag = false
if (oDiv.scrollHeight > oDiv.clientHeight) {
flag = true
}
return flag
}
export default {
hasEllipsis
}
\ No newline at end of file
import { ref } from 'vue'
import { useBrowserLocation, useEventListener, useTitle, useUrlSearchParams, useWindowScroll, logicAnd } from '@vueuse/core'
export const fn = () => {
// const location = useBrowserLocation()
// console.warn(location.value);
// useEventListener(window, 'scroll', (evt) => {
// const { x, y } = useWindowScroll()
// // console.warn(x.value);
// console.warn(y.value);
// })
// useTitle('New Title')
const a = ref(true)
const b = ref(true)
const flag = a.value && b.value
console.warn(flag);
}
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-17 12:13:13
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-07-19 10:33:36
* @FilePath: /front/src/composables/index.js
* @Description:
*/
import { onMounted, onUnmounted } from 'vue'
/**
* 添加和清除 DOM 事件监听器
* @param {*} target
* @param {*} event
* @param {*} callback
*/
export function useEventListener(target, event, callback) {
onMounted(() => target?.addEventListener(event, callback))
onUnmounted(() => target?.removeEventListener(event, callback))
}
/*
* @Date: 2022-06-13 17:42:32
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-03-03 17:51:55
* @FilePath: /data-table/src/composables/useShare.js
* @Description: 文件描述
*/
import wx from 'weixin-js-sdk';
// import { Toast } from 'vant';
/**
* @description: 微信分享功能
* @param {*} title 标题
* @param {*} desc 描述
* @param {*} imgUrl 图标
* @return {*}
*/
export const sharePage = ({title = '自定义表单', desc = '数据收集', imgUrl = ''}) => {
const shareData = {
title, // 分享标题
desc, // 分享描述
link: location.origin + location.pathname + location.hash, // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致
imgUrl, // 分享图标
success: function () {
console.warn('设置成功');
}
}
// 分享好友(微信好友或qq好友)
// wx.updateAppMessageShareData(shareData);
wx.onMenuShareAppMessage(shareData);
// 分享到朋友圈或qq空间
// wx.updateTimelineShareData(shareData);
wx.onMenuShareTimeline(shareData);
// 分享到腾讯微博
wx.onMenuShareWeibo(shareData);
// // 获取“分享给朋友”按钮点击状态及自定义分享内容接口(即将废弃)
// wx.onMenuShareAppMessage(shareData);
// // 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口(即将废弃)
// wx.onMenuShareTimeline(shareData);
// // 获取“分享到QQ”按钮点击状态及自定义分享内容接口(即将废弃)
// wx.onMenuShareQQ(shareData);
}
/*
* @Date: 2022-07-18 10:22:22
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-08-05 17:17:15
* @FilePath: /front/src/constant.js
* @Description: 文件描述
*/
// 颜色变量
export const styleColor = {
baseColor: '#C2915F',
backgroundColor: '#FFF9EF',
}
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-14 23:28:39
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-07 22:49:56
* @FilePath: /tswj/src/env.d.ts
* @Description:
*/
interface ImportMetaEnv extends Readonly<Record<string, string>> {
readonly VITE_OPENID: string;
readonly VITE_ID: string;
readonly VITE_PIN: string;
readonly VITE_APPID: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
/**
* 依赖注入命名集合
*/
export const myInjectionKey = Symbol()
export const fooInjectionKey = Symbol()
import _ from 'lodash'
import TableField from '@/components/TableField/index.vue'
import TextField from '@/components/TextField/index.vue'
import TextareaField from '@/components/TextareaField/index.vue'
import RadioField from '@/components/RadioField/index.vue'
import CheckboxField from '@/components/CheckboxField/index.vue'
import PickerField from '@/components/PickerField/index.vue'
import AreaPickerField from '@/components/AreaPickerField/index.vue'
import DatePickerField from '@/components/DatePickerField/index.vue'
import TimePickerField from '@/components/TimePickerField/index.vue'
import DateTimePickerField from '@/components/DateTimePickerField/index.vue'
import ImageUploaderField from '@/components/ImageUploaderField/index.vue'
import FileUploaderField from '@/components/FileUploaderField/index.vue'
import PhoneField from '@/components/PhoneField/index.vue'
import EmailField from '@/components/EmailField/index.vue'
import SignField from '@/components/SignField/index.vue'
import RatePickerField from '@/components/RatePickerField/index.vue'
import CalendarField from '@/components/CalendarField/index.vue'
import IdentityField from '@/components/IdentityField/index.vue'
import NumberField from '@/components/NumberField/index.vue'
import DesField from '@/components/DesField/index.vue'
import DividerField from '@/components/DividerField/index.vue'
import VideoField from '@/components/VideoField/index.vue'
import MarqueeField from '@/components/MarqueeField/index.vue'
import ContactField from '@/components/ContactField/index.vue'
import RuleField from '@/components/RuleField/index.vue'
import MultiRuleField from '@/components/MultiRuleField/index.vue'
import ButtonField from '@/components/ButtonField/index.vue'
import NoteField from '@/components/NoteField/index.vue';
import NameField from '@/components/NameField/index.vue';
import GenderField from '@/components/GenderField/index.vue';
import AppointmentField from '@/components/AppointmentField/index.vue';
import CustomField from '@/components/CustomField/index.vue';
import GroupField from '@/components/GroupField/index.vue';
import OrgPickerField from '@/components/OrgPickerField/index.vue';
import VolunteerGroupField from '@/components/VolunteerGroupField/index.vue';
/**
* 生成自定义组件类型
* @param {*} data
* @type input 单行文本 TextField
* @type textarea 多行文本 TextareaField
* @type radio 单项选择 RadioField
* @type checkbox 多项选择 CheckboxField
* @type select 单列选择器 PickerField
* @type area_picker 地址选择器 AreaPickerField
* @type date_picker 日期选择器 DatePickerField
* @type time_picker 时间选择器 TimePickerField
* @type datetime_picker 日期时间选择器 DateTimePickerField
* @type image_uploader 图片上传 ImageUploaderField
* @type phone 手机输入框 PhoneField
* @type email 邮箱输入框 EmailField
* @type sign 电子签名输入框 SignField
* @type rate_picker 评分选择器 RatePickerField
* @type calendar 日历选择器 CalendarField
* @type id_code 身份证输入框 IdentityField
* @type desc 文字描述 DesField
* @type divider 分割线 DividerField
* @type video 视频控件 VideoField
* @type marquee 跑马灯控件 MarqueeField
* @type rule 活动规则控件 RuleField
* @type multi_rule 活动规则控件 MultiRuleField
* @type note 富文本控件 NoteField
* @type name 姓名控件 NameField
* @type gender 性别控件 GenderField
* @type appointment 预约控件 AppointmentField
* @type group 组集合输入控件 GroupField
* @type org_picker 树形选择控件 OrgPickerField
* @type volunteer_group 义工组别选择控件 VolunteerGroupField
*/
export function createComponentType(data) {
// 判断类型和使用组件
_.each(data, (item, index) => {
// 必填项规则添加
if (item.component_props.required) {
item.rules = [{ required: true, message: item.placeholder ? item.placeholder : '必填项不能为空' }]
}
if (item.component_props.tag === 'input') {
item.type = 'text';
item.name = item.key;
item.component = TextField;
}
if (item.component_props.tag === 'textarea') {
item.type = 'textarea';
item.name = item.key;
// item.rows = 10;
item.autosize = true;
item.component = TextareaField;
}
if (item.component_props.tag === 'number') {
item.name = item.key;
item.component = NumberField;
}
if (item.component_props.tag === 'radio') {
item.component = RadioField;
}
if (item.component_props.tag === 'checkbox') {
item.component = CheckboxField;
}
if (item.component_props.tag === 'select') {
item.component = PickerField;
}
if (item.component_props.tag === 'address') {
item.component = AreaPickerField;
}
if (item.component_props.tag === 'date') {
item.component = DatePickerField;
}
if (item.component_props.tag === 'time') {
item.component = TimePickerField;
}
if (item.component_props.tag === 'datetime') {
item.component = DateTimePickerField;
}
if (item.component_props.tag === 'image_uploader') {
item.component = ImageUploaderField;
}
if (item.component_props.tag === 'file_uploader') {
item.component = FileUploaderField;
}
if (item.component_props.tag === 'phone') {
item.name = item.key;
item.component = PhoneField;
}
if (item.component_props.tag === 'email') {
item.name = item.key;
item.component = EmailField;
}
if (item.component_props.tag === 'sign') {
item.name = item.key;
item.component = SignField;
}
if (item.component_props.tag === 'rate') {
item.name = item.key;
item.component = RatePickerField;
}
if (item.component_props.tag === 'calendar') {
item.name = item.key;
item.component = CalendarField;
}
if (item.component_props.tag === 'id_card') {
item.name = item.key;
item.component = IdentityField;
}
if (item.component_props.tag === 'desc') {
item.name = item.key;
item.component = DesField;
}
if (item.component_props.tag === 'divider') {
item.name = item.key;
item.component = DividerField;
}
if (item.component_props.tag === 'video') {
item.name = item.key;
item.component = VideoField;
}
if (item.component_props.tag === 'marquee') {
item.name = item.key;
item.component = MarqueeField;
}
if (item.component_props.tag === 'contact') {
item.name = item.key;
item.component = ContactField;
}
if (item.component_props.tag === 'rule') {
item.name = item.key;
item.component = RuleField;
}
if (item.component_props.tag === 'button') {
item.name = item.key;
item.component = ButtonField;
}
if (item.component_props.tag === 'multi_rule') {
item.name = item.key;
item.value = [];
item.component = MultiRuleField;
}
if (item.component_props.tag === 'note') {
item.name = item.key;
item.component = NoteField;
}
if (item.component_props.tag === 'name') {
item.name = item.key;
item.component = NameField;
}
if (item.component_props.tag === 'gender') {
item.name = item.key;
item.component = GenderField;
}
if (item.component_props.tag === 'appointment') {
item.name = item.key;
item.component = AppointmentField;
}
if (item.component_props.tag === 'custom') {
item.name = item.key;
item.component = CustomField;
}
if (item.component_props.tag === 'group') {
item.name = item.key;
item.component = GroupField;
}
if (item.component_props.tag === 'org_picker') {
item.name = item.key;
item.component = OrgPickerField;
}
if (item.component_props.tag === 'volunteer_group') {
item.component = VolunteerGroupField;
}
})
}
import { provide, inject } from "vue";
// const key = Symbol();
/**
* 创建全局变量
* @param {*} context
* @param {*} key
*/
export function createContext(context, key) {
provide(key, context)
}
/**
* 使用全局变量
* @param {*} key
* @returns
*/
export function useContext(key) {
return inject(key)
}
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-28 22:31:25
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-05-30 10:18:09
* @FilePath: /tswj/src/hooks/useDebounce.js
* @Description:
*/
import _ from 'lodash';
/**
* 封装lodash防抖
* @param {*} fn 执行函数
* @param {*} timestamp 执行间隔
* @param {*} options 函数配置 - 在延迟开始前调用,在延迟结束后不调用
* @returns 返回新的 debounced(防抖动)函数。
*/
export const useDebounce = (fn, timestamp = 500, options = { leading: true, trailing: false }) => {
return _.debounce(fn, timestamp, options);
}
/**
* @description 封装简化滚动查询列表执行流程
* @param {*} data 接口返回列表数据
* @param {*} list 自定义列表
* @param {*} offset
* @param {*} loading
* @param {*} finished
* @param {*} finishedTextStatus
* @param {*} emptyStatus
*/
import _ from 'lodash'
export const flowFn = (data, list, offset, loading, finished, finishedTextStatus, emptyStatus) => {
list.value = _.concat(list.value, data);
list.value = _.uniqBy(list.value, 'id');
offset.value = list.value.length;
loading.value = false;
// 数据全部加载完成
if (!data.length) {
// 加载状态结束
finished.value = true;
}
// 空数据提示
if (!list.value.length) {
finishedTextStatus.value = false;
}
emptyStatus.value = Object.is(list.value.length, 0);
}
/*
* @Date: 2022-07-21 13:28:05
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-08-22 09:51:52
* @FilePath: /front/src/hooks/useGo.js
* @Description: 文件描述
*/
import { useRouter } from 'vue-router';
import { getArticleAPI } from '@/api'
import { Cookies } from '@/utils/generatePackage'
import { parseQueryString } from '@/utils/tools'
/**
* 封装路由跳转方便行内调用
* @returns
*/
export function useGo () {
let router = useRouter()
function go (path, query) {
router.push({
path: path,
query: query
})
}
return go
}
/**
* 封装跳转文章详情页
* @param id 文章ID
* @param cid 栏目ID
* @param column 栏目名称
* @param section 二级栏目名称
* @param name 子栏目名称
* @returns
*/
export function useGoTo () {
let router = useRouter()
// function detail({ id, cid, column, section, name, post_link }) {
function detail(item) {
// 保存点击位置
// Cookies.set('scrollTop', getScrollTop());
// Cookies.set('scrollTopId', id);
// 判断是否跳转URL
// const { code, data } = await getArticleAPI({ f: 'article', i: id, cid });
// if (code) {
// if (data.post_link) { // 优先显示链接文章
// location.href = data.post_link;
// return false;
// }
// router.push({
// path: '/detail',
// query: { cid, id, column, section, name }
// });
// }
if (item) {
if (item.post_link) {
if (item.post_link.indexOf('f/guanzong/web')) {
item.post_link = item.post_link.replace('web', 'front');
}
if (item.post_link.indexOf('f/guanzong/web/#/list') > 0 || item.post_link.indexOf('f/guanzong/front/#/list') > 0) {
router.push({
path: '/list',
query: parseQueryString(item.post_link)
});
return false;
} else if (item.post_link) { // 优先显示链接文章
location.href = item.post_link;
return false;
}
} else {
router.push({
path: '/detail',
query: { cid: item.item, id: item.id, column: item.column, section: item.section, name: item.name }
});
}
}
}
return detail
}
export function useReplace () {
let router = useRouter()
function replace (path, query) {
router.replace({
path: path,
query: query
})
}
return replace
}
export function getScrollTop () {
var scroll_top = 0;
if (document.documentElement && document.documentElement.scrollTop) {
scroll_top = document.documentElement.scrollTop;
}
else if (document.body) {
scroll_top = document.body.scrollTop;
}
return scroll_top;
}
import { mainStore } from '@/utils/generatePackage.js'
// 删除 keep-alive 缓存
export const store = mainStore();
export const killPages = () => {
store.changeKeepPages();
}
export const addPages = () => {
store.keepThisPage();
}
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-31 12:06:19
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-06-07 10:28:48
* @FilePath: /data-table/src/main.js
* @Description:
*/
import { createApp } from 'vue';
import { Button, Image as VanImage, Col, Row, Icon, Form, Field, CellGroup, ConfigProvider, Toast, Uploader, Empty, Tab, Tabs, Overlay, NumberKeyboard, Lazyload, List, PullRefresh, Popup, Picker, Sticky, Stepper, Tag, Swipe, SwipeItem, Dialog, ActionSheet, Loading, Checkbox, Search, NavBar, Collapse, CollapseItem, RadioGroup, Radio, CheckboxGroup, Area, DatePicker, TimePicker, PickerGroup, Rate, Calendar, Divider, Popover, NoticeBar, ImagePreview, FloatingBubble } from 'vant';
import router from './router';
import App from './App.vue';
// import axios from './utils/axios';
import axios from '@/utils/axios';
// import 'default-passive-events'; // 解决Chrome控制台non-passive event listener输出问题
import { createPinia } from 'pinia';
import vueEsign from 'vue-esign'
import 'vant/lib/index.css';
const pinia = createPinia();
const app = createApp(App);
// 屏蔽警告信息
app.config.warnHandler = () => null;
app.config.globalProperties.$http = axios; // 关键语句
app.use(pinia).use(router).use(Button).use(VanImage).use(Col).use(Row).use(Icon).use(Form).use(Field).use(CellGroup).use(Toast).use(Uploader).use(Empty).use(Tab).use(Tabs).use(Overlay).use(NumberKeyboard).use(Lazyload).use(List).use(PullRefresh).use(Popup).use(Picker).use(Sticky).use(Stepper).use(Tag).use(Swipe).use(SwipeItem).use(Dialog).use(ActionSheet).use(Loading).use(Checkbox).use(Search).use(ConfigProvider).use(NavBar).use(Collapse).use(CollapseItem).use(Radio).use(RadioGroup).use(CheckboxGroup).use(Area).use(DatePicker).use(TimePicker).use(PickerGroup).use(Rate).use(Calendar).use(Divider).use(Popover).use(NoticeBar).use(ImagePreview).use(FloatingBubble);
app.use(vueEsign)
app.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.
<template>
<router-view></router-view>
</template>
<script>
export default {
data () {
return {
}
},
mounted () {
},
methods: {
}
}
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App1</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./main.js"></script>
</body>
</html>
import { createApp } from 'vue';
import App from './App.vue';
// import store, { key } from './store/index';
import router from './router';
createApp(App).use(router).mount('#app');
import { createRouter, createWebHashHistory } from 'vue-router';
const router = createRouter({
history: createWebHashHistory('/index.html'),
routes: [
{
path: '/',
name: 'mono2',
component: () => import('./views/index.vue'),
},
],
});
export default router;
<template>
<div class="">456</div>
</template>
<script>
export default {
data () {
return {
}
},
mounted () {
},
methods: {
}
}
</script>
<style lang="less" scoped>
</style>
<template>
<router-view></router-view>
</template>
<script>
export default {
data () {
return {
}
},
mounted () {
},
methods: {
}
}
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App1</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./main.js"></script>
</body>
</html>
import { createApp } from 'vue';
import App from './App.vue';
// import store, { key } from './store/index';
import router from './router';
createApp(App).use(router).mount('#app');
import { createRouter, createWebHashHistory } from 'vue-router';
const router = createRouter({
history: createWebHashHistory('/index.html'),
routes: [
{
path: '/',
name: 'mono2',
component: () => import('./views/index.vue'),
},
],
});
export default router;
<template>
<div class="">123</div>
</template>
<script>
export default {
data () {
return {
}
},
mounted () {
},
methods: {
}
}
</script>
<style lang="less" scoped>
</style>
/*
* @Date: 2023-09-01 10:29:30
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-23 10:34:10
* @FilePath: /temple_material_request/src/route.js
* @Description: 文件描述
*/
export default [{
path: '/',
component: () => import('@/views/index.vue'),
meta: {
title: '首页',
}
}, {
path: '/auth',
component: () => import('@/views/auth.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;
export default {
defaultPageSize: 10,
}
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-05-26 10:08:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-02 22:50:53
* @FilePath: /tswj/src/settings/designSetting.js
* @Description:
*/
import { ref } from 'vue';
import { styleColor } from '@/constant.js';
export const styleObject1 = ref({
backgroundColor: styleColor.baseFontColor,
color: styleColor.baseColor,
borderColor: styleColor.baseColor
})
export const styleObject2 = ref({
backgroundColor: styleColor.baseColor,
color: styleColor.baseFontColor,
borderColor: styleColor.baseColor
})
export const styleObject3 = ref({
// backgroundColor: '#6D97D2',
backgroundColor: '#F4675A',
color: styleColor.baseFontColor,
// borderColor: '#6D97D2'
borderColor: '#F4675A'
})
export const styleObject4 = ref({
backgroundColor: styleColor.baseFontColor,
color: '#713610',
borderColor: '#713610'
})
export const styleObject5 = ref({
backgroundColor: styleColor.baseFontColor,
color: '#FDD347',
borderColor: '#FDD347'
})
export const styleObject6 = ref({
backgroundColor: styleColor.baseFontColor,
color: '#777777',
borderColor: '#777777'
})
export const styleObject7 = ref({
backgroundColor: styleColor.baseFontColor,
color: '#0B3A72',
borderColor: '#0B3A72'
})
/*
* @Author: hookehuyr hookehuyr@gmail.com
* @Date: 2022-06-07 22:46:46
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-08 05:34:56
* @FilePath: /tswj/src/shims-vue.d.ts
* @Description:
*/
declare module '*.vue' {
import type { DefineComponent } from 'vue';
const component: DefineComponent;
export default component;
}
/*
* @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-07-18 10:22:22
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-07-18 10:42:46
* @FilePath: /front/src/theme-vars.js
* @Description: 文件描述
*/
/*
* @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: 2022-06-29 18:18:09
* @FilePath: /tswj/src/views/test/404.vue
* @Description: 文件描述
-->
<template>
<div class="">404</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
</script>
<style lang="less" scoped>
</style>
<template>
<div />
</template>
<script setup lang="ts">
// 类装饰器、方法装饰器、属性装饰器、参数装饰器
// function addAge(constructor: Function) {
// constructor.prototype.age = 18
// }
// @addAge
// class Person {
// name: string;
// age!: number;
// constructor() {
// this.name = 'abc'
// }
// say () {
// console.warn('xxx')
// }
// }
// let person = new Person();
// console.warn(person);
// 属性/方法装饰器
// 声明装饰器修饰方法
// function method(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
// console.warn(target);
// console.warn('prop ' + propertyKey);
// console.warn('desc ' + JSON.stringify(descriptor));
// descriptor.writable = false;
// }
// // 声明装饰器修饰属性
// function prop(target: any, key: string): any {
// console.warn(target);
// console.warn('prop ' + key);
// const descriptor: PropertyDescriptor = {
// writable: true,
// configurable: true,
// enumerable: true,
// value: 'abc'
// };
// return descriptor;
// }
// // 类
// class Person {
// // @prop
// name: string;
// constructor() {
// this.name = 'xxx'
// }
// @method
// say() {
// return 'instance method'
// }
// @method
// static run() {
// return 'static method'
// }
// }
// const person = new Person()
// person.name
// Person.run()
// 参数装饰器
// function logParameter(target: Object, propertyKey: string, index: number) {
// console.log(target, propertyKey, index);
// }
// class Person {
// greet(@logParameter message: string, @logParameter name: string): string {
// return `${message} ${name}`;
// }
// }
// const p = new Person('');
// p.greet('hello', 'randy');
// class Person {
// name = 'abc'
// constructor (name) {
// this.name = name;
// }
// say() {
// console.warn('');
// }
// }
// import Person from '@/Person'
// class Son extends Person {
// say () {
// return ''
// }
// }
// const person = new Son('')
// console.warn(person);
// type E3 = NonNullable<string | number | null | undefined>
// // let e1: E3 = 1
// let e2: E3 = undefined
// console.warn(e2);
// function getUserInfo () {
// return 'abc'
// }
// type E = ReturnType<typeof getUserInfo>
// const user: E = {}
// console.warn(user);
// interface A {
// a: string;
// b: number;
// d: boolean;
// }
// type aPartial = Partial<A>
// type Point = 'x';
// type PointList = Record<Point, { key: number }>
// const z: PointList = {
// x: {
// key: 1
// }
// }
</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-23 10:34:37
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-23 10:34:49
* @FilePath: /temple_material_request/src/views/index.vue
* @Description: 文件描述
-->
<template>
<div class=""></div>
</template>
<script setup>
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
</script>
<style lang="less" scoped>
</style>
<!--
* @Date: 2022-06-29 18:18:02
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-07-22 13:24:19
* @FilePath: /data-table/src/views/no_auth.vue
* @Description: 文件描述
-->
<template>
<div class="table-box" :style="{ margin: is_pc ? '1rem 0' : '1rem', overflow: 'auto' }">
<div class="text-box">
<van-icon name="warning" color="red" size="1.25rem" />&nbsp;您暂无权限访问该页面
</div>
<div style="font-size: 15px; color: #525967; text-align: center; margin: 1rem auto;">{{ formSetting.auth_error }}</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Cookies, $, _, axios, storeToRefs, mainStore, Toast, useTitle } from '@/utils/generatePackage.js'
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
import { styleColor } from "@/constant.js";
import { wxInfo, getUrlParams } from "@/utils/tools";
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
// 获取表单设置
const store = mainStore();
const { formSetting } = storeToRefs(store);
const is_pc = computed(() => wxInfo().isPC);
onMounted(() => {
// TAG: 全局背景色
document
.querySelector("body")
.setAttribute("style", `background-color: ${styleColor.backgroundColor}`);
})
</script>
<style lang="less" scoped>
.table-box {
background-color: #ffffff;
padding: 1rem;
border-radius: 5px;
max-width: 800px;
min-width: 20rem;
.text-box {
text-align: center;
color: red;
overflow: hidden;
}
}
</style>
<!--
* @Date: 2022-06-29 18:18:02
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-29 18:18:09
* @FilePath: /tswj/src/views/test/404.vue
* @Description: 文件描述
-->
<template>
<div class="stop-page">
<div style="padding-top: 2rem; padding-bottom: 2rem; text-align: center">
<van-image
round
width="10rem"
height="10rem"
style="vertical-align: bottom"
:src="icon_success"
/>
<p style="font-size: 1.05rem; margin: 0.5rem; font-weight: bold">
<span v-if="status === 'apply'">表单未开始</span>
<span v-if="status === 'finish'">表单已结束</span>
<span v-if="status === 'disable'">表单已关闭</span>
</p>
<!-- <p style="font-size: 0.9rem; margin-bottom: 0.5rem">您的作品正在审核中</p> -->
<!-- <p style="font-size: 0.9rem">请耐心等待~~</p> -->
</div>
<!-- <div style="padding: 0 15% 1rem 15%">
<div class="button-plain" :style="styleObj" @click="handle">返回</div>
</div> -->
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { styleColor } from "@/constant.js";
import icon_success from "@images/que-sucess@2x.png";
import {
Cookies,
$,
_,
axios,
storeToRefs,
mainStore,
Toast,
useTitle,
} from "@/utils/generatePackage.js";
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
const styleObj = {
background: styleColor.baseColor,
border: styleColor.baseColor,
color: "#FFFFFF",
};
const status = $route.query.status;
onMounted(() => {});
const handle = () => {
$router.go(-1);
};
</script>
<style lang="less" scoped>
.stop-page {
.button-plain {
width: auto;
height: auto;
text-align: center;
padding: 0.6rem;
margin: 0.5rem;
font-size: 1rem;
// background: @base-font-color;
border-radius: 24px;
// border: 1px solid @base-color;
// color: @base-color;
font-weight: bold;
}
}
</style>
<!--
* @Date: 2022-06-29 18:18:02
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-02-16 16:41:15
* @FilePath: /data-table/src/views/success.vue
* @Description: 文件描述
-->
<template>
<div class="success-page">
<div v-if="successInfo.commit_text_type === 'default'" class="text-wrapper">
<van-image
round
width="10rem"
height="10rem"
style="vertical-align: bottom"
:src="icon_success"
/>
<p class="name">{{ successInfo.form_name }}</p>
<p class="text">{{ successInfo.commit_text }}</p>
</div>
<div v-else class="rich-text" v-html="successInfo.commit_text" />
<!-- <div style="padding: 0 15% 1rem 15%">
<div class="button-plain" :style="styleObj" @click="handle">返回</div>
</div> -->
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { styleColor } from "@/constant.js";
import icon_success from "@images/que-sucess@2x.png";
import {
Cookies,
$,
_,
axios,
storeToRefs,
mainStore,
Toast,
useTitle,
} from "@/utils/generatePackage.js";
//import { } from '@/utils/generateModules.js'
//import { } from '@/utils/generateIcons.js'
//import { } from '@/composables'
const $route = useRoute();
const $router = useRouter();
useTitle($route.meta.title);
const styleObj = {
background: styleColor.baseColor,
border: styleColor.baseColor,
color: "#FFFFFF",
};
// 获取成功返回信息
const store = mainStore();
const { successInfo } = storeToRefs(store);
const richText = '<div style="font-weight: bold;">123</div>'
onMounted(() => {
$('body').css('backgroundColor', 'white');
});
const handle = () => {
$router.go(-1);
};
</script>
<style lang="less" scoped>
.success-page {
.text-wrapper {
padding-top: 2rem;
padding-bottom: 2rem;
text-align: center;
.name {
font-size: 1.25rem;
margin: 0.5rem;
font-weight: bold;
}
.text {
font-size: 1.05rem;
margin: 0.5rem;
font-weight: bold;
}
}
.rich-text {
padding: 1rem 2rem;
white-space: pre-wrap;
:deep(img) {
width: 100%;
}
}
.button-plain {
width: auto;
height: auto;
text-align: center;
padding: 0.6rem;
margin: 0.5rem;
font-size: 1rem;
// background: @base-font-color;
border-radius: 24px;
// border: 1px solid @base-color;
// color: @base-color;
font-weight: bold;
}
}
</style>
<template>
<div class="tinymce-box">
<TEditor ref="refEdit" ></TEditor>
<div @click="getValue">获取内容</div>
<div @click="setValue">设置内容</div>
</div>
</template>
<script setup>
import TEditor from "@/components/TEditor/index.vue";
const refEdit = ref(null);
// refEdit.value.handleGetContent()
const getValue = () => {
console.warn(refEdit.value.handleGetContent());
}
const setValue = () => {
refEdit.value.handleSetContent('<p>test</p>')
}
</script>
<style>
.tinymce-box {
width: 100%;
}
</style>
{
"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",
],
"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
}
}
{
"defaultSeverity": "warning",
"extends": [
"tslint:recommended"
],
"linterOptions": {
"exclude": [
"node_modules/**"
]
},
"rules": {
"quotemark": [
true,
"single"
],
"indent": [
true,
"spaces",
2
],
"interface-name": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"no-consecutive-blank-lines": false,
"no-console": true
}
}
/*
* @Date: 2022-06-13 10:39:44
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-06-13 10:41:43
* @FilePath: /tswj/typings/index.d.ts
* @Description: 文件描述
*/
export {};
// => 全局类型声明
declare global {
interface Window {
_hmt: any;
wx: any;
AlipayJSBridge: any;
}
namespace GD {
interface BaseResponse<T = any> {
code: number;
data: T;
msg: string;
page: {
pageNo: number;
pageSize: number;
pages: number;
total: number;
};
}
}
}
// const response = GD.BaseResponse<{name: string}>
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 Components from 'unplugin-vue-components/vite';
// import { VantResolver } from 'unplugin-vue-components/resolvers';
import { defineConfig, loadEnv } from 'vite';
import { createProxy } from './build/proxy'
import DefineOptions from 'unplugin-vue-define-options/vite';
import AutoImport from 'unplugin-auto-import/vite';
import postcsspxtoviewport from 'postcss-px-to-viewport'
var path = require('path');
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 插件的更多细节。
vue(),
// Components({
// // resolvers: [VantResolver()],
// }),
// 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的支持。
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"),
"@composables": path.resolve(__dirname, "src/composables"),
"@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: ['vue'], // 如果你在你的应用程序中有相同依赖的副本(比如 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: [
// postcsspxtoviewport({
// unitToConvert: 'px', // 要转化的单位
// viewportWidth: 375, // UI设计稿的宽度
// unitPrecision: 6, // 转换后的精度,即小数点位数
// propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
// viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
// fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
// selectorBlackList: ['ignore-'], // 指定不转换为视窗单位的类名,
// minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
// mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
// replace: true, // 是否转换后直接更换属性值
// // exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配
// exclude: [],
// landscape: false // 是否处理横屏情况
// })
]
},
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', 'pinia', 'vue-router', 'vant'], // 默认情况下,不在 node_modules 中的,链接的包不会被预构建。使用此选项可强制预构建链接的包。
// keepNames: false, // 打包器有时需要重命名符号以避免冲突。 设置此项为 true 可以在函数和类上保留 name 属性。 若想获取更多详情,请参阅 keepNames
}
});
};
This diff could not be displayed because it is too large.