jeecgboot-vue 1.0.0 版本发布
22
.env
|
@ -1,8 +1,22 @@
|
|||
# port
|
||||
VITE_PORT = 3100
|
||||
|
||||
# spa-title
|
||||
VITE_GLOB_APP_TITLE = Jeecg Boot
|
||||
# 网站标题
|
||||
VITE_GLOB_APP_TITLE = JeecgBoot 企业级低代码平台
|
||||
|
||||
# 简称,用于配置文件名字 不要出现空格、数字开头等特殊字符
|
||||
VITE_GLOB_APP_SHORT_NAME = JeecgBootAdmin
|
||||
|
||||
# 单点登录服务端地址
|
||||
VITE_GLOBE_APP_CAS_BASE_URL=http://cas.test.com:8443/cas
|
||||
|
||||
# 是否开启单点登录
|
||||
VITE_GLOB_APP_OPEN_SSO = false
|
||||
|
||||
# 开启微前端模式
|
||||
VITE_GLOB_APP_OPEN_QIANKUN=true
|
||||
|
||||
# 文件预览地址
|
||||
VITE_GLOB_ONLINE_VIEW_URL=http://fileview.jeecg.com/onlinePreview
|
||||
|
||||
|
||||
# spa shortname
|
||||
VITE_GLOB_APP_SHORT_NAME = Jeecg-Boot-Admin
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
# 是否打开mock
|
||||
VITE_USE_MOCK = false
|
||||
VITE_USE_MOCK = true
|
||||
|
||||
# 公共路径
|
||||
# 发布路径
|
||||
VITE_PUBLIC_PATH = /
|
||||
|
||||
# 跨域代理,您可以配置多个 ,请注意,没有换行符
|
||||
VITE_PROXY = [["/jeecg-boot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]]
|
||||
# VITE_PROXY=[["/api","https://vvbin.cn/test"]]
|
||||
VITE_PROXY = [["/jeecgboot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]]
|
||||
|
||||
# 控制台不输出
|
||||
VITE_DROP_CONSOLE = false
|
||||
|
||||
# 接口父路径
|
||||
VITE_GLOB_API_URL= /jeecg-boot
|
||||
#后台接口父地址(必填)
|
||||
VITE_GLOB_API_URL=/jeecgboot
|
||||
|
||||
# 文件上次地址(可选)
|
||||
VITE_GLOB_UPLOAD_URL=/upload
|
||||
#后台接口全路径地址(必填)
|
||||
VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot
|
||||
|
||||
# 接口前缀
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
|
||||
#微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径
|
||||
VITE_APP_SUB_jeecg-app-1 = '//localhost:8092'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# 是否启用mock
|
||||
VITE_USE_MOCK = true
|
||||
|
||||
# 公共路径
|
||||
# 发布路径
|
||||
VITE_PUBLIC_PATH = /
|
||||
|
||||
# 控制台不输出
|
||||
|
@ -10,19 +10,18 @@ VITE_DROP_CONSOLE = true
|
|||
# 是否启用gzip或brotli压缩
|
||||
# 选项值: gzip | brotli | none
|
||||
# 如果需要多个可以使用“,”分隔
|
||||
VITE_BUILD_COMPRESS = 'none'
|
||||
VITE_BUILD_COMPRESS = 'gzip'
|
||||
|
||||
# 使用压缩时是否删除原始文件,默认为false
|
||||
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
|
||||
|
||||
# 接口父路径
|
||||
VITE_GLOB_API_URL=/basic-api
|
||||
#后台接口父地址(必填)
|
||||
VITE_GLOB_API_URL=/jeecgboot
|
||||
|
||||
# 文件上次地址(可选)
|
||||
# 它可以由nginx转发,也可以直接写入实际地址
|
||||
VITE_GLOB_UPLOAD_URL=/upload
|
||||
#后台接口全路径地址(必填)
|
||||
VITE_GLOB_DOMAIN_URL=http://api3.boot.jeecg.com
|
||||
|
||||
# 接口父路径
|
||||
# 接口父路径前缀
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
|
||||
# 是否启用图像压缩
|
||||
|
|
33
.env.test
|
@ -1,36 +1,31 @@
|
|||
NODE_ENV=production
|
||||
# Whether to open mock
|
||||
# 是否启用mock
|
||||
VITE_USE_MOCK = true
|
||||
|
||||
# public path
|
||||
# 发布路径
|
||||
VITE_PUBLIC_PATH = /
|
||||
|
||||
# Delete console
|
||||
# 控制台不输出
|
||||
VITE_DROP_CONSOLE = true
|
||||
|
||||
# Whether to enable gzip or brotli compression
|
||||
# Optional: gzip | brotli | none
|
||||
# If you need multiple forms, you can use `,` to separate
|
||||
VITE_BUILD_COMPRESS = 'none'
|
||||
# 是否启用gzip或brotli压缩
|
||||
# 选项值: gzip | brotli | none
|
||||
# 如果需要多个可以使用“,”分隔
|
||||
VITE_BUILD_COMPRESS = 'gzip'
|
||||
|
||||
# Whether to delete origin files when using compress, default false
|
||||
# 使用压缩时是否删除原始文件,默认为false
|
||||
VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
|
||||
|
||||
# Basic interface address SPA
|
||||
VITE_GLOB_API_URL=/basic-api
|
||||
#后台接口地址(必填)
|
||||
VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot
|
||||
|
||||
# File upload address, optional
|
||||
# It can be forwarded by nginx or write the actual address directly
|
||||
VITE_GLOB_UPLOAD_URL=/upload
|
||||
|
||||
# Interface prefix
|
||||
# 接口父路径前缀
|
||||
VITE_GLOB_API_URL_PREFIX=
|
||||
|
||||
# Whether to enable image compression
|
||||
# 是否启用图像压缩
|
||||
VITE_USE_IMAGEMIN= true
|
||||
|
||||
# use pwa
|
||||
# 使用pwa
|
||||
VITE_USE_PWA = false
|
||||
|
||||
# Is it compatible with older browsers
|
||||
# 是否兼容旧浏览器
|
||||
VITE_LEGACY = false
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
JEECG BOOT 低代码平台(Vue3前端版本)
|
||||
===============
|
||||
|
||||
当前最新版本: 1.0.0-beta(发布日期:未正式发布)
|
||||
当前最新版本: 1.0.0-beta(预计发布日期 20220321)
|
||||
|
||||
|
||||
## 简介
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { generate } from '@ant-design/colors';
|
||||
|
||||
export const primaryColor = '#0960bd';
|
||||
export const primaryColor = '#1890FF';
|
||||
|
||||
export const darkMode = 'light';
|
||||
|
||||
|
|
|
@ -5,18 +5,19 @@ import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant';
|
|||
import fs, { writeFileSync } from 'fs-extra';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { getRootPath, getEnvConfig } from '../utils';
|
||||
import { getEnvConfig, getRootPath } from '../utils';
|
||||
import { getConfigFileName } from '../getConfigFileName';
|
||||
|
||||
import pkg from '../../package.json';
|
||||
|
||||
function createConfig(
|
||||
{
|
||||
configName,
|
||||
config,
|
||||
configFileName = GLOB_CONFIG_FILE_NAME,
|
||||
}: { configName: string; config: any; configFileName?: string } = { configName: '', config: {} }
|
||||
) {
|
||||
interface CreateConfigParams {
|
||||
configName: string;
|
||||
config: any;
|
||||
configFileName?: string;
|
||||
}
|
||||
|
||||
function createConfig(params: CreateConfigParams) {
|
||||
const { configName, config, configFileName } = params;
|
||||
try {
|
||||
const windowConf = `window.${configName}`;
|
||||
// Ensure that the variable will not be modified
|
||||
|
@ -40,5 +41,5 @@ function createConfig(
|
|||
export function runBuildConfig() {
|
||||
const config = getEnvConfig();
|
||||
const configFileName = getConfigFileName(config);
|
||||
createConfig({ config, configName: configFileName });
|
||||
createConfig({ config, configName: configFileName, configFileName: GLOB_CONFIG_FILE_NAME });
|
||||
}
|
||||
|
|
|
@ -28,12 +28,12 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
|
|||
if (envName === 'VITE_PORT') {
|
||||
realName = Number(realName);
|
||||
}
|
||||
if (envName === 'VITE_PROXY') {
|
||||
try {
|
||||
realName = JSON.parse(realName);
|
||||
} catch (error) {
|
||||
realName = '';
|
||||
}
|
||||
if (envName === 'VITE_PROXY' && realName) {
|
||||
try {
|
||||
realName = JSON.parse(realName.replace(/'/g, '"'));
|
||||
} catch (error) {
|
||||
realName = '';
|
||||
}
|
||||
}
|
||||
ret[envName] = realName;
|
||||
if (typeof realName === 'string') {
|
||||
|
@ -50,7 +50,7 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
|
|||
*/
|
||||
function getConfFiles() {
|
||||
const script = process.env.npm_lifecycle_script;
|
||||
const reg = new RegExp('--mode ([a-z]+)');
|
||||
const reg = new RegExp('--mode ([a-z_\\d]+)');
|
||||
const result = reg.exec(script as string) as any;
|
||||
if (result) {
|
||||
const mode = result[1] as string;
|
||||
|
|
|
@ -4,6 +4,7 @@ import vueJsx from '@vitejs/plugin-vue-jsx';
|
|||
import legacy from '@vitejs/plugin-legacy';
|
||||
import purgeIcons from 'vite-plugin-purge-icons';
|
||||
import windiCSS from 'vite-plugin-windicss';
|
||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend';
|
||||
import { configHtmlPlugin } from './html';
|
||||
import { configPwaConfig } from './pwa';
|
||||
import { configMockPlugin } from './mock';
|
||||
|
@ -29,7 +30,10 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
|||
vue(),
|
||||
// have to
|
||||
vueJsx(),
|
||||
// support name
|
||||
vueSetupExtend(),
|
||||
];
|
||||
|
||||
// vite-plugin-windicss
|
||||
vitePlugins.push(windiCSS());
|
||||
|
||||
|
@ -67,7 +71,7 @@ export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
|
|||
|
||||
// rollup-plugin-gzip
|
||||
vitePlugins.push(
|
||||
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE)
|
||||
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE),
|
||||
);
|
||||
|
||||
// vite-plugin-pwa
|
||||
|
|
|
@ -14,7 +14,52 @@ export function configStyleImportPlugin(isBuild: boolean) {
|
|||
libraryName: 'ant-design-vue',
|
||||
esModule: true,
|
||||
resolveStyle: (name) => {
|
||||
return `ant-design-vue/es/${name}/style/index`;
|
||||
// 这里是“子组件”列表,无需额外引入样式文件
|
||||
const ignoreList = [
|
||||
'typography-text',
|
||||
'typography-title',
|
||||
'typography-paragraph',
|
||||
'typography-link',
|
||||
'anchor-link',
|
||||
'sub-menu',
|
||||
'menu-item',
|
||||
'menu-item-group',
|
||||
'dropdown-button',
|
||||
'breadcrumb-item',
|
||||
'breadcrumb-separator',
|
||||
'input-password',
|
||||
'input-search',
|
||||
'input-group',
|
||||
'form-item',
|
||||
'radio-group',
|
||||
'checkbox-group',
|
||||
'layout-sider',
|
||||
'layout-content',
|
||||
'layout-footer',
|
||||
'layout-header',
|
||||
'step',
|
||||
'select-option',
|
||||
'select-opt-group',
|
||||
'card-grid',
|
||||
'card-meta',
|
||||
'collapse-panel',
|
||||
'descriptions-item',
|
||||
'list-item',
|
||||
'list-item-meta',
|
||||
'table-column',
|
||||
'table-column-group',
|
||||
'tab-pane',
|
||||
'tab-content',
|
||||
'timeline-item',
|
||||
'tree-node',
|
||||
'skeleton-input',
|
||||
'skeleton-avatar',
|
||||
'skeleton-title',
|
||||
'skeleton-paragraph',
|
||||
'skeleton-image',
|
||||
'skeleton-button',
|
||||
];
|
||||
return ignoreList.includes(name) ? '' : `ant-design-vue/es/${name}/style/index`;
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -66,7 +66,7 @@ export function configThemePlugin(isBuild: boolean): Plugin[] {
|
|||
'border-color-base': '#303030',
|
||||
// 'border-color-split': '#30363d',
|
||||
'item-active-bg': '#111b26',
|
||||
'app-content-background': 'rgb(255 255 255 / 4%)',
|
||||
'app-content-background': '#1e1e1e',
|
||||
'tree-node-selected-bg': '#11263c',
|
||||
|
||||
'alert-success-border-color': '#274916',
|
||||
|
|
|
@ -7,7 +7,7 @@ type ProxyItem = [string, string];
|
|||
|
||||
type ProxyList = ProxyItem[];
|
||||
|
||||
type ProxyTargetList = Record<string, ProxyOptions & { rewrite: (path: string) => string }>;
|
||||
type ProxyTargetList = Record<string, ProxyOptions>;
|
||||
|
||||
const httpsRE = /^https:\/\//;
|
||||
|
||||
|
|
137
doc/修改日志.md
|
@ -1,137 +0,0 @@
|
|||
## ✨ 功能优化---zhangyafei---2021-07-19
|
||||
- **添加增删改查demo**
|
||||
- src/views/demo/system/test/TestDrawer.vue
|
||||
- src/views/demo/system/test/test.data.ts
|
||||
- src/api/demo/model/systemModel.ts
|
||||
- src/api/demo/system.ts
|
||||
- mock/demo/system.ts
|
||||
- src/views/demo/system/test/index.vue
|
||||
- **添加代码高亮编辑器**
|
||||
- src/views/demo/codemirror/index.vue
|
||||
- **添加日历组件**
|
||||
- src/views/demo/fullcalendar/event-utils.ts
|
||||
- src/views/demo/fullcalendar/index.vue
|
||||
- **添加vexTable示例**
|
||||
- src/views/demo/vextable/index.vue
|
||||
- **添加JAreaLinkage示例**
|
||||
- src/components/Form/src/componentMap.ts
|
||||
- src/components/Form/src/types/index.ts
|
||||
- src/components/Form/index.ts
|
||||
- src/views/demo/form/index.vue
|
||||
- src/assets/less/JAreaLinkage.less
|
||||
- src/components/Form/src/components/JAreaLinkage.vue
|
||||
- **修改示例路由配置**
|
||||
- src/router/routes/modules/demo/feat.ts
|
||||
- src/router/routes/modules/demo/comp.ts
|
||||
- **修改路由国际化**
|
||||
- src/locales/lang/zh_CN/routes/demo.ts
|
||||
- **全局组件注册**
|
||||
- src/main.ts
|
||||
- **package添加组件依赖**
|
||||
- package.json
|
||||
- **路由跳转暂时屏蔽动画效果有bug冲突**
|
||||
- src/layouts/page/index.vue
|
||||
|
||||
## ✨ 功能优化---zhangyafei---2021-07-29
|
||||
- **添加一对多,一对一示例**
|
||||
- src/views/demo/vextable/VexTableModal.vue
|
||||
- src/views/demo/vextable/OneToOneModal.vue
|
||||
- src/views/demo/vextable/modal.vue
|
||||
- src/views/demo/vextable/index2.vue
|
||||
- src/views/demo/vextable/index.vue
|
||||
- src/views/demo/vextable/drawer.vue
|
||||
- **添加嵌套子表格示例**
|
||||
- src/views/demo/table/NestedTable.vue
|
||||
- **常用antd 组件全局注入**
|
||||
- src/components/registerGlobComp.ts
|
||||
- **添加权限,指令用法示例代码**
|
||||
- src/views/demo/permission/front/Btn.vue
|
||||
- **添加三方组件注册文件**
|
||||
- src/settings/registerThirdComp.ts
|
||||
- **main.ts注释汉化**
|
||||
- src/main.ts
|
||||
## ✨ 功能优化---liusq---2021-08-19
|
||||
- **增加接口token**
|
||||
- src/enums/httpEnum.ts
|
||||
- src/utils/http/axios/index.ts
|
||||
- **新增用户管理、角色管理**
|
||||
- src/views/demo/system/roles/*
|
||||
- src/views/demo/system/user/*
|
||||
- **登录验证码功能**
|
||||
- src/api/demo/model/systemModel.ts
|
||||
- src/api/demo/system.ts
|
||||
- src/api/model/baseModel.ts
|
||||
- src/api/sys/model/userModel.ts
|
||||
- src/api/sys/user.ts
|
||||
- src/locales/lang/zh_CN/routes/demo.ts
|
||||
- src/locales/lang/zh_CN/sys.ts
|
||||
- src/router/routes/modules/demo/system.ts
|
||||
- src/store/modules/user.ts
|
||||
- **接口和moke路径修改**
|
||||
- src/mock/demo/account.ts
|
||||
- src/mock/demo/select-demo.ts
|
||||
- src/mock/demo/system.ts
|
||||
- src/mock/demo/table-demo.ts
|
||||
- src/mock/demo/tree-demo.ts
|
||||
- src/mock/sys/menu.ts
|
||||
- src/mock/sys/user.ts
|
||||
- src/mock/_util.ts
|
||||
- src/api/sys/menu.ts
|
||||
- src/api/sys/user.ts
|
||||
- **table配置项修改**
|
||||
- src/settings/componentSetting.ts
|
||||
- **上传返回值修改**
|
||||
- src/components/Upload/src/UploadModal.vue
|
||||
## ✨ 功能完善---zhangyafei---2021-08-27
|
||||
- **添加租户功能**
|
||||
-src/views/system/tenant/**
|
||||
- **修改antd注册方式,改为全局注册**
|
||||
-src/main.ts
|
||||
-src/settings/registerThirdComp.ts
|
||||
- **网络请求类翻译,添加全局操作成功顶部消息提示**
|
||||
-src/utils/http/axios/Axios.ts
|
||||
-src/utils/http/axios/index.ts
|
||||
-src/-types/axios.d.ts
|
||||
- **表格选择工具类样式修改**
|
||||
-src/components/Table/src/BasicTable.vue
|
||||
- **底层代码优化**
|
||||
- src/api/demo/system.ts
|
||||
- src/api/sys/user.ts
|
||||
- src/router/guard/permissionGuard.ts
|
||||
- src/store/modules/user.ts
|
||||
- src/settings/projectSetting.ts
|
||||
- src/main.ts
|
||||
- mock/sys/user.ts
|
||||
- package.json
|
||||
## ✨ 功能完善---liusq---2021-08-27
|
||||
- **完善用户管理、角色管理功能**
|
||||
- system/user/UserRecycleBinModal.vue
|
||||
- system/user/UserDrawer.vue
|
||||
- system/user/user.data.ts
|
||||
- system/user/user.api.ts
|
||||
- system/user/index.vue
|
||||
- system/role/UserRoleDrawer.vue
|
||||
- system/role/RoleDrawer.vue
|
||||
- system/role/role.data.ts
|
||||
- system/role/role.api.ts
|
||||
- system/role/index.vue
|
||||
- /locales/lang/zh-CN/routes/demo.ts
|
||||
- /locales/lang/zh-CN/sys.ts
|
||||
- /api/demo/system.ts
|
||||
- **完善登录注册功能**
|
||||
- src/api/sys/user.ts
|
||||
- src/store/modules/user.ts
|
||||
- src/views/sys/forget-password/step1.vue
|
||||
- src/views/sys/forget-password/step2.vue
|
||||
- src/views/sys/forget-password/step3.vue
|
||||
- src/views/sys/login/ForgetPasswordForm.vue
|
||||
- src/views/sys/login/MobileForm.vue
|
||||
- src/views/sys/login/RegisterForm.vue
|
||||
- src/views/sys/login/useLogin.ts
|
||||
- src/assets/images/checkcode.png
|
||||
|
||||
## ✨ 还原路由走本地---scott---2021-08-31
|
||||
- src\settings\projectSetting.ts
|
||||
|
||||
## ✨ 功能完善---zyf---2021-08-31
|
||||
测试
|
|
@ -1,5 +0,0 @@
|
|||
###---zhangyafei---2021-08-31 租户、用户、角色
|
||||
update sys_permission set url='/system/tenant' ,component='/system/tenant/index' where id='1280350452934307841';
|
||||
update sys_permission set url='/system/user' ,component='/system/user/index' where id='3f915b2769fc80648e92d04e84ca059d';
|
||||
update sys_permission set url='/system/role' ,component='/system/role/index' where id='190c2b43bec6a5f7a4194a85db67d96a';
|
||||
###---zhangyafei---2021-08-31
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" id="htmlRoot">
|
||||
<html lang="zh_CN" id="htmlRoot">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
|
@ -10,7 +10,11 @@
|
|||
/>
|
||||
|
||||
<title><%= title %></title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="icon" href="/logo.png" />
|
||||
<!-- 全局配置 -->
|
||||
<script>
|
||||
window._CONFIG = {};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
|
|
@ -58,3 +58,6 @@ export interface requestParams {
|
|||
export function getRequestToken({ headers }: requestParams): string | undefined {
|
||||
return headers?.authorization;
|
||||
}
|
||||
|
||||
//TODO 接口父路径(写死不够灵活)
|
||||
export const baseUrl = '/jeecgboot/mock';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { resultSuccess, resultError } from '../_util';
|
||||
|
||||
import { resultSuccess, resultError, baseUrl } from '../_util';
|
||||
import { ResultEnum } from '../../src/enums/httpEnum';
|
||||
const userInfo = {
|
||||
name: 'Jeecg',
|
||||
userid: '00000001',
|
||||
|
@ -44,7 +44,7 @@ const userInfo = {
|
|||
|
||||
export default [
|
||||
{
|
||||
url: '/jeecg-boot/account/getAccountInfo',
|
||||
url: `${baseUrl}/account/getAccountInfo`,
|
||||
timeout: 1000,
|
||||
method: 'get',
|
||||
response: () => {
|
||||
|
@ -52,11 +52,19 @@ export default [
|
|||
},
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/user/sessionTimeout',
|
||||
url: `${baseUrl}/user/sessionTimeout`,
|
||||
method: 'post',
|
||||
statusCode: 401,
|
||||
response: () => {
|
||||
return resultError();
|
||||
},
|
||||
},
|
||||
{
|
||||
url: '/basic-api/user/tokenExpired',
|
||||
method: 'post',
|
||||
statusCode: 200,
|
||||
response: () => {
|
||||
return resultError('Token Expired!', { code: ResultEnum.TIMEOUT as number });
|
||||
},
|
||||
},
|
||||
] as MockMethod[];
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { resultSuccess } from '../_util';
|
||||
import { resultSuccess, baseUrl } from '../_util';
|
||||
|
||||
const demoList = (keyword) => {
|
||||
const demoList = (keyword, count = 20) => {
|
||||
const result = {
|
||||
list: [] as any[],
|
||||
};
|
||||
for (let index = 0; index < 20; index++) {
|
||||
for (let index = 0; index < count; index++) {
|
||||
result.list.push({
|
||||
name: `${keyword ?? ''}选项${index}`,
|
||||
id: `${index}`,
|
||||
|
@ -16,13 +16,13 @@ const demoList = (keyword) => {
|
|||
|
||||
export default [
|
||||
{
|
||||
url: '/jeecg-boot/select/getDemoOptions',
|
||||
url: `${baseUrl}/select/getDemoOptions`,
|
||||
timeout: 1000,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
const { keyword } = query;
|
||||
const { keyword,count} = query;
|
||||
console.log(keyword);
|
||||
return resultSuccess(demoList(keyword));
|
||||
return resultSuccess(demoList(keyword,count));
|
||||
},
|
||||
},
|
||||
] as MockMethod[];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {MockMethod} from 'vite-plugin-mock';
|
||||
import {resultError, resultPageSuccess, resultSuccess} from '../_util';
|
||||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { resultError, resultPageSuccess, resultSuccess, baseUrl } from '../_util';
|
||||
|
||||
const accountList = (() => {
|
||||
const result: any[] = [];
|
||||
|
@ -150,7 +150,7 @@ const menuList = (() => {
|
|||
permission: ['menu1:view', 'menu2:add', 'menu3:update', 'menu4:del'][index],
|
||||
component: [
|
||||
'/dashboard/welcome/index',
|
||||
'/dashboard/analysis/index',
|
||||
'/dashboard/Analysis/index',
|
||||
'/dashboard/workbench/index',
|
||||
'/dashboard/test/index',
|
||||
][j],
|
||||
|
@ -172,7 +172,7 @@ const menuList = (() => {
|
|||
(k + 1),
|
||||
component: [
|
||||
'/dashboard/welcome/index',
|
||||
'/dashboard/analysis/index',
|
||||
'/dashboard/Analysis/index',
|
||||
'/dashboard/workbench/index',
|
||||
'/dashboard/test/index',
|
||||
][j],
|
||||
|
@ -195,104 +195,104 @@ const menuList = (() => {
|
|||
})();
|
||||
|
||||
export default [
|
||||
{
|
||||
url: '/jeecg-boot/system/getAccountList',
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({query}) => {
|
||||
const {page = 1, pageSize = 20} = query;
|
||||
return resultPageSuccess(page, pageSize, accountList);
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/system/getAccountList`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
const { page = 1, pageSize = 20 } = query;
|
||||
return resultPageSuccess(page, pageSize, accountList);
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/sys/user/list',
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({query}) => {
|
||||
const {page = 1, pageSize = 20} = query;
|
||||
return resultPageSuccess(page, pageSize, userList);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/sys/user/list`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
const { page = 1, pageSize = 20 } = query;
|
||||
return resultPageSuccess(page, pageSize, userList);
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/system/getRoleListByPage',
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({query}) => {
|
||||
const {page = 1, pageSize = 20} = query;
|
||||
return resultPageSuccess(page, pageSize, roleList);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/system/getRoleListByPage`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
const { page = 1, pageSize = 20 } = query;
|
||||
return resultPageSuccess(page, pageSize, roleList);
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/sys/role/list',
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({query}) => {
|
||||
const {page = 1, pageSize = 20} = query;
|
||||
return resultPageSuccess(page, pageSize, newRoleList);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/sys/role/list`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
const { page = 1, pageSize = 20 } = query;
|
||||
return resultPageSuccess(page, pageSize, newRoleList);
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/system/getTestListByPage',
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({query}) => {
|
||||
const {page = 1, pageSize = 20} = query;
|
||||
return resultPageSuccess(page, pageSize, testList);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/system/getTestListByPage`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
const { page = 1, pageSize = 20 } = query;
|
||||
return resultPageSuccess(page, pageSize, testList);
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/system/getDemoTableListByPage',
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({query}) => {
|
||||
const {page = 1, pageSize = 20} = query;
|
||||
return resultPageSuccess(page, pageSize, tableDemoList);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/system/getDemoTableListByPage`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
const { page = 1, pageSize = 20 } = query;
|
||||
return resultPageSuccess(page, pageSize, tableDemoList);
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/system/setRoleStatus',
|
||||
timeout: 500,
|
||||
method: 'post',
|
||||
response: ({query}) => {
|
||||
const {id, status} = query;
|
||||
return resultSuccess({id, status});
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/system/setRoleStatus`,
|
||||
timeout: 500,
|
||||
method: 'post',
|
||||
response: ({ query }) => {
|
||||
const { id, status } = query;
|
||||
return resultSuccess({ id, status });
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/system/getAllRoleList',
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: () => {
|
||||
return resultSuccess(roleList);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/system/getAllRoleList`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: () => {
|
||||
return resultSuccess(roleList);
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/system/getDeptList',
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: () => {
|
||||
return resultSuccess(deptList);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/system/getDeptList`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: () => {
|
||||
return resultSuccess(deptList);
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/system/getMenuList',
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: () => {
|
||||
return resultSuccess(menuList);
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/system/getMenuList`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: () => {
|
||||
return resultSuccess(menuList);
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/system/accountExist',
|
||||
timeout: 500,
|
||||
method: 'post',
|
||||
response: ({body}) => {
|
||||
const {account} = body || {};
|
||||
if (account && account.indexOf('admin') !== -1) {
|
||||
return resultError('该字段不能包含admin');
|
||||
} else {
|
||||
return resultSuccess(`${account} can use`);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
url: `${baseUrl}/system/accountExist`,
|
||||
timeout: 500,
|
||||
method: 'post',
|
||||
response: ({ body }) => {
|
||||
const { account } = body || {};
|
||||
if (account && account.indexOf('admin') !== -1) {
|
||||
return resultError('该字段不能包含admin');
|
||||
} else {
|
||||
return resultSuccess(`${account} can use`);
|
||||
}
|
||||
},
|
||||
},
|
||||
] as MockMethod[];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { Random } from 'mockjs';
|
||||
import { resultPageSuccess } from '../_util';
|
||||
import { resultPageSuccess, baseUrl } from '../_util';
|
||||
|
||||
function getRandomPics(count = 10): string[] {
|
||||
const arr: string[] = [];
|
||||
|
@ -12,7 +12,7 @@ function getRandomPics(count = 10): string[] {
|
|||
|
||||
const demoList = (() => {
|
||||
const result: any[] = [];
|
||||
for (let index = 0; index < 60; index++) {
|
||||
for (let index = 0; index < 200; index++) {
|
||||
result.push({
|
||||
id: `${index}`,
|
||||
beginTime: '@datetime',
|
||||
|
@ -41,7 +41,7 @@ const demoList = (() => {
|
|||
|
||||
export default [
|
||||
{
|
||||
url: '/jeecg-boot/table/getDemoList',
|
||||
url: `${baseUrl}/table/getDemoList`,
|
||||
timeout: 100,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { resultSuccess } from '../_util';
|
||||
import { resultSuccess, baseUrl } from '../_util';
|
||||
|
||||
const demoTreeList = (keyword) => {
|
||||
const result = {
|
||||
|
@ -26,7 +26,7 @@ const demoTreeList = (keyword) => {
|
|||
|
||||
export default [
|
||||
{
|
||||
url: '/jeecg-boot/tree/getDemoOptions',
|
||||
url: `${baseUrl}/tree/getDemoOptions`,
|
||||
timeout: 1000,
|
||||
method: 'get',
|
||||
response: ({ query }) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { resultSuccess, resultError, getRequestToken, requestParams } from '../_util';
|
||||
import { resultSuccess, resultError, getRequestToken, requestParams,baseUrl} from '../_util';
|
||||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { createFakeUserList } from './user';
|
||||
|
||||
|
@ -17,7 +17,7 @@ const dashboardRoute = {
|
|||
{
|
||||
path: 'analysis',
|
||||
name: 'Analysis',
|
||||
component: '/dashboard/analysis/index',
|
||||
component: '/dashboard/Analysis/index',
|
||||
meta: {
|
||||
hideMenu: true,
|
||||
hideBreadcrumb: true,
|
||||
|
@ -237,7 +237,7 @@ const linkRoute = {
|
|||
|
||||
export default [
|
||||
{
|
||||
url: '/jeecg-boot/sys/permission/getUserPermissionByToken',
|
||||
url: `${baseUrl}/sys/permission/getUserPermissionByToken`,
|
||||
timeout: 1000,
|
||||
method: 'get',
|
||||
response: (request: requestParams) => {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { MockMethod } from 'vite-plugin-mock';
|
||||
import { resultError, resultSuccess, getRequestToken, requestParams } from '../_util';
|
||||
|
||||
import { resultError, resultSuccess, getRequestToken, requestParams, baseUrl } from '../_util';
|
||||
export function createFakeUserList() {
|
||||
return [
|
||||
{
|
||||
userId: '1',
|
||||
username: 'jeecg',
|
||||
username: 'admin',
|
||||
realname: '管理员',
|
||||
avatar: 'https://q1.qlogo.cn/g?b=qq&nk=190848757&s=640',
|
||||
desc: 'manager',
|
||||
|
@ -21,7 +20,7 @@ export function createFakeUserList() {
|
|||
},
|
||||
{
|
||||
userId: '2',
|
||||
username: 'test',
|
||||
username: 'jeecg',
|
||||
password: '123456',
|
||||
realname: '测试用户',
|
||||
avatar: 'https://q1.qlogo.cn/g?b=qq&nk=339449197&s=640',
|
||||
|
@ -47,7 +46,7 @@ const fakeCodeList: any = {
|
|||
export default [
|
||||
// mock user login
|
||||
{
|
||||
url: '/jeecg-boot/sys/login',
|
||||
url: `${baseUrl}/sys/login`,
|
||||
timeout: 200,
|
||||
method: 'post',
|
||||
response: ({ body }) => {
|
||||
|
@ -58,19 +57,19 @@ export default [
|
|||
if (!checkUser) {
|
||||
return resultError('Incorrect account or password!');
|
||||
}
|
||||
const { userId, username: _username, token, realName, desc, roles } = checkUser;
|
||||
const { userId, username: _username, token, realname, desc, roles } = checkUser;
|
||||
return resultSuccess({
|
||||
roles,
|
||||
userId,
|
||||
username: _username,
|
||||
token,
|
||||
realName,
|
||||
realname,
|
||||
desc,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/sys/user/getUserInfo',
|
||||
url: `${baseUrl}/sys/user/getUserInfo`,
|
||||
method: 'get',
|
||||
response: (request: requestParams) => {
|
||||
const token = getRequestToken(request);
|
||||
|
@ -83,7 +82,7 @@ export default [
|
|||
},
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/sys/permission/getPermCode',
|
||||
url: `${baseUrl}/sys/permission/getPermCode`,
|
||||
timeout: 200,
|
||||
method: 'get',
|
||||
response: (request: requestParams) => {
|
||||
|
@ -99,7 +98,7 @@ export default [
|
|||
},
|
||||
},
|
||||
{
|
||||
url: '/jeecg-boot/sys/logout',
|
||||
url: `${baseUrl}/sys/logout`,
|
||||
timeout: 200,
|
||||
method: 'get',
|
||||
response: (request: requestParams) => {
|
||||
|
@ -113,11 +112,12 @@ export default [
|
|||
},
|
||||
},
|
||||
{
|
||||
url: `/jeecg-boot/sys/randomImage/1629428467008`,
|
||||
url: `${baseUrl}/sys/randomImage/1629428467008`,
|
||||
timeout: 200,
|
||||
method: 'get',
|
||||
response: (request: requestParams) => {
|
||||
var result = "data:image/jpg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAjAGkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3h/ME5lErCKNSHi8rO44yCp65/P060gmdbbIaKecxl0VDsEmOmMk8cgZ96dcypFGpkEm0uOUzxznJI6DjnPH54ryTWNW1+P436T4ftNev4LTU7Brhw9tbCSHiZxGrNCcKCijkMeuSSOAD1KJ7hrTZNK0d1Iz7egGVPRSV6HGRkE4z1xV5SWQEqVJGSpxke3FeYL4n1PSfi5pXhK7vxrFlf27XVveyQRrcQHa4KFo1CMhMLdFUjfy2F59NjZm3Bl2kMRxnGO3JA7Y/HI7UAVrjfbWt3NJLNKmCwVAoaNcc4PHTk8+n5rKs1tDGtsdw5X94GkOT90ls5xnr14PYDNeUfDzxvq3xCuNZvG8SNp1zBKHtdFgtYpFjhAADuWXfKpJwwRkIwcFd6geg+Dm12Tw9bN4hkX+0Y5bmKcLGVV9s7KjLkA7dijBPLAgnJ5oWgGrb36zBtqyPh9oKwuvG4DncByCeeexPsLHm7jH5amSNxnzFI2gY479/bNVrxYZpRD57Q3JRkikRFLxlgfmUspGQEbrkccg8V5l8PfEOt6h4p8YW+r+JJf7M8OXZhjWWC2jjMQaZSZWWNSMLGDkFQD1BHFAHq7usMcksjnYoLHI+6AOen0pqllZfNkUMWZVUdG5yOvOcD+dcclt4j1/XlvtM8T3dn4cIc7kgt2a4PGwwBoTiLqfMZm34+VQpVz0Ou2t/eWfk2GrXGmTNxHcW9ukxV8EAOrqwKZIJ+6fl+8M0AXjHcb5GWdcN9xWjyF6ehGe/5j05jmdri3cxPJGI3YOAOXABGARnGTjkcjpwenmvwt8Y61czeIdM8b6g0esaW3mTR3SwQJFAB99dijcOpZySoBjI+8TXR+EtK16SNdR1rWL64WUNPaWtxbxQGBXbKCVY0VjKq/f525dgBxuKA6i4ZfsSEyq0R275Wm8v5f7wZe/TjgHNWqiiSWNEV5vNwp3MygFj68cAdeMen4y0wKk6Mtysp3yQsvktEoyPmI+YgnGB9O57dPIfGML3H7SnhaGO+msXfS2C3EIjLqcXPTzFZeenIPXjnFeyiIJIzx4XzH3SZBO75ccc8dF/L3zXHah4D0K58US+ILuLUPtcMeI5l1G5WT5i+VjYSDYCW2hVIHLDaMg0AX9K8FaVZ+IJPEVxPc6rrTAxLf3rqzRJgKURUVUToeQoPzNk8mt0qRJF5uTMVdBNGuAucHoScdByeOPcAxRw3MdzOpuC3nZkQiEBY8EcMf4sggfRT0qYQSJBJGJWlGwKodirZxjlxzzxzjIOfYAA8Tn+HehfErRoPGvhDUP7J1uQCaWK3YmJLpQWZT0aN95X5xxgBgp3ZPb/AAi8U6r4q8BRajriv9qW5khFy6hBcrkEOoCqAAW2cZ5Q85yBdtPAfhSTSv7Og0mWxiWH7PcQ288lq86Y2/vjEy+cCM8sW6t6mukt9PttNsobLTbC0gtY34gjURIgzuJVVGM55xxz3oAnZf8ASI38vcQrLu3fdBwenccfy96+abbwjqHiu8+K1lpt/NFJBqYlW1MwSO5KzzECRmBJwA2ASBuKljxkfSF9ai7jeESzRtJGy5R3UAdCcoVIOGOCCD36qMc9oHgHw/oGrSalpMd1a3DuWnRb6Z1lYr/y2VnYOw3sQT03Z96AMn4W+PP+Et0xrLVZmi8TaerRX9pJH5Rba2BIE9egbGMMSCACtdxOHuYmXy3CCVRjIHmLkbs5HTrx3A9DXJN8LvCraj/adpa3SajtZBqC6rdGaMhdgw3mZOB8uMjgY9q39X0Sx1myuLLUknWwbLSLDdyQrKGUhgxRlOPvZUnac5OT0AseQfEHT7u71CP4keHrbTZJtFSGWQ/Zmk+3gMytMByDGm0BXwrbVdwwVYmPqXhvxDZeKdEj1bRL6AWM42NvT9/DLtVQkmWOXBx16jbjIINGl+GdPs9I/seG6nSAfIY7e/n3qqEBVSQuZI1A25RWABOOhO7P8NeA/DejRveaBpb2IuW2k/bJmDxjIDlJNyk4LYyOjHBGaAOwjeQogYxtIuBNtbhTjPH6cHsalqlbWMFrcSNuVnkkeZAwG5c/eI79wOO2O+SbtABSMiuMMoYZBwRnkHIP50UUALRRRQAUUUUAFFFFACBVUsVUAscsQOpxjn8AKWiigBFVUQIihVUYAAwAKY8EUkqSOgZ0BCk9uQf5qD+FFFAElFFFAH//2Q==";
|
||||
const result =
|
||||
'data:image/jpg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAjAGkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3h/ME5lErCKNSHi8rO44yCp65/P060gmdbbIaKecxl0VDsEmOmMk8cgZ96dcypFGpkEm0uOUzxznJI6DjnPH54ryTWNW1+P436T4ftNev4LTU7Brhw9tbCSHiZxGrNCcKCijkMeuSSOAD1KJ7hrTZNK0d1Iz7egGVPRSV6HGRkE4z1xV5SWQEqVJGSpxke3FeYL4n1PSfi5pXhK7vxrFlf27XVveyQRrcQHa4KFo1CMhMLdFUjfy2F59NjZm3Bl2kMRxnGO3JA7Y/HI7UAVrjfbWt3NJLNKmCwVAoaNcc4PHTk8+n5rKs1tDGtsdw5X94GkOT90ls5xnr14PYDNeUfDzxvq3xCuNZvG8SNp1zBKHtdFgtYpFjhAADuWXfKpJwwRkIwcFd6geg+Dm12Tw9bN4hkX+0Y5bmKcLGVV9s7KjLkA7dijBPLAgnJ5oWgGrb36zBtqyPh9oKwuvG4DncByCeeexPsLHm7jH5amSNxnzFI2gY479/bNVrxYZpRD57Q3JRkikRFLxlgfmUspGQEbrkccg8V5l8PfEOt6h4p8YW+r+JJf7M8OXZhjWWC2jjMQaZSZWWNSMLGDkFQD1BHFAHq7usMcksjnYoLHI+6AOen0pqllZfNkUMWZVUdG5yOvOcD+dcclt4j1/XlvtM8T3dn4cIc7kgt2a4PGwwBoTiLqfMZm34+VQpVz0Ou2t/eWfk2GrXGmTNxHcW9ukxV8EAOrqwKZIJ+6fl+8M0AXjHcb5GWdcN9xWjyF6ehGe/5j05jmdri3cxPJGI3YOAOXABGARnGTjkcjpwenmvwt8Y61czeIdM8b6g0esaW3mTR3SwQJFAB99dijcOpZySoBjI+8TXR+EtK16SNdR1rWL64WUNPaWtxbxQGBXbKCVY0VjKq/f525dgBxuKA6i4ZfsSEyq0R275Wm8v5f7wZe/TjgHNWqiiSWNEV5vNwp3MygFj68cAdeMen4y0wKk6Mtysp3yQsvktEoyPmI+YgnGB9O57dPIfGML3H7SnhaGO+msXfS2C3EIjLqcXPTzFZeenIPXjnFeyiIJIzx4XzH3SZBO75ccc8dF/L3zXHah4D0K58US+ILuLUPtcMeI5l1G5WT5i+VjYSDYCW2hVIHLDaMg0AX9K8FaVZ+IJPEVxPc6rrTAxLf3rqzRJgKURUVUToeQoPzNk8mt0qRJF5uTMVdBNGuAucHoScdByeOPcAxRw3MdzOpuC3nZkQiEBY8EcMf4sggfRT0qYQSJBJGJWlGwKodirZxjlxzzxzjIOfYAA8Tn+HehfErRoPGvhDUP7J1uQCaWK3YmJLpQWZT0aN95X5xxgBgp3ZPb/AAi8U6r4q8BRajriv9qW5khFy6hBcrkEOoCqAAW2cZ5Q85yBdtPAfhSTSv7Og0mWxiWH7PcQ288lq86Y2/vjEy+cCM8sW6t6mukt9PttNsobLTbC0gtY34gjURIgzuJVVGM55xxz3oAnZf8ASI38vcQrLu3fdBwenccfy96+abbwjqHiu8+K1lpt/NFJBqYlW1MwSO5KzzECRmBJwA2ASBuKljxkfSF9ai7jeESzRtJGy5R3UAdCcoVIOGOCCD36qMc9oHgHw/oGrSalpMd1a3DuWnRb6Z1lYr/y2VnYOw3sQT03Z96AMn4W+PP+Et0xrLVZmi8TaerRX9pJH5Rba2BIE9egbGMMSCACtdxOHuYmXy3CCVRjIHmLkbs5HTrx3A9DXJN8LvCraj/adpa3SajtZBqC6rdGaMhdgw3mZOB8uMjgY9q39X0Sx1myuLLUknWwbLSLDdyQrKGUhgxRlOPvZUnac5OT0AseQfEHT7u71CP4keHrbTZJtFSGWQ/Zmk+3gMytMByDGm0BXwrbVdwwVYmPqXhvxDZeKdEj1bRL6AWM42NvT9/DLtVQkmWOXBx16jbjIINGl+GdPs9I/seG6nSAfIY7e/n3qqEBVSQuZI1A25RWABOOhO7P8NeA/DejRveaBpb2IuW2k/bJmDxjIDlJNyk4LYyOjHBGaAOwjeQogYxtIuBNtbhTjPH6cHsalqlbWMFrcSNuVnkkeZAwG5c/eI79wOO2O+SbtABSMiuMMoYZBwRnkHIP50UUALRRRQAUUUUAFFFFACBVUsVUAscsQOpxjn8AKWiigBFVUQIihVUYAAwAKY8EUkqSOgZ0BCk9uQf5qD+FFFAElFFFAH//2Q==';
|
||||
return resultSuccess(result);
|
||||
},
|
||||
},
|
||||
|
|
133
package.json
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"name": "jeecg-boot-vue3",
|
||||
"name": "jeecgboot-vue3",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "jeecg",
|
||||
"email": "jeecgos@163.com",
|
||||
"url": "https://gitee.com/jeecg/jeecg-boot-vue3"
|
||||
"url": "https://github.com/jeecgboot/jeecgboot-vue3"
|
||||
},
|
||||
"scripts": {
|
||||
"bootstrap": "yarn install",
|
||||
|
@ -35,28 +35,26 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@iconify/iconify": "^2.0.4",
|
||||
"@logicflow/core": "^0.6.15",
|
||||
"@logicflow/extension": "^0.6.15",
|
||||
"@fullcalendar/core": "^5.8.0",
|
||||
"@fullcalendar/daygrid": "^5.8.0",
|
||||
"@fullcalendar/interaction": "^5.8.0",
|
||||
"@fullcalendar/timegrid": "^5.8.0",
|
||||
"@fullcalendar/vue3": "^5.8.0",
|
||||
"@vueuse/core": "^6.0.0",
|
||||
"@vueuse/core": "^6.6.2",
|
||||
"@zxcvbn-ts/core": "^1.0.0-beta.0",
|
||||
"ant-design-vue": "^2.2.6",
|
||||
"axios": "^0.21.1",
|
||||
"ant-design-vue": "2.2.8",
|
||||
"axios": "^0.23.0",
|
||||
"china-area-data": "^5.0.1",
|
||||
"clipboard": "^2.0.8",
|
||||
"codemirror": "^5.62.3",
|
||||
"codemirror": "^5.63.3",
|
||||
"cron-parser": "^3.5.0",
|
||||
"cropperjs": "^1.5.12",
|
||||
"crypto-js": "^4.1.1",
|
||||
"dayjs": "^1.10.6",
|
||||
"dom-align": "^1.12.2",
|
||||
"echarts": "^5.1.2",
|
||||
"echarts": "^5.2.1",
|
||||
"enquire.js": "^2.1.6",
|
||||
"intro.js": "^4.1.0",
|
||||
"intro.js": "^4.2.2",
|
||||
"js-cookie": "^2.2.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lodash.get": "^4.4.2",
|
||||
|
@ -65,98 +63,103 @@
|
|||
"mockjs": "^1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"path-to-regexp": "^6.2.0",
|
||||
"pinia": "2.0.0-rc.6",
|
||||
"pinia": "2.0.0-rc.14",
|
||||
"print-js": "^1.6.0",
|
||||
"qrcode": "^1.4.4",
|
||||
"qrcodejs2": "0.0.2",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"showdown": "^1.9.1",
|
||||
"sortablejs": "^1.14.0",
|
||||
"tinymce": "^5.8.2",
|
||||
"vditor": "^3.8.6",
|
||||
"vue": "3.2.4",
|
||||
"tinymce": "^5.10.0",
|
||||
"vditor": "^3.8.7",
|
||||
"vue": "^3.2.20",
|
||||
"vue-cropper": "^0.5.6",
|
||||
"vue-cropperjs": "^5.0.0",
|
||||
"vue-i18n": "9.1.7",
|
||||
"vue-i18n": "^9.1.9",
|
||||
"vue-infinite-scroll": "^2.0.2",
|
||||
"vue-router": "^4.0.11",
|
||||
"vue-types": "^4.0.3",
|
||||
"vxe-table": "^4.0.24",
|
||||
"vue-print-nb-jeecg": "^1.0.10",
|
||||
"vue-router": "^4.0.12",
|
||||
"vue-types": "^4.1.1",
|
||||
"vxe-table": "4.1.0",
|
||||
"vxe-table-plugin-antd": "^3.0.3",
|
||||
"xe-utils": "^3.3.1",
|
||||
"xlsx": "^0.17.1",
|
||||
"vue-json-pretty": "1.8.1"
|
||||
"xlsx": "^0.17.3",
|
||||
"qiankun": "^2.5.1",
|
||||
"vue-json-pretty": "^2.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^13.1.0",
|
||||
"@commitlint/config-conventional": "^13.1.0",
|
||||
"@iconify/json": "^1.1.392",
|
||||
"@commitlint/cli": "^13.2.1",
|
||||
"@commitlint/config-conventional": "^13.2.0",
|
||||
"@iconify/json": "^1.1.399",
|
||||
"@purge-icons/generated": "^0.7.0",
|
||||
"@types/codemirror": "^5.60.2",
|
||||
"@types/codemirror": "^5.60.5",
|
||||
"@types/crypto-js": "^4.0.2",
|
||||
"@types/fs-extra": "^9.0.12",
|
||||
"@types/inquirer": "^7.3.3",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/inquirer": "^8.1.3",
|
||||
"@types/intro.js": "^3.0.2",
|
||||
"@types/jest": "^27.0.1",
|
||||
"@types/lodash-es": "^4.17.4",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/lodash-es": "^4.17.5",
|
||||
"@types/mockjs": "^1.0.4",
|
||||
"@types/node": "^16.7.1",
|
||||
"@types/node": "^16.11.1",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/qrcode": "^1.4.1",
|
||||
"@types/qs": "^6.9.7",
|
||||
"@types/showdown": "^1.9.4",
|
||||
"@types/sortablejs": "^1.10.7",
|
||||
"@typescript-eslint/eslint-plugin": "^4.29.3",
|
||||
"@typescript-eslint/parser": "^4.29.3",
|
||||
"@vitejs/plugin-legacy": "^1.5.1",
|
||||
"@vitejs/plugin-vue": "^1.4.0",
|
||||
"@vitejs/plugin-vue-jsx": "^1.1.7",
|
||||
"@vue/compiler-sfc": "3.2.4",
|
||||
"@vue/test-utils": "^2.0.0-rc.12",
|
||||
"autoprefixer": "^10.3.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.1.0",
|
||||
"@typescript-eslint/parser": "^5.1.0",
|
||||
"@vitejs/plugin-legacy": "^1.6.2",
|
||||
"@vitejs/plugin-vue": "^1.9.3",
|
||||
"@vitejs/plugin-vue-jsx": "^1.2.0",
|
||||
"@vue/compiler-sfc": "3.2.20",
|
||||
"@vue/test-utils": "^2.0.0-rc.16",
|
||||
"autoprefixer": "^10.3.7",
|
||||
"commitizen": "^4.2.4",
|
||||
"conventional-changelog-cli": "^2.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^10.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint": "^8.0.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-define-config": "^1.0.9",
|
||||
"eslint-plugin-jest": "^24.4.0",
|
||||
"eslint-plugin-prettier": "^3.4.1",
|
||||
"eslint-plugin-vue": "^7.16.0",
|
||||
"esno": "^0.9.1",
|
||||
"eslint-define-config": "^1.1.1",
|
||||
"eslint-plugin-jest": "^25.2.2",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^7.19.1",
|
||||
"esno": "^0.10.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"http-server": "^13.0.1",
|
||||
"husky": "^7.0.1",
|
||||
"inquirer": "^8.1.2",
|
||||
"http-server": "^14.0.0",
|
||||
"husky": "^7.0.2",
|
||||
"inquirer": "^8.2.0",
|
||||
"is-ci": "^3.0.0",
|
||||
"jest": "^27.0.6",
|
||||
"less": "^4.1.1",
|
||||
"lint-staged": "^11.1.2",
|
||||
"jest": "^27.3.1",
|
||||
"less": "^4.1.2",
|
||||
"lint-staged": "^11.2.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.3.6",
|
||||
"prettier": "^2.3.2",
|
||||
"postcss": "^8.3.9",
|
||||
"prettier": "^2.4.1",
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup-plugin-visualizer": "5.5.2",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint-config-prettier": "^8.0.2",
|
||||
"stylelint-config-prettier": "^9.0.3",
|
||||
"stylelint-config-standard": "^22.0.0",
|
||||
"stylelint-order": "^4.1.0",
|
||||
"ts-jest": "^27.0.5",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "4.3.5",
|
||||
"vite": "2.5.0",
|
||||
"ts-jest": "^27.0.7",
|
||||
"ts-node": "^10.3.0",
|
||||
"typescript": "^4.4.4",
|
||||
"vite": "^2.6.10",
|
||||
"vite-plugin-compression": "^0.3.5",
|
||||
"vite-plugin-html": "^2.1.0",
|
||||
"vite-plugin-imagemin": "^0.4.5",
|
||||
"vite-plugin-imagemin": "^0.4.6",
|
||||
"vite-plugin-mock": "^2.9.6",
|
||||
"vite-plugin-purge-icons": "^0.7.0",
|
||||
"vite-plugin-pwa": "^0.11.0",
|
||||
"vite-plugin-pwa": "^0.11.3",
|
||||
"vite-plugin-style-import": "^1.2.1",
|
||||
"vite-plugin-svg-icons": "^1.0.4",
|
||||
"vite-plugin-windicss": "^1.2.8",
|
||||
"vite-plugin-svg-icons": "^1.0.5",
|
||||
"vite-plugin-theme": "^0.8.1",
|
||||
"vue-eslint-parser": "^7.10.0",
|
||||
"vue-tsc": "^0.3.0"
|
||||
"vite-plugin-vue-setup-extend": "^0.1.0",
|
||||
"vite-plugin-windicss": "^1.4.12",
|
||||
"vue-eslint-parser": "^8.0.0",
|
||||
"vue-tsc": "^0.28.7"
|
||||
},
|
||||
"resolutions": {
|
||||
"//": "Used to install imagemin dependencies, because imagemin may not be installed in China. If it is abroad, you can delete it",
|
||||
|
@ -165,13 +168,13 @@
|
|||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jeecgboot/jeecg-boot-vue3"
|
||||
"url": "git+https://github.com/jeecgboot/jeecgboot-vue3.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/jeecgboot/jeecg-boot-vue3/issues"
|
||||
"url": "https://github.com/jeecgboot/jeecgboot-vue3/issues"
|
||||
},
|
||||
"homepage": "https://github.com/jeecgboot/jeecg-boot-vue3",
|
||||
"homepage": "https://github.com/jeecgboot/jeecgboot-vue3",
|
||||
"engines": {
|
||||
"node": "^12 || >=14"
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ module.exports = {
|
|||
quoteProps: 'as-needed',
|
||||
bracketSpacing: true,
|
||||
trailingComma: 'es5',
|
||||
jsxBracketSameLine: false,
|
||||
jsxSingleQuote: false,
|
||||
arrowParens: 'always',
|
||||
insertPragma: false,
|
||||
|
|
After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 7.3 KiB |
|
@ -0,0 +1,711 @@
|
|||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
.mce-content-body .mce-item-anchor {
|
||||
background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'8'%20height%3D'12'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20d%3D'M0%200L8%200%208%2012%204.09117821%209%200%2012z'%2F%3E%3C%2Fsvg%3E%0A") no-repeat center;
|
||||
cursor: default;
|
||||
display: inline-block;
|
||||
height: 12px !important;
|
||||
padding: 0 2px;
|
||||
-webkit-user-modify: read-only;
|
||||
-moz-user-modify: read-only;
|
||||
-webkit-user-select: all;
|
||||
-ms-user-select: all;
|
||||
user-select: all;
|
||||
width: 8px !important;
|
||||
}
|
||||
.mce-content-body .mce-item-anchor[data-mce-selected] {
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.tox-comments-visible .tox-comment {
|
||||
background-color: #fff0b7;
|
||||
}
|
||||
.tox-comments-visible .tox-comment--active {
|
||||
background-color: #ffe168;
|
||||
}
|
||||
.tox-checklist > li:not(.tox-checklist--hidden) {
|
||||
list-style: none;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
.tox-checklist > li:not(.tox-checklist--hidden)::before {
|
||||
content: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-unchecked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2215%22%20height%3D%2215%22%20x%3D%22.5%22%20y%3D%22.5%22%20fill-rule%3D%22nonzero%22%20stroke%3D%22%234C4C4C%22%20rx%3D%222%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A");
|
||||
cursor: pointer;
|
||||
height: 1em;
|
||||
margin-left: -1.5em;
|
||||
margin-top: 0.125em;
|
||||
position: absolute;
|
||||
width: 1em;
|
||||
}
|
||||
.tox-checklist li:not(.tox-checklist--hidden).tox-checklist--checked::before {
|
||||
content: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-checked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22%234099FF%22%20fill-rule%3D%22nonzero%22%20rx%3D%222%22%2F%3E%3Cpath%20id%3D%22Path%22%20fill%3D%22%23FFF%22%20fill-rule%3D%22nonzero%22%20d%3D%22M11.5703186%2C3.14417309%20C11.8516238%2C2.73724603%2012.4164781%2C2.62829933%2012.83558%2C2.89774797%20C13.260121%2C3.17069355%2013.3759736%2C3.72932262%2013.0909105%2C4.14168582%20L7.7580587%2C11.8560195%20C7.43776896%2C12.3193404%206.76483983%2C12.3852142%206.35607322%2C11.9948725%20L3.02491697%2C8.8138662%20C2.66090143%2C8.46625845%202.65798871%2C7.89594698%203.01850234%2C7.54483354%20C3.373942%2C7.19866177%203.94940006%2C7.19592841%204.30829608%2C7.5386474%20L6.85276923%2C9.9684299%20L11.5703186%2C3.14417309%20Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A");
|
||||
}
|
||||
[dir=rtl] .tox-checklist > li:not(.tox-checklist--hidden)::before {
|
||||
margin-left: 0;
|
||||
margin-right: -1.5em;
|
||||
}
|
||||
/* stylelint-disable */
|
||||
/* http://prismjs.com/ */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
font-size: 1em;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
-moz-tab-size: 4;
|
||||
tab-size: 4;
|
||||
-webkit-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
@media print {
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: 0.5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: 0.1em;
|
||||
border-radius: 0.3em;
|
||||
white-space: normal;
|
||||
}
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
.namespace {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, 0.5);
|
||||
}
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
/* stylelint-enable */
|
||||
.mce-content-body {
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.mce-content-body .mce-visual-caret {
|
||||
background-color: black;
|
||||
background-color: currentColor;
|
||||
position: absolute;
|
||||
}
|
||||
.mce-content-body .mce-visual-caret-hidden {
|
||||
display: none;
|
||||
}
|
||||
.mce-content-body *[data-mce-caret] {
|
||||
left: -1000px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
right: auto;
|
||||
top: 0;
|
||||
}
|
||||
.mce-content-body .mce-offscreen-selection {
|
||||
left: -2000000px;
|
||||
max-width: 1000000px;
|
||||
position: absolute;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false] {
|
||||
cursor: default;
|
||||
}
|
||||
.mce-content-body *[contentEditable=true] {
|
||||
cursor: text;
|
||||
}
|
||||
.tox-cursor-format-painter {
|
||||
cursor: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%0A%20%20%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M15%2C6%20C15%2C5.45%2014.55%2C5%2014%2C5%20L6%2C5%20C5.45%2C5%205%2C5.45%205%2C6%20L5%2C10%20C5%2C10.55%205.45%2C11%206%2C11%20L14%2C11%20C14.55%2C11%2015%2C10.55%2015%2C10%20L15%2C9%20L16%2C9%20L16%2C12%20L9%2C12%20L9%2C19%20C9%2C19.55%209.45%2C20%2010%2C20%20L11%2C20%20C11.55%2C20%2012%2C19.55%2012%2C19%20L12%2C14%20L18%2C14%20L18%2C7%20L15%2C7%20L15%2C6%20Z%22%2F%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M1%2C1%20L8.25%2C1%20C8.66421356%2C1%209%2C1.33578644%209%2C1.75%20L9%2C1.75%20C9%2C2.16421356%208.66421356%2C2.5%208.25%2C2.5%20L2.5%2C2.5%20L2.5%2C8.25%20C2.5%2C8.66421356%202.16421356%2C9%201.75%2C9%20L1.75%2C9%20C1.33578644%2C9%201%2C8.66421356%201%2C8.25%20L1%2C1%20Z%22%2F%3E%0A%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A"), default;
|
||||
}
|
||||
.mce-content-body figure.align-left {
|
||||
float: left;
|
||||
}
|
||||
.mce-content-body figure.align-right {
|
||||
float: right;
|
||||
}
|
||||
.mce-content-body figure.image.align-center {
|
||||
display: table;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.mce-preview-object {
|
||||
border: 1px solid gray;
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
margin: 0 2px 0 2px;
|
||||
position: relative;
|
||||
}
|
||||
.mce-preview-object .mce-shim {
|
||||
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.mce-preview-object[data-mce-selected="2"] .mce-shim {
|
||||
display: none;
|
||||
}
|
||||
.mce-object {
|
||||
background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20d%3D%22M4%203h16a1%201%200%200%201%201%201v16a1%201%200%200%201-1%201H4a1%201%200%200%201-1-1V4a1%201%200%200%201%201-1zm1%202v14h14V5H5zm4.79%202.565l5.64%204.028a.5.5%200%200%201%200%20.814l-5.64%204.028a.5.5%200%200%201-.79-.407V7.972a.5.5%200%200%201%20.79-.407z%22%2F%3E%3C%2Fsvg%3E%0A") no-repeat center;
|
||||
border: 1px dashed #aaa;
|
||||
}
|
||||
.mce-pagebreak {
|
||||
border: 1px dashed #aaa;
|
||||
cursor: default;
|
||||
display: block;
|
||||
height: 5px;
|
||||
margin-top: 15px;
|
||||
page-break-before: always;
|
||||
width: 100%;
|
||||
}
|
||||
@media print {
|
||||
.mce-pagebreak {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
.tiny-pageembed .mce-shim {
|
||||
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.tiny-pageembed[data-mce-selected="2"] .mce-shim {
|
||||
display: none;
|
||||
}
|
||||
.tiny-pageembed {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
.tiny-pageembed--21by9,
|
||||
.tiny-pageembed--16by9,
|
||||
.tiny-pageembed--4by3,
|
||||
.tiny-pageembed--1by1 {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.tiny-pageembed--21by9 {
|
||||
padding-top: 42.857143%;
|
||||
}
|
||||
.tiny-pageembed--16by9 {
|
||||
padding-top: 56.25%;
|
||||
}
|
||||
.tiny-pageembed--4by3 {
|
||||
padding-top: 75%;
|
||||
}
|
||||
.tiny-pageembed--1by1 {
|
||||
padding-top: 100%;
|
||||
}
|
||||
.tiny-pageembed--21by9 iframe,
|
||||
.tiny-pageembed--16by9 iframe,
|
||||
.tiny-pageembed--4by3 iframe,
|
||||
.tiny-pageembed--1by1 iframe {
|
||||
border: 0;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.mce-content-body[data-mce-placeholder] {
|
||||
position: relative;
|
||||
}
|
||||
.mce-content-body[data-mce-placeholder]:not(.mce-visualblocks)::before {
|
||||
color: rgba(84, 111, 94, 0.7);
|
||||
content: attr(data-mce-placeholder);
|
||||
position: absolute;
|
||||
}
|
||||
.mce-content-body:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before {
|
||||
left: 1px;
|
||||
}
|
||||
.mce-content-body[dir=rtl][data-mce-placeholder]:not(.mce-visualblocks)::before {
|
||||
right: 1px;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle {
|
||||
background-color: #4099ff;
|
||||
border-color: #4099ff;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
box-sizing: border-box;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
z-index: 10000;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:hover {
|
||||
background-color: #4099ff;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(1) {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(2) {
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(3) {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(4) {
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
.mce-content-body .mce-resize-backdrop {
|
||||
z-index: 10000;
|
||||
}
|
||||
.mce-content-body .mce-clonedresizable {
|
||||
cursor: default;
|
||||
opacity: 0.5;
|
||||
outline: 1px dashed black;
|
||||
position: absolute;
|
||||
z-index: 10001;
|
||||
}
|
||||
.mce-content-body .mce-clonedresizable.mce-resizetable-columns th,
|
||||
.mce-content-body .mce-clonedresizable.mce-resizetable-columns td {
|
||||
border: 0;
|
||||
}
|
||||
.mce-content-body .mce-resize-helper {
|
||||
background: #555;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
border: 1px;
|
||||
border-radius: 3px;
|
||||
color: white;
|
||||
display: none;
|
||||
font-family: sans-serif;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
margin: 5px 10px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 10002;
|
||||
}
|
||||
.tox-rtc-user-selection {
|
||||
position: relative;
|
||||
}
|
||||
.tox-rtc-user-cursor {
|
||||
bottom: 0;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 2px;
|
||||
}
|
||||
.tox-rtc-user-cursor::before {
|
||||
background-color: inherit;
|
||||
border-radius: 50%;
|
||||
content: '';
|
||||
display: block;
|
||||
height: 8px;
|
||||
position: absolute;
|
||||
right: -3px;
|
||||
top: -3px;
|
||||
width: 8px;
|
||||
}
|
||||
.tox-rtc-user-cursor:hover::after {
|
||||
background-color: inherit;
|
||||
border-radius: 100px;
|
||||
box-sizing: border-box;
|
||||
color: #fff;
|
||||
content: attr(data-user);
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
left: -5px;
|
||||
min-height: 8px;
|
||||
min-width: 8px;
|
||||
padding: 0 12px;
|
||||
position: absolute;
|
||||
top: -11px;
|
||||
white-space: nowrap;
|
||||
z-index: 1000;
|
||||
}
|
||||
.tox-rtc-user-selection--1 .tox-rtc-user-cursor {
|
||||
background-color: #2dc26b;
|
||||
}
|
||||
.tox-rtc-user-selection--2 .tox-rtc-user-cursor {
|
||||
background-color: #e03e2d;
|
||||
}
|
||||
.tox-rtc-user-selection--3 .tox-rtc-user-cursor {
|
||||
background-color: #f1c40f;
|
||||
}
|
||||
.tox-rtc-user-selection--4 .tox-rtc-user-cursor {
|
||||
background-color: #3598db;
|
||||
}
|
||||
.tox-rtc-user-selection--5 .tox-rtc-user-cursor {
|
||||
background-color: #b96ad9;
|
||||
}
|
||||
.tox-rtc-user-selection--6 .tox-rtc-user-cursor {
|
||||
background-color: #e67e23;
|
||||
}
|
||||
.tox-rtc-user-selection--7 .tox-rtc-user-cursor {
|
||||
background-color: #aaa69d;
|
||||
}
|
||||
.tox-rtc-user-selection--8 .tox-rtc-user-cursor {
|
||||
background-color: #f368e0;
|
||||
}
|
||||
.tox-rtc-remote-image {
|
||||
background: #eaeaea url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2236%22%20height%3D%2212%22%20viewBox%3D%220%200%2036%2012%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Ccircle%20cx%3D%226%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%20%20%3Ccircle%20cx%3D%2218%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20begin%3D%22.33s%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%20%20%3Ccircle%20cx%3D%2230%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20begin%3D%22.66s%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%3C%2Fsvg%3E%0A") no-repeat center center;
|
||||
border: 1px solid #ccc;
|
||||
min-height: 240px;
|
||||
min-width: 320px;
|
||||
}
|
||||
.mce-match-marker {
|
||||
background: #aaa;
|
||||
color: #fff;
|
||||
}
|
||||
.mce-match-marker-selected {
|
||||
background: #39f;
|
||||
color: #fff;
|
||||
}
|
||||
.mce-match-marker-selected::selection {
|
||||
background: #39f;
|
||||
color: #fff;
|
||||
}
|
||||
.mce-content-body img[data-mce-selected],
|
||||
.mce-content-body video[data-mce-selected],
|
||||
.mce-content-body audio[data-mce-selected],
|
||||
.mce-content-body object[data-mce-selected],
|
||||
.mce-content-body embed[data-mce-selected],
|
||||
.mce-content-body table[data-mce-selected] {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body hr[data-mce-selected] {
|
||||
outline: 3px solid #b4d7ff;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false][data-mce-selected] {
|
||||
cursor: not-allowed;
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,
|
||||
.mce-content-body.mce-content-readonly *[contentEditable=true]:hover {
|
||||
outline: none;
|
||||
}
|
||||
.mce-content-body *[data-mce-selected="inline-boundary"] {
|
||||
background-color: #b4d7ff;
|
||||
}
|
||||
.mce-content-body .mce-edit-focus {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected],
|
||||
.mce-content-body th[data-mce-selected] {
|
||||
position: relative;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected]::selection,
|
||||
.mce-content-body th[data-mce-selected]::selection {
|
||||
background: none;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected] *,
|
||||
.mce-content-body th[data-mce-selected] * {
|
||||
outline: none;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected]::after,
|
||||
.mce-content-body th[data-mce-selected]::after {
|
||||
background-color: rgba(180, 215, 255, 0.7);
|
||||
border: 1px solid rgba(180, 215, 255, 0.7);
|
||||
bottom: -1px;
|
||||
content: '';
|
||||
left: -1px;
|
||||
mix-blend-mode: multiply;
|
||||
position: absolute;
|
||||
right: -1px;
|
||||
top: -1px;
|
||||
}
|
||||
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||
.mce-content-body td[data-mce-selected]::after,
|
||||
.mce-content-body th[data-mce-selected]::after {
|
||||
border-color: rgba(0, 84, 180, 0.7);
|
||||
}
|
||||
}
|
||||
.mce-content-body img::selection {
|
||||
background: none;
|
||||
}
|
||||
.ephox-snooker-resizer-bar {
|
||||
background-color: #b4d7ff;
|
||||
opacity: 0;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.ephox-snooker-resizer-cols {
|
||||
cursor: col-resize;
|
||||
}
|
||||
.ephox-snooker-resizer-rows {
|
||||
cursor: row-resize;
|
||||
}
|
||||
.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging {
|
||||
opacity: 1;
|
||||
}
|
||||
.mce-spellchecker-word {
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23ff0000'%20fill%3D'none'%20stroke-linecap%3D'round'%20stroke-opacity%3D'.75'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A");
|
||||
background-position: 0 calc(100% + 1px);
|
||||
background-repeat: repeat-x;
|
||||
background-size: auto 6px;
|
||||
cursor: default;
|
||||
height: 2rem;
|
||||
}
|
||||
.mce-spellchecker-grammar {
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%2300A835'%20fill%3D'none'%20stroke-linecap%3D'round'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A");
|
||||
background-position: 0 calc(100% + 1px);
|
||||
background-repeat: repeat-x;
|
||||
background-size: auto 6px;
|
||||
cursor: default;
|
||||
}
|
||||
.mce-toc {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
.mce-toc h2 {
|
||||
margin: 4px;
|
||||
}
|
||||
.mce-toc li {
|
||||
list-style-type: none;
|
||||
}
|
||||
table[style*="border-width: 0px"],
|
||||
.mce-item-table:not([border]),
|
||||
.mce-item-table[border="0"],
|
||||
table[style*="border-width: 0px"] td,
|
||||
.mce-item-table:not([border]) td,
|
||||
.mce-item-table[border="0"] td,
|
||||
table[style*="border-width: 0px"] th,
|
||||
.mce-item-table:not([border]) th,
|
||||
.mce-item-table[border="0"] th,
|
||||
table[style*="border-width: 0px"] caption,
|
||||
.mce-item-table:not([border]) caption,
|
||||
.mce-item-table[border="0"] caption {
|
||||
border: 1px dashed #bbb;
|
||||
}
|
||||
.mce-visualblocks p,
|
||||
.mce-visualblocks h1,
|
||||
.mce-visualblocks h2,
|
||||
.mce-visualblocks h3,
|
||||
.mce-visualblocks h4,
|
||||
.mce-visualblocks h5,
|
||||
.mce-visualblocks h6,
|
||||
.mce-visualblocks div:not([data-mce-bogus]),
|
||||
.mce-visualblocks section,
|
||||
.mce-visualblocks article,
|
||||
.mce-visualblocks blockquote,
|
||||
.mce-visualblocks address,
|
||||
.mce-visualblocks pre,
|
||||
.mce-visualblocks figure,
|
||||
.mce-visualblocks figcaption,
|
||||
.mce-visualblocks hgroup,
|
||||
.mce-visualblocks aside,
|
||||
.mce-visualblocks ul,
|
||||
.mce-visualblocks ol,
|
||||
.mce-visualblocks dl {
|
||||
background-repeat: no-repeat;
|
||||
border: 1px dashed #bbb;
|
||||
margin-left: 3px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.mce-visualblocks p {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7);
|
||||
}
|
||||
.mce-visualblocks h1 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==);
|
||||
}
|
||||
.mce-visualblocks h2 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==);
|
||||
}
|
||||
.mce-visualblocks h3 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7);
|
||||
}
|
||||
.mce-visualblocks h4 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==);
|
||||
}
|
||||
.mce-visualblocks h5 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==);
|
||||
}
|
||||
.mce-visualblocks h6 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==);
|
||||
}
|
||||
.mce-visualblocks div:not([data-mce-bogus]) {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7);
|
||||
}
|
||||
.mce-visualblocks section {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=);
|
||||
}
|
||||
.mce-visualblocks article {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7);
|
||||
}
|
||||
.mce-visualblocks blockquote {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7);
|
||||
}
|
||||
.mce-visualblocks address {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=);
|
||||
}
|
||||
.mce-visualblocks pre {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==);
|
||||
}
|
||||
.mce-visualblocks figure {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7);
|
||||
}
|
||||
.mce-visualblocks figcaption {
|
||||
border: 1px dashed #bbb;
|
||||
}
|
||||
.mce-visualblocks hgroup {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7);
|
||||
}
|
||||
.mce-visualblocks aside {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=);
|
||||
}
|
||||
.mce-visualblocks ul {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==);
|
||||
}
|
||||
.mce-visualblocks ol {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==);
|
||||
}
|
||||
.mce-visualblocks dl {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybEOnmOvUoWznTqeuEjNSCqeGRUAOw==);
|
||||
}
|
||||
.mce-visualblocks:not([dir=rtl]) p,
|
||||
.mce-visualblocks:not([dir=rtl]) h1,
|
||||
.mce-visualblocks:not([dir=rtl]) h2,
|
||||
.mce-visualblocks:not([dir=rtl]) h3,
|
||||
.mce-visualblocks:not([dir=rtl]) h4,
|
||||
.mce-visualblocks:not([dir=rtl]) h5,
|
||||
.mce-visualblocks:not([dir=rtl]) h6,
|
||||
.mce-visualblocks:not([dir=rtl]) div:not([data-mce-bogus]),
|
||||
.mce-visualblocks:not([dir=rtl]) section,
|
||||
.mce-visualblocks:not([dir=rtl]) article,
|
||||
.mce-visualblocks:not([dir=rtl]) blockquote,
|
||||
.mce-visualblocks:not([dir=rtl]) address,
|
||||
.mce-visualblocks:not([dir=rtl]) pre,
|
||||
.mce-visualblocks:not([dir=rtl]) figure,
|
||||
.mce-visualblocks:not([dir=rtl]) figcaption,
|
||||
.mce-visualblocks:not([dir=rtl]) hgroup,
|
||||
.mce-visualblocks:not([dir=rtl]) aside,
|
||||
.mce-visualblocks:not([dir=rtl]) ul,
|
||||
.mce-visualblocks:not([dir=rtl]) ol,
|
||||
.mce-visualblocks:not([dir=rtl]) dl {
|
||||
margin-left: 3px;
|
||||
}
|
||||
.mce-visualblocks[dir=rtl] p,
|
||||
.mce-visualblocks[dir=rtl] h1,
|
||||
.mce-visualblocks[dir=rtl] h2,
|
||||
.mce-visualblocks[dir=rtl] h3,
|
||||
.mce-visualblocks[dir=rtl] h4,
|
||||
.mce-visualblocks[dir=rtl] h5,
|
||||
.mce-visualblocks[dir=rtl] h6,
|
||||
.mce-visualblocks[dir=rtl] div:not([data-mce-bogus]),
|
||||
.mce-visualblocks[dir=rtl] section,
|
||||
.mce-visualblocks[dir=rtl] article,
|
||||
.mce-visualblocks[dir=rtl] blockquote,
|
||||
.mce-visualblocks[dir=rtl] address,
|
||||
.mce-visualblocks[dir=rtl] pre,
|
||||
.mce-visualblocks[dir=rtl] figure,
|
||||
.mce-visualblocks[dir=rtl] figcaption,
|
||||
.mce-visualblocks[dir=rtl] hgroup,
|
||||
.mce-visualblocks[dir=rtl] aside,
|
||||
.mce-visualblocks[dir=rtl] ul,
|
||||
.mce-visualblocks[dir=rtl] ol,
|
||||
.mce-visualblocks[dir=rtl] dl {
|
||||
background-position-x: right;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.mce-nbsp,
|
||||
.mce-shy {
|
||||
background: #aaa;
|
||||
}
|
||||
.mce-shy::after {
|
||||
content: '-';
|
||||
}
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
|
@ -0,0 +1,705 @@
|
|||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
.mce-content-body .mce-item-anchor {
|
||||
background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'8'%20height%3D'12'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20d%3D'M0%200L8%200%208%2012%204.09117821%209%200%2012z'%2F%3E%3C%2Fsvg%3E%0A") no-repeat center;
|
||||
cursor: default;
|
||||
display: inline-block;
|
||||
height: 12px !important;
|
||||
padding: 0 2px;
|
||||
-webkit-user-modify: read-only;
|
||||
-moz-user-modify: read-only;
|
||||
-webkit-user-select: all;
|
||||
-ms-user-select: all;
|
||||
user-select: all;
|
||||
width: 8px !important;
|
||||
}
|
||||
.mce-content-body .mce-item-anchor[data-mce-selected] {
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.tox-comments-visible .tox-comment {
|
||||
background-color: #fff0b7;
|
||||
}
|
||||
.tox-comments-visible .tox-comment--active {
|
||||
background-color: #ffe168;
|
||||
}
|
||||
.tox-checklist > li:not(.tox-checklist--hidden) {
|
||||
list-style: none;
|
||||
margin: 0.25em 0;
|
||||
}
|
||||
.tox-checklist > li:not(.tox-checklist--hidden)::before {
|
||||
content: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-unchecked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2215%22%20height%3D%2215%22%20x%3D%22.5%22%20y%3D%22.5%22%20fill-rule%3D%22nonzero%22%20stroke%3D%22%234C4C4C%22%20rx%3D%222%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A");
|
||||
cursor: pointer;
|
||||
height: 1em;
|
||||
margin-left: -1.5em;
|
||||
margin-top: 0.125em;
|
||||
position: absolute;
|
||||
width: 1em;
|
||||
}
|
||||
.tox-checklist li:not(.tox-checklist--hidden).tox-checklist--checked::before {
|
||||
content: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-checked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22%234099FF%22%20fill-rule%3D%22nonzero%22%20rx%3D%222%22%2F%3E%3Cpath%20id%3D%22Path%22%20fill%3D%22%23FFF%22%20fill-rule%3D%22nonzero%22%20d%3D%22M11.5703186%2C3.14417309%20C11.8516238%2C2.73724603%2012.4164781%2C2.62829933%2012.83558%2C2.89774797%20C13.260121%2C3.17069355%2013.3759736%2C3.72932262%2013.0909105%2C4.14168582%20L7.7580587%2C11.8560195%20C7.43776896%2C12.3193404%206.76483983%2C12.3852142%206.35607322%2C11.9948725%20L3.02491697%2C8.8138662%20C2.66090143%2C8.46625845%202.65798871%2C7.89594698%203.01850234%2C7.54483354%20C3.373942%2C7.19866177%203.94940006%2C7.19592841%204.30829608%2C7.5386474%20L6.85276923%2C9.9684299%20L11.5703186%2C3.14417309%20Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A");
|
||||
}
|
||||
[dir=rtl] .tox-checklist > li:not(.tox-checklist--hidden)::before {
|
||||
margin-left: 0;
|
||||
margin-right: -1.5em;
|
||||
}
|
||||
/* stylelint-disable */
|
||||
/* http://prismjs.com/ */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
font-size: 1em;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
-moz-tab-size: 4;
|
||||
tab-size: 4;
|
||||
-webkit-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
@media print {
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: 0.5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: 0.1em;
|
||||
border-radius: 0.3em;
|
||||
white-space: normal;
|
||||
}
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
.namespace {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, 0.5);
|
||||
}
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
/* stylelint-enable */
|
||||
.mce-content-body {
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.mce-content-body .mce-visual-caret {
|
||||
background-color: black;
|
||||
background-color: currentColor;
|
||||
position: absolute;
|
||||
}
|
||||
.mce-content-body .mce-visual-caret-hidden {
|
||||
display: none;
|
||||
}
|
||||
.mce-content-body *[data-mce-caret] {
|
||||
left: -1000px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
right: auto;
|
||||
top: 0;
|
||||
}
|
||||
.mce-content-body .mce-offscreen-selection {
|
||||
left: -2000000px;
|
||||
max-width: 1000000px;
|
||||
position: absolute;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false] {
|
||||
cursor: default;
|
||||
}
|
||||
.mce-content-body *[contentEditable=true] {
|
||||
cursor: text;
|
||||
}
|
||||
.tox-cursor-format-painter {
|
||||
cursor: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%0A%20%20%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M15%2C6%20C15%2C5.45%2014.55%2C5%2014%2C5%20L6%2C5%20C5.45%2C5%205%2C5.45%205%2C6%20L5%2C10%20C5%2C10.55%205.45%2C11%206%2C11%20L14%2C11%20C14.55%2C11%2015%2C10.55%2015%2C10%20L15%2C9%20L16%2C9%20L16%2C12%20L9%2C12%20L9%2C19%20C9%2C19.55%209.45%2C20%2010%2C20%20L11%2C20%20C11.55%2C20%2012%2C19.55%2012%2C19%20L12%2C14%20L18%2C14%20L18%2C7%20L15%2C7%20L15%2C6%20Z%22%2F%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M1%2C1%20L8.25%2C1%20C8.66421356%2C1%209%2C1.33578644%209%2C1.75%20L9%2C1.75%20C9%2C2.16421356%208.66421356%2C2.5%208.25%2C2.5%20L2.5%2C2.5%20L2.5%2C8.25%20C2.5%2C8.66421356%202.16421356%2C9%201.75%2C9%20L1.75%2C9%20C1.33578644%2C9%201%2C8.66421356%201%2C8.25%20L1%2C1%20Z%22%2F%3E%0A%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A"), default;
|
||||
}
|
||||
.mce-content-body figure.align-left {
|
||||
float: left;
|
||||
}
|
||||
.mce-content-body figure.align-right {
|
||||
float: right;
|
||||
}
|
||||
.mce-content-body figure.image.align-center {
|
||||
display: table;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.mce-preview-object {
|
||||
border: 1px solid gray;
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
margin: 0 2px 0 2px;
|
||||
position: relative;
|
||||
}
|
||||
.mce-preview-object .mce-shim {
|
||||
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.mce-preview-object[data-mce-selected="2"] .mce-shim {
|
||||
display: none;
|
||||
}
|
||||
.mce-object {
|
||||
background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20d%3D%22M4%203h16a1%201%200%200%201%201%201v16a1%201%200%200%201-1%201H4a1%201%200%200%201-1-1V4a1%201%200%200%201%201-1zm1%202v14h14V5H5zm4.79%202.565l5.64%204.028a.5.5%200%200%201%200%20.814l-5.64%204.028a.5.5%200%200%201-.79-.407V7.972a.5.5%200%200%201%20.79-.407z%22%2F%3E%3C%2Fsvg%3E%0A") no-repeat center;
|
||||
border: 1px dashed #aaa;
|
||||
}
|
||||
.mce-pagebreak {
|
||||
border: 1px dashed #aaa;
|
||||
cursor: default;
|
||||
display: block;
|
||||
height: 5px;
|
||||
margin-top: 15px;
|
||||
page-break-before: always;
|
||||
width: 100%;
|
||||
}
|
||||
@media print {
|
||||
.mce-pagebreak {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
.tiny-pageembed .mce-shim {
|
||||
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.tiny-pageembed[data-mce-selected="2"] .mce-shim {
|
||||
display: none;
|
||||
}
|
||||
.tiny-pageembed {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
.tiny-pageembed--21by9,
|
||||
.tiny-pageembed--16by9,
|
||||
.tiny-pageembed--4by3,
|
||||
.tiny-pageembed--1by1 {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.tiny-pageembed--21by9 {
|
||||
padding-top: 42.857143%;
|
||||
}
|
||||
.tiny-pageembed--16by9 {
|
||||
padding-top: 56.25%;
|
||||
}
|
||||
.tiny-pageembed--4by3 {
|
||||
padding-top: 75%;
|
||||
}
|
||||
.tiny-pageembed--1by1 {
|
||||
padding-top: 100%;
|
||||
}
|
||||
.tiny-pageembed--21by9 iframe,
|
||||
.tiny-pageembed--16by9 iframe,
|
||||
.tiny-pageembed--4by3 iframe,
|
||||
.tiny-pageembed--1by1 iframe {
|
||||
border: 0;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.mce-content-body[data-mce-placeholder] {
|
||||
position: relative;
|
||||
}
|
||||
.mce-content-body[data-mce-placeholder]:not(.mce-visualblocks)::before {
|
||||
color: rgba(84, 111, 94, 0.7);
|
||||
content: attr(data-mce-placeholder);
|
||||
position: absolute;
|
||||
}
|
||||
.mce-content-body:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before {
|
||||
left: 1px;
|
||||
}
|
||||
.mce-content-body[dir=rtl][data-mce-placeholder]:not(.mce-visualblocks)::before {
|
||||
right: 1px;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle {
|
||||
background-color: #4099ff;
|
||||
border-color: #4099ff;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
box-sizing: border-box;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
z-index: 10000;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:hover {
|
||||
background-color: #4099ff;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(1) {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(2) {
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(3) {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
.mce-content-body div.mce-resizehandle:nth-of-type(4) {
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
.mce-content-body .mce-resize-backdrop {
|
||||
z-index: 10000;
|
||||
}
|
||||
.mce-content-body .mce-clonedresizable {
|
||||
cursor: default;
|
||||
opacity: 0.5;
|
||||
outline: 1px dashed black;
|
||||
position: absolute;
|
||||
z-index: 10001;
|
||||
}
|
||||
.mce-content-body .mce-clonedresizable.mce-resizetable-columns th,
|
||||
.mce-content-body .mce-clonedresizable.mce-resizetable-columns td {
|
||||
border: 0;
|
||||
}
|
||||
.mce-content-body .mce-resize-helper {
|
||||
background: #555;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
border: 1px;
|
||||
border-radius: 3px;
|
||||
color: white;
|
||||
display: none;
|
||||
font-family: sans-serif;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
margin: 5px 10px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 10002;
|
||||
}
|
||||
.tox-rtc-user-selection {
|
||||
position: relative;
|
||||
}
|
||||
.tox-rtc-user-cursor {
|
||||
bottom: 0;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 2px;
|
||||
}
|
||||
.tox-rtc-user-cursor::before {
|
||||
background-color: inherit;
|
||||
border-radius: 50%;
|
||||
content: '';
|
||||
display: block;
|
||||
height: 8px;
|
||||
position: absolute;
|
||||
right: -3px;
|
||||
top: -3px;
|
||||
width: 8px;
|
||||
}
|
||||
.tox-rtc-user-cursor:hover::after {
|
||||
background-color: inherit;
|
||||
border-radius: 100px;
|
||||
box-sizing: border-box;
|
||||
color: #fff;
|
||||
content: attr(data-user);
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
left: -5px;
|
||||
min-height: 8px;
|
||||
min-width: 8px;
|
||||
padding: 0 12px;
|
||||
position: absolute;
|
||||
top: -11px;
|
||||
white-space: nowrap;
|
||||
z-index: 1000;
|
||||
}
|
||||
.tox-rtc-user-selection--1 .tox-rtc-user-cursor {
|
||||
background-color: #2dc26b;
|
||||
}
|
||||
.tox-rtc-user-selection--2 .tox-rtc-user-cursor {
|
||||
background-color: #e03e2d;
|
||||
}
|
||||
.tox-rtc-user-selection--3 .tox-rtc-user-cursor {
|
||||
background-color: #f1c40f;
|
||||
}
|
||||
.tox-rtc-user-selection--4 .tox-rtc-user-cursor {
|
||||
background-color: #3598db;
|
||||
}
|
||||
.tox-rtc-user-selection--5 .tox-rtc-user-cursor {
|
||||
background-color: #b96ad9;
|
||||
}
|
||||
.tox-rtc-user-selection--6 .tox-rtc-user-cursor {
|
||||
background-color: #e67e23;
|
||||
}
|
||||
.tox-rtc-user-selection--7 .tox-rtc-user-cursor {
|
||||
background-color: #aaa69d;
|
||||
}
|
||||
.tox-rtc-user-selection--8 .tox-rtc-user-cursor {
|
||||
background-color: #f368e0;
|
||||
}
|
||||
.tox-rtc-remote-image {
|
||||
background: #eaeaea url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2236%22%20height%3D%2212%22%20viewBox%3D%220%200%2036%2012%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Ccircle%20cx%3D%226%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%20%20%3Ccircle%20cx%3D%2218%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20begin%3D%22.33s%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%20%20%3Ccircle%20cx%3D%2230%22%20cy%3D%226%22%20r%3D%223%22%20fill%3D%22rgba(0%2C%200%2C%200%2C%20.2)%22%3E%0A%20%20%20%20%3Canimate%20attributeName%3D%22r%22%20values%3D%223%3B5%3B3%22%20calcMode%3D%22linear%22%20begin%3D%22.66s%22%20dur%3D%221s%22%20repeatCount%3D%22indefinite%22%20%2F%3E%0A%20%20%3C%2Fcircle%3E%0A%3C%2Fsvg%3E%0A") no-repeat center center;
|
||||
border: 1px solid #ccc;
|
||||
min-height: 240px;
|
||||
min-width: 320px;
|
||||
}
|
||||
.mce-match-marker {
|
||||
background: #aaa;
|
||||
color: #fff;
|
||||
}
|
||||
.mce-match-marker-selected {
|
||||
background: #39f;
|
||||
color: #fff;
|
||||
}
|
||||
.mce-match-marker-selected::selection {
|
||||
background: #39f;
|
||||
color: #fff;
|
||||
}
|
||||
.mce-content-body img[data-mce-selected],
|
||||
.mce-content-body video[data-mce-selected],
|
||||
.mce-content-body audio[data-mce-selected],
|
||||
.mce-content-body object[data-mce-selected],
|
||||
.mce-content-body embed[data-mce-selected],
|
||||
.mce-content-body table[data-mce-selected] {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body hr[data-mce-selected] {
|
||||
outline: 3px solid #b4d7ff;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body *[contentEditable=false][data-mce-selected] {
|
||||
cursor: not-allowed;
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,
|
||||
.mce-content-body.mce-content-readonly *[contentEditable=true]:hover {
|
||||
outline: none;
|
||||
}
|
||||
.mce-content-body *[data-mce-selected="inline-boundary"] {
|
||||
background-color: #b4d7ff;
|
||||
}
|
||||
.mce-content-body .mce-edit-focus {
|
||||
outline: 3px solid #b4d7ff;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected],
|
||||
.mce-content-body th[data-mce-selected] {
|
||||
position: relative;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected]::selection,
|
||||
.mce-content-body th[data-mce-selected]::selection {
|
||||
background: none;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected] *,
|
||||
.mce-content-body th[data-mce-selected] * {
|
||||
outline: none;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.mce-content-body td[data-mce-selected]::after,
|
||||
.mce-content-body th[data-mce-selected]::after {
|
||||
background-color: rgba(180, 215, 255, 0.7);
|
||||
border: 1px solid rgba(180, 215, 255, 0.7);
|
||||
bottom: -1px;
|
||||
content: '';
|
||||
left: -1px;
|
||||
mix-blend-mode: multiply;
|
||||
position: absolute;
|
||||
right: -1px;
|
||||
top: -1px;
|
||||
}
|
||||
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||
.mce-content-body td[data-mce-selected]::after,
|
||||
.mce-content-body th[data-mce-selected]::after {
|
||||
border-color: rgba(0, 84, 180, 0.7);
|
||||
}
|
||||
}
|
||||
.mce-content-body img::selection {
|
||||
background: none;
|
||||
}
|
||||
.ephox-snooker-resizer-bar {
|
||||
background-color: #b4d7ff;
|
||||
opacity: 0;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.ephox-snooker-resizer-cols {
|
||||
cursor: col-resize;
|
||||
}
|
||||
.ephox-snooker-resizer-rows {
|
||||
cursor: row-resize;
|
||||
}
|
||||
.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging {
|
||||
opacity: 1;
|
||||
}
|
||||
.mce-spellchecker-word {
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23ff0000'%20fill%3D'none'%20stroke-linecap%3D'round'%20stroke-opacity%3D'.75'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A");
|
||||
background-position: 0 calc(100% + 1px);
|
||||
background-repeat: repeat-x;
|
||||
background-size: auto 6px;
|
||||
cursor: default;
|
||||
height: 2rem;
|
||||
}
|
||||
.mce-spellchecker-grammar {
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%2300A835'%20fill%3D'none'%20stroke-linecap%3D'round'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A");
|
||||
background-position: 0 calc(100% + 1px);
|
||||
background-repeat: repeat-x;
|
||||
background-size: auto 6px;
|
||||
cursor: default;
|
||||
}
|
||||
.mce-toc {
|
||||
border: 1px solid gray;
|
||||
}
|
||||
.mce-toc h2 {
|
||||
margin: 4px;
|
||||
}
|
||||
.mce-toc li {
|
||||
list-style-type: none;
|
||||
}
|
||||
table[style*="border-width: 0px"],
|
||||
.mce-item-table:not([border]),
|
||||
.mce-item-table[border="0"],
|
||||
table[style*="border-width: 0px"] td,
|
||||
.mce-item-table:not([border]) td,
|
||||
.mce-item-table[border="0"] td,
|
||||
table[style*="border-width: 0px"] th,
|
||||
.mce-item-table:not([border]) th,
|
||||
.mce-item-table[border="0"] th,
|
||||
table[style*="border-width: 0px"] caption,
|
||||
.mce-item-table:not([border]) caption,
|
||||
.mce-item-table[border="0"] caption {
|
||||
border: 1px dashed #bbb;
|
||||
}
|
||||
.mce-visualblocks p,
|
||||
.mce-visualblocks h1,
|
||||
.mce-visualblocks h2,
|
||||
.mce-visualblocks h3,
|
||||
.mce-visualblocks h4,
|
||||
.mce-visualblocks h5,
|
||||
.mce-visualblocks h6,
|
||||
.mce-visualblocks div:not([data-mce-bogus]),
|
||||
.mce-visualblocks section,
|
||||
.mce-visualblocks article,
|
||||
.mce-visualblocks blockquote,
|
||||
.mce-visualblocks address,
|
||||
.mce-visualblocks pre,
|
||||
.mce-visualblocks figure,
|
||||
.mce-visualblocks figcaption,
|
||||
.mce-visualblocks hgroup,
|
||||
.mce-visualblocks aside,
|
||||
.mce-visualblocks ul,
|
||||
.mce-visualblocks ol,
|
||||
.mce-visualblocks dl {
|
||||
background-repeat: no-repeat;
|
||||
border: 1px dashed #bbb;
|
||||
margin-left: 3px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.mce-visualblocks p {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7);
|
||||
}
|
||||
.mce-visualblocks h1 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==);
|
||||
}
|
||||
.mce-visualblocks h2 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==);
|
||||
}
|
||||
.mce-visualblocks h3 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7);
|
||||
}
|
||||
.mce-visualblocks h4 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==);
|
||||
}
|
||||
.mce-visualblocks h5 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==);
|
||||
}
|
||||
.mce-visualblocks h6 {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==);
|
||||
}
|
||||
.mce-visualblocks div:not([data-mce-bogus]) {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7);
|
||||
}
|
||||
.mce-visualblocks section {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=);
|
||||
}
|
||||
.mce-visualblocks article {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7);
|
||||
}
|
||||
.mce-visualblocks blockquote {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7);
|
||||
}
|
||||
.mce-visualblocks address {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=);
|
||||
}
|
||||
.mce-visualblocks pre {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==);
|
||||
}
|
||||
.mce-visualblocks figure {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7);
|
||||
}
|
||||
.mce-visualblocks figcaption {
|
||||
border: 1px dashed #bbb;
|
||||
}
|
||||
.mce-visualblocks hgroup {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7);
|
||||
}
|
||||
.mce-visualblocks aside {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=);
|
||||
}
|
||||
.mce-visualblocks ul {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==);
|
||||
}
|
||||
.mce-visualblocks ol {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==);
|
||||
}
|
||||
.mce-visualblocks dl {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybEOnmOvUoWznTqeuEjNSCqeGRUAOw==);
|
||||
}
|
||||
.mce-visualblocks:not([dir=rtl]) p,
|
||||
.mce-visualblocks:not([dir=rtl]) h1,
|
||||
.mce-visualblocks:not([dir=rtl]) h2,
|
||||
.mce-visualblocks:not([dir=rtl]) h3,
|
||||
.mce-visualblocks:not([dir=rtl]) h4,
|
||||
.mce-visualblocks:not([dir=rtl]) h5,
|
||||
.mce-visualblocks:not([dir=rtl]) h6,
|
||||
.mce-visualblocks:not([dir=rtl]) div:not([data-mce-bogus]),
|
||||
.mce-visualblocks:not([dir=rtl]) section,
|
||||
.mce-visualblocks:not([dir=rtl]) article,
|
||||
.mce-visualblocks:not([dir=rtl]) blockquote,
|
||||
.mce-visualblocks:not([dir=rtl]) address,
|
||||
.mce-visualblocks:not([dir=rtl]) pre,
|
||||
.mce-visualblocks:not([dir=rtl]) figure,
|
||||
.mce-visualblocks:not([dir=rtl]) figcaption,
|
||||
.mce-visualblocks:not([dir=rtl]) hgroup,
|
||||
.mce-visualblocks:not([dir=rtl]) aside,
|
||||
.mce-visualblocks:not([dir=rtl]) ul,
|
||||
.mce-visualblocks:not([dir=rtl]) ol,
|
||||
.mce-visualblocks:not([dir=rtl]) dl {
|
||||
margin-left: 3px;
|
||||
}
|
||||
.mce-visualblocks[dir=rtl] p,
|
||||
.mce-visualblocks[dir=rtl] h1,
|
||||
.mce-visualblocks[dir=rtl] h2,
|
||||
.mce-visualblocks[dir=rtl] h3,
|
||||
.mce-visualblocks[dir=rtl] h4,
|
||||
.mce-visualblocks[dir=rtl] h5,
|
||||
.mce-visualblocks[dir=rtl] h6,
|
||||
.mce-visualblocks[dir=rtl] div:not([data-mce-bogus]),
|
||||
.mce-visualblocks[dir=rtl] section,
|
||||
.mce-visualblocks[dir=rtl] article,
|
||||
.mce-visualblocks[dir=rtl] blockquote,
|
||||
.mce-visualblocks[dir=rtl] address,
|
||||
.mce-visualblocks[dir=rtl] pre,
|
||||
.mce-visualblocks[dir=rtl] figure,
|
||||
.mce-visualblocks[dir=rtl] figcaption,
|
||||
.mce-visualblocks[dir=rtl] hgroup,
|
||||
.mce-visualblocks[dir=rtl] aside,
|
||||
.mce-visualblocks[dir=rtl] ul,
|
||||
.mce-visualblocks[dir=rtl] ol,
|
||||
.mce-visualblocks[dir=rtl] dl {
|
||||
background-position-x: right;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.mce-nbsp,
|
||||
.mce-shy {
|
||||
background: #aaa;
|
||||
}
|
||||
.mce-shy::after {
|
||||
content: '-';
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection {
|
||||
/* Note: this file is used inside the content, so isn't part of theming */
|
||||
background-color: green;
|
||||
display: inline-block;
|
||||
opacity: 0.5;
|
||||
position: absolute;
|
||||
}
|
||||
body {
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
body img {
|
||||
/* this is related to the content margin */
|
||||
max-width: 96vw;
|
||||
}
|
||||
body table img {
|
||||
max-width: 95%;
|
||||
}
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse}
|
|
@ -0,0 +1,677 @@
|
|||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
/* RESET all the things! */
|
||||
.tinymce-mobile-outer-container {
|
||||
all: initial;
|
||||
display: block;
|
||||
}
|
||||
.tinymce-mobile-outer-container * {
|
||||
border: 0;
|
||||
box-sizing: initial;
|
||||
cursor: inherit;
|
||||
float: none;
|
||||
line-height: 1;
|
||||
margin: 0;
|
||||
outline: 0;
|
||||
padding: 0;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
/* TBIO-3691, stop the gray flicker on touch. */
|
||||
text-shadow: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tinymce-mobile-icon-arrow-back::before {
|
||||
content: "\e5cd";
|
||||
}
|
||||
.tinymce-mobile-icon-image::before {
|
||||
content: "\e412";
|
||||
}
|
||||
.tinymce-mobile-icon-cancel-circle::before {
|
||||
content: "\e5c9";
|
||||
}
|
||||
.tinymce-mobile-icon-full-dot::before {
|
||||
content: "\e061";
|
||||
}
|
||||
.tinymce-mobile-icon-align-center::before {
|
||||
content: "\e234";
|
||||
}
|
||||
.tinymce-mobile-icon-align-left::before {
|
||||
content: "\e236";
|
||||
}
|
||||
.tinymce-mobile-icon-align-right::before {
|
||||
content: "\e237";
|
||||
}
|
||||
.tinymce-mobile-icon-bold::before {
|
||||
content: "\e238";
|
||||
}
|
||||
.tinymce-mobile-icon-italic::before {
|
||||
content: "\e23f";
|
||||
}
|
||||
.tinymce-mobile-icon-unordered-list::before {
|
||||
content: "\e241";
|
||||
}
|
||||
.tinymce-mobile-icon-ordered-list::before {
|
||||
content: "\e242";
|
||||
}
|
||||
.tinymce-mobile-icon-font-size::before {
|
||||
content: "\e245";
|
||||
}
|
||||
.tinymce-mobile-icon-underline::before {
|
||||
content: "\e249";
|
||||
}
|
||||
.tinymce-mobile-icon-link::before {
|
||||
content: "\e157";
|
||||
}
|
||||
.tinymce-mobile-icon-unlink::before {
|
||||
content: "\eca2";
|
||||
}
|
||||
.tinymce-mobile-icon-color::before {
|
||||
content: "\e891";
|
||||
}
|
||||
.tinymce-mobile-icon-previous::before {
|
||||
content: "\e314";
|
||||
}
|
||||
.tinymce-mobile-icon-next::before {
|
||||
content: "\e315";
|
||||
}
|
||||
.tinymce-mobile-icon-large-font::before,
|
||||
.tinymce-mobile-icon-style-formats::before {
|
||||
content: "\e264";
|
||||
}
|
||||
.tinymce-mobile-icon-undo::before {
|
||||
content: "\e166";
|
||||
}
|
||||
.tinymce-mobile-icon-redo::before {
|
||||
content: "\e15a";
|
||||
}
|
||||
.tinymce-mobile-icon-removeformat::before {
|
||||
content: "\e239";
|
||||
}
|
||||
.tinymce-mobile-icon-small-font::before {
|
||||
content: "\e906";
|
||||
}
|
||||
.tinymce-mobile-icon-readonly-back::before,
|
||||
.tinymce-mobile-format-matches::after {
|
||||
content: "\e5ca";
|
||||
}
|
||||
.tinymce-mobile-icon-small-heading::before {
|
||||
content: "small";
|
||||
}
|
||||
.tinymce-mobile-icon-large-heading::before {
|
||||
content: "large";
|
||||
}
|
||||
.tinymce-mobile-icon-small-heading::before,
|
||||
.tinymce-mobile-icon-large-heading::before {
|
||||
font-family: sans-serif;
|
||||
font-size: 80%;
|
||||
}
|
||||
.tinymce-mobile-mask-edit-icon::before {
|
||||
content: "\e254";
|
||||
}
|
||||
.tinymce-mobile-icon-back::before {
|
||||
content: "\e5c4";
|
||||
}
|
||||
.tinymce-mobile-icon-heading::before {
|
||||
/* TODO: Translate */
|
||||
content: "Headings";
|
||||
font-family: sans-serif;
|
||||
font-size: 80%;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tinymce-mobile-icon-h1::before {
|
||||
content: "H1";
|
||||
font-weight: bold;
|
||||
}
|
||||
.tinymce-mobile-icon-h2::before {
|
||||
content: "H2";
|
||||
font-weight: bold;
|
||||
}
|
||||
.tinymce-mobile-icon-h3::before {
|
||||
content: "H3";
|
||||
font-weight: bold;
|
||||
}
|
||||
.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background: rgba(51, 51, 51, 0.5);
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container {
|
||||
align-items: center;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .mixin-menu-item {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
height: 2.1em;
|
||||
width: 2.1em;
|
||||
}
|
||||
.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-size: 1em;
|
||||
}
|
||||
@media only screen and (min-device-width:700px) {
|
||||
.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section .tinymce-mobile-mask-tap-icon {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
height: 2.1em;
|
||||
width: 2.1em;
|
||||
background-color: white;
|
||||
color: #207ab7;
|
||||
}
|
||||
.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section .tinymce-mobile-mask-tap-icon::before {
|
||||
content: "\e900";
|
||||
font-family: 'tinymce-mobile', sans-serif;
|
||||
}
|
||||
.tinymce-mobile-outer-container .tinymce-mobile-disabled-mask .tinymce-mobile-content-container .tinymce-mobile-content-tap-section:not(.tinymce-mobile-mask-tap-icon-selected) .tinymce-mobile-mask-tap-icon {
|
||||
z-index: 2;
|
||||
}
|
||||
.tinymce-mobile-android-container.tinymce-mobile-android-maximized {
|
||||
background: #ffffff;
|
||||
border: none;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.tinymce-mobile-android-container:not(.tinymce-mobile-android-maximized) {
|
||||
position: relative;
|
||||
}
|
||||
.tinymce-mobile-android-container .tinymce-mobile-editor-socket {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.tinymce-mobile-android-container .tinymce-mobile-editor-socket iframe {
|
||||
display: flex !important;
|
||||
flex-grow: 1;
|
||||
height: auto !important;
|
||||
}
|
||||
.tinymce-mobile-android-scroll-reload {
|
||||
overflow: hidden;
|
||||
}
|
||||
:not(.tinymce-mobile-readonly-mode) > .tinymce-mobile-android-selection-context-toolbar {
|
||||
margin-top: 23px;
|
||||
}
|
||||
.tinymce-mobile-toolstrip {
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
z-index: 1;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar {
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
height: 2.5em;
|
||||
width: 100%;
|
||||
/* Make it no larger than the toolstrip, so that it needs to scroll */
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group > div {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group.tinymce-mobile-exit-container {
|
||||
background: #f44336;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group.tinymce-mobile-toolbar-scrollable-group {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item {
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item.tinymce-mobile-toolbar-button {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 80%;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item.tinymce-mobile-toolbar-button.tinymce-mobile-toolbar-button-selected {
|
||||
background: #d4dbd7;
|
||||
color: #cccccc;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group:first-of-type,
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar:not(.tinymce-mobile-context-toolbar) .tinymce-mobile-toolbar-group:last-of-type {
|
||||
background: #207ab7;
|
||||
color: #eceff1;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar {
|
||||
/* Note, this file is imported inside .tinymce-mobile-context-toolbar, so that prefix is on everything here. */
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
padding-bottom: 0.4em;
|
||||
padding-top: 0.4em;
|
||||
/* Make any buttons appearing on the left and right display in the centre (e.g. color edges) */
|
||||
/* For widgets like the colour picker, use the whole height */
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog {
|
||||
display: flex;
|
||||
min-height: 1.5em;
|
||||
overflow: hidden;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
transition: left cubic-bezier(0.4, 0, 1, 1) 0.15s;
|
||||
width: 100%;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen input {
|
||||
font-family: Sans-serif;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-input-container {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-input-container .tinymce-mobile-input-container-x {
|
||||
-ms-grid-row-align: center;
|
||||
align-self: center;
|
||||
background: inherit;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
color: #888;
|
||||
font-size: 0.6em;
|
||||
font-weight: bold;
|
||||
height: 100%;
|
||||
padding-right: 2px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-input-container.tinymce-mobile-input-container-empty .tinymce-mobile-input-container-x {
|
||||
display: none;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-previous,
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-next {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-previous::before,
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-next::before {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-weight: bold;
|
||||
height: 100%;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-previous.tinymce-mobile-toolbar-navigation-disabled::before,
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serialised-dialog .tinymce-mobile-serialised-dialog-chain .tinymce-mobile-serialised-dialog-screen .tinymce-mobile-icon-next.tinymce-mobile-toolbar-navigation-disabled::before {
|
||||
visibility: hidden;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-dot-item {
|
||||
color: #cccccc;
|
||||
font-size: 10px;
|
||||
line-height: 10px;
|
||||
margin: 0 2px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-dot-item.tinymce-mobile-dot-active {
|
||||
color: #d4dbd7;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-large-font::before,
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-large-heading::before {
|
||||
margin-left: 0.5em;
|
||||
margin-right: 0.9em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-small-font::before,
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-icon-small-heading::before {
|
||||
margin-left: 0.9em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
padding: 0.28em 0;
|
||||
position: relative;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-size-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-size-container .tinymce-mobile-slider-size-line {
|
||||
background: #cccccc;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
height: 0.2em;
|
||||
margin-bottom: 0.3em;
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container {
|
||||
padding-left: 2em;
|
||||
padding-right: 2em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-slider-gradient-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-slider-gradient-container .tinymce-mobile-slider-gradient {
|
||||
background: linear-gradient(to right, hsl(0, 100%, 50%) 0%, hsl(60, 100%, 50%) 17%, hsl(120, 100%, 50%) 33%, hsl(180, 100%, 50%) 50%, hsl(240, 100%, 50%) 67%, hsl(300, 100%, 50%) 83%, hsl(0, 100%, 50%) 100%);
|
||||
display: flex;
|
||||
flex: 1;
|
||||
height: 0.2em;
|
||||
margin-bottom: 0.3em;
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-hue-slider-black {
|
||||
/* Not part of theming */
|
||||
background: black;
|
||||
height: 0.2em;
|
||||
margin-bottom: 0.3em;
|
||||
margin-top: 0.3em;
|
||||
width: 1.2em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider.tinymce-mobile-hue-slider-container .tinymce-mobile-hue-slider-white {
|
||||
/* Not part of theming */
|
||||
background: white;
|
||||
height: 0.2em;
|
||||
margin-bottom: 0.3em;
|
||||
margin-top: 0.3em;
|
||||
width: 1.2em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-thumb {
|
||||
/* vertically centering trick (margin: auto, top: 0, bottom: 0). On iOS and Safari, if you leave
|
||||
* out these values, then it shows the thumb at the top of the spectrum. This is probably because it is
|
||||
* absolutely positioned with only a left value, and not a top. Note, on Chrome it seems to be fine without
|
||||
* this approach.
|
||||
*/
|
||||
align-items: center;
|
||||
background-clip: padding-box;
|
||||
background-color: #455a64;
|
||||
border: 0.5em solid rgba(136, 136, 136, 0);
|
||||
border-radius: 3em;
|
||||
bottom: 0;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
height: 0.5em;
|
||||
justify-content: center;
|
||||
left: -10px;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
transition: border 120ms cubic-bezier(0.39, 0.58, 0.57, 1);
|
||||
width: 0.5em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-slider .tinymce-mobile-slider-thumb.tinymce-mobile-thumb-active {
|
||||
border: 0.5em solid rgba(136, 136, 136, 0.39);
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serializer-wrapper,
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group > div {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-serializer-wrapper {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-toolbar-group-item:not(.tinymce-mobile-serialised-dialog) {
|
||||
height: 100%;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group .tinymce-mobile-dot-container {
|
||||
display: flex;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input {
|
||||
background: #ffffff;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
color: #455a64;
|
||||
flex-grow: 1;
|
||||
font-size: 0.85em;
|
||||
padding-bottom: 0.1em;
|
||||
padding-left: 5px;
|
||||
padding-top: 0.1em;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input::-webkit-input-placeholder {
|
||||
/* WebKit, Blink, Edge */
|
||||
color: #888;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input:-ms-input-placeholder {
|
||||
/* WebKit, Blink, Edge */
|
||||
color: #888;
|
||||
}
|
||||
.tinymce-mobile-toolstrip .tinymce-mobile-toolbar.tinymce-mobile-context-toolbar .tinymce-mobile-toolbar-group input::placeholder {
|
||||
/* WebKit, Blink, Edge */
|
||||
color: #888;
|
||||
}
|
||||
/* dropup */
|
||||
.tinymce-mobile-dropup {
|
||||
background: white;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
.tinymce-mobile-dropup.tinymce-mobile-dropup-shrinking {
|
||||
transition: height 0.3s ease-out;
|
||||
}
|
||||
.tinymce-mobile-dropup.tinymce-mobile-dropup-growing {
|
||||
transition: height 0.3s ease-in;
|
||||
}
|
||||
.tinymce-mobile-dropup.tinymce-mobile-dropup-closed {
|
||||
flex-grow: 0;
|
||||
}
|
||||
.tinymce-mobile-dropup.tinymce-mobile-dropup-open:not(.tinymce-mobile-dropup-growing) {
|
||||
flex-grow: 1;
|
||||
}
|
||||
/* TODO min-height for device size and orientation */
|
||||
.tinymce-mobile-ios-container .tinymce-mobile-dropup:not(.tinymce-mobile-dropup-closed) {
|
||||
min-height: 200px;
|
||||
}
|
||||
@media only screen and (orientation: landscape) {
|
||||
.tinymce-mobile-dropup:not(.tinymce-mobile-dropup-closed) {
|
||||
min-height: 200px;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-device-width : 320px) and (max-device-width : 568px) and (orientation : landscape) {
|
||||
.tinymce-mobile-ios-container .tinymce-mobile-dropup:not(.tinymce-mobile-dropup-closed) {
|
||||
min-height: 150px;
|
||||
}
|
||||
}
|
||||
/* styles menu */
|
||||
.tinymce-mobile-styles-menu {
|
||||
font-family: sans-serif;
|
||||
outline: 4px solid black;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.tinymce-mobile-styles-menu [role="menu"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
.tinymce-mobile-styles-menu [role="menu"].transitioning {
|
||||
transition: transform 0.5s ease-in-out;
|
||||
}
|
||||
.tinymce-mobile-styles-menu .tinymce-mobile-styles-item {
|
||||
border-bottom: 1px solid #ddd;
|
||||
color: #455a64;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
padding: 1em 1em;
|
||||
position: relative;
|
||||
}
|
||||
.tinymce-mobile-styles-menu .tinymce-mobile-styles-collapser .tinymce-mobile-styles-collapse-icon::before {
|
||||
color: #455a64;
|
||||
content: "\e314";
|
||||
font-family: 'tinymce-mobile', sans-serif;
|
||||
}
|
||||
.tinymce-mobile-styles-menu .tinymce-mobile-styles-item.tinymce-mobile-styles-item-is-menu::after {
|
||||
color: #455a64;
|
||||
content: "\e315";
|
||||
font-family: 'tinymce-mobile', sans-serif;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
.tinymce-mobile-styles-menu .tinymce-mobile-styles-item.tinymce-mobile-format-matches::after {
|
||||
font-family: 'tinymce-mobile', sans-serif;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
.tinymce-mobile-styles-menu .tinymce-mobile-styles-separator,
|
||||
.tinymce-mobile-styles-menu .tinymce-mobile-styles-collapser {
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
border-top: #455a64;
|
||||
color: #455a64;
|
||||
display: flex;
|
||||
min-height: 2.5em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
.tinymce-mobile-styles-menu [data-transitioning-destination="before"][data-transitioning-state],
|
||||
.tinymce-mobile-styles-menu [data-transitioning-state="before"] {
|
||||
transform: translate(-100%);
|
||||
}
|
||||
.tinymce-mobile-styles-menu [data-transitioning-destination="current"][data-transitioning-state],
|
||||
.tinymce-mobile-styles-menu [data-transitioning-state="current"] {
|
||||
transform: translate(0%);
|
||||
}
|
||||
.tinymce-mobile-styles-menu [data-transitioning-destination="after"][data-transitioning-state],
|
||||
.tinymce-mobile-styles-menu [data-transitioning-state="after"] {
|
||||
transform: translate(100%);
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'tinymce-mobile';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: url('fonts/tinymce-mobile.woff?8x92w3') format('woff');
|
||||
}
|
||||
@media (min-device-width: 700px) {
|
||||
.tinymce-mobile-outer-container,
|
||||
.tinymce-mobile-outer-container input {
|
||||
font-size: 25px;
|
||||
}
|
||||
}
|
||||
@media (max-device-width: 700px) {
|
||||
.tinymce-mobile-outer-container,
|
||||
.tinymce-mobile-outer-container input {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
.tinymce-mobile-icon {
|
||||
font-family: 'tinymce-mobile', sans-serif;
|
||||
}
|
||||
.mixin-flex-and-centre {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.mixin-flex-bar {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
}
|
||||
.tinymce-mobile-outer-container .tinymce-mobile-editor-socket iframe {
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
}
|
||||
.tinymce-mobile-editor-socket .tinymce-mobile-mask-edit-icon {
|
||||
/* Note, on the iPod touch in landscape, this isn't visible when the navbar appears */
|
||||
background-color: #207ab7;
|
||||
border-radius: 50%;
|
||||
bottom: 1em;
|
||||
color: white;
|
||||
font-size: 1em;
|
||||
height: 2.1em;
|
||||
position: fixed;
|
||||
right: 2em;
|
||||
width: 2.1em;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
@media only screen and (min-device-width:700px) {
|
||||
.tinymce-mobile-editor-socket .tinymce-mobile-mask-edit-icon {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
.tinymce-mobile-outer-container:not(.tinymce-mobile-fullscreen-maximized) .tinymce-mobile-editor-socket {
|
||||
height: 300px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.tinymce-mobile-outer-container:not(.tinymce-mobile-fullscreen-maximized) .tinymce-mobile-editor-socket iframe {
|
||||
height: 100%;
|
||||
}
|
||||
.tinymce-mobile-outer-container:not(.tinymce-mobile-fullscreen-maximized) .tinymce-mobile-toolstrip {
|
||||
display: none;
|
||||
}
|
||||
/*
|
||||
Note, that if you don't include this (::-webkit-file-upload-button), the toolbar width gets
|
||||
increased and the whole body becomes scrollable. It's important!
|
||||
*/
|
||||
input[type="file"]::-webkit-file-upload-button {
|
||||
display: none;
|
||||
}
|
||||
@media only screen and (min-device-width : 320px) and (max-device-width : 568px) and (orientation : landscape) {
|
||||
.tinymce-mobile-ios-container .tinymce-mobile-editor-socket .tinymce-mobile-mask-edit-icon {
|
||||
bottom: 50%;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useGlobSetting } from '/@/hooks/setting';
|
||||
const globSetting = useGlobSetting();
|
||||
const baseUploadUrl = globSetting.uploadUrl;
|
||||
enum Api {
|
||||
positionList = '/sys/position/list',
|
||||
userList = '/sys/user/list',
|
||||
roleList = '/sys/role/list',
|
||||
queryDepartTreeSync = '/sys/sysDepart/queryDepartTreeSync',
|
||||
queryTreeList = '/sys/sysDepart/queryTreeList',
|
||||
loadTreeData = '/sys/category/loadTreeData',
|
||||
loadDictItem = '/sys/category/loadDictItem/',
|
||||
getDictItems = '/sys/dict/getDictItems/',
|
||||
getTableList = '/sys/user/queryUserComponentData',
|
||||
getCategoryData = '/sys/category/loadAllData',
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传父路径
|
||||
*/
|
||||
export const uploadUrl=`${baseUploadUrl}/sys/common/upload`;
|
||||
|
||||
/**
|
||||
* 职务列表
|
||||
* @param params
|
||||
*/
|
||||
export const getPositionList = (params) => {
|
||||
return defHttp.get({ url: Api.positionList, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
* @param params
|
||||
*/
|
||||
export const getUserList = (params) => {
|
||||
return defHttp.get({ url: Api.userList, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 角色列表
|
||||
* @param params
|
||||
*/
|
||||
export const getRoleList = (params) => {
|
||||
return defHttp.get({ url: Api.roleList, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 异步获取部门树列表
|
||||
*/
|
||||
export const queryDepartTreeSync = (params?) =>{
|
||||
return defHttp.get({ url: Api.queryDepartTreeSync, params });
|
||||
}
|
||||
/**
|
||||
* 获取部门树列表
|
||||
*/
|
||||
export const queryTreeList = (params?) =>{
|
||||
return defHttp.get({ url: Api.queryTreeList, params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 分类字典树控件 加载节点
|
||||
*/
|
||||
export const loadTreeData = (params?) =>{
|
||||
return defHttp.get({ url: Api.loadTreeData, params });
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据字典code加载字典text
|
||||
*/
|
||||
export const loadDictItem = (params?) =>{
|
||||
return defHttp.get({ url: Api.loadDictItem, params });
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字典code加载字典text
|
||||
*/
|
||||
export const getDictItems = (dictCode) =>{
|
||||
return defHttp.get({ url: Api.getDictItems+dictCode},{joinTime:false});
|
||||
}
|
||||
/**
|
||||
* 部门用户modal选择列表加载list
|
||||
*/
|
||||
export const getTableList = (params)=>{
|
||||
return defHttp.get({url:Api.getTableList,params})
|
||||
}
|
||||
/**
|
||||
* 加载全部分类字典数据
|
||||
*/
|
||||
export const loadCategoryData = (params)=>{
|
||||
return defHttp.get({url:Api.getCategoryData,params})
|
||||
}
|
||||
/**
|
||||
* 文件上传
|
||||
*/
|
||||
export const uploadFile = (params,success)=>{
|
||||
return defHttp.uploadFile({url:uploadUrl}, params,{success})
|
||||
}
|
|
@ -2,8 +2,9 @@ import { defHttp } from '/@/utils/http/axios';
|
|||
import { GetAccountInfoModel } from './model/accountModel';
|
||||
|
||||
enum Api {
|
||||
ACCOUNT_INFO = '/account/getAccountInfo',
|
||||
SESSION_TIMEOUT = '/user/sessionTimeout',
|
||||
ACCOUNT_INFO = '/mock/account/getAccountInfo',
|
||||
SESSION_TIMEOUT = '/mock/user/sessionTimeout',
|
||||
TOKEN_EXPIRED = '/mock/user/tokenExpired',
|
||||
}
|
||||
|
||||
// Get personal center-basic settings
|
||||
|
@ -11,3 +12,5 @@ enum Api {
|
|||
export const accountInfoApi = () => defHttp.get<GetAccountInfoModel>({ url: Api.ACCOUNT_INFO });
|
||||
|
||||
export const sessionTimeoutApi = () => defHttp.post<void>({ url: Api.SESSION_TIMEOUT });
|
||||
|
||||
export const tokenExpiredApi = () => defHttp.post<void>({ url: Api.TOKEN_EXPIRED });
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { DemoOptionsItem, selectParams } from './model/optionsModel';
|
||||
enum Api {
|
||||
OPTIONS_LIST = '/select/getDemoOptions',
|
||||
OPTIONS_LIST = '/mock/select/getDemoOptions',
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,28 +4,26 @@ import {
|
|||
MenuParams,
|
||||
RoleParams,
|
||||
TestPageParams,
|
||||
UserPageParams,
|
||||
RolePageParams,
|
||||
MenuListGetResultModel,
|
||||
DeptListGetResultModel,
|
||||
AccountListGetResultModel,
|
||||
RolePageListGetResultModel,
|
||||
RoleListGetResultModel,
|
||||
TestListGetResultModel,
|
||||
UserListGetResultModel,
|
||||
TestListGetResultModel
|
||||
} from './model/systemModel';
|
||||
import {defHttp} from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
AccountList = '/system/getAccountList',
|
||||
IsAccountExist = '/system/accountExist',
|
||||
DeptList = '/system/getDeptList',
|
||||
setRoleStatus = '/system/setRoleStatus',
|
||||
MenuList = '/system/getMenuList',
|
||||
RolePageList = '/system/getRoleListByPage',
|
||||
DemoTableList = '/system/getDemoTableListByPage',
|
||||
TestPageList = '/system/getTestListByPage',
|
||||
GetAllRoleList = '/system/getAllRoleList',
|
||||
AccountList = '/mock/system/getAccountList',
|
||||
IsAccountExist = '/mock/system/accountExist',
|
||||
DeptList = '/mock/system/getDeptList',
|
||||
setRoleStatus = '/mock/system/setRoleStatus',
|
||||
MenuList = '/mock/system/getMenuList',
|
||||
RolePageList = '/mock/system/getRoleListByPage',
|
||||
DemoTableList = '/mock/system/getDemoTableListByPage',
|
||||
TestPageList = '/mock/system/getTestListByPage',
|
||||
GetAllRoleList = '/mock/system/getAllRoleList',
|
||||
}
|
||||
|
||||
export const getAccountList = (params: AccountParams) =>
|
||||
|
@ -54,29 +52,3 @@ export const getDemoTableListByPage = (params) =>
|
|||
|
||||
export const isAccountExist = (account: string) =>
|
||||
defHttp.post({url: Api.IsAccountExist, params: {account}}, {errorMessageMode: 'none'});
|
||||
|
||||
export const isRoleExist = (params) =>
|
||||
defHttp.get({url: Api.isRoleExist, params},{isTransformResponse:false});
|
||||
|
||||
export const getUserListByPage = (params?: UserPageParams) =>
|
||||
defHttp.get({url: Api.UserList, params});
|
||||
|
||||
export const getRolesListByPage = (params?: RolePageParams) =>
|
||||
defHttp.get<RolePageListGetResultModel>({url: Api.RolesList, params});
|
||||
|
||||
export const getAllRolesList = (params?: RoleParams) =>
|
||||
defHttp.get<RoleListGetResultModel>({url: Api.allRolesList, params});
|
||||
|
||||
export const getAllTenantList = (params?: RoleParams) =>
|
||||
defHttp.get({url: Api.allTenantList, params});
|
||||
|
||||
export const getUserRoles = (params) =>
|
||||
defHttp.get({url: Api.getUserRole, params}, {errorMessageMode: 'none'});
|
||||
|
||||
export const getAllPostList = (params) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
defHttp.get({url: Api.allPostList, params}).then(res => {
|
||||
resolve(res.records)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { defHttp } from '/@/utils/http/axios';
|
|||
import { DemoParams, DemoListGetResultModel } from './model/tableModel';
|
||||
|
||||
enum Api {
|
||||
DEMO_LIST = '/table/getDemoList',
|
||||
DEMO_LIST = '/mock/table/getDemoList',
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { defHttp } from '/@/utils/http/axios';
|
||||
|
||||
enum Api {
|
||||
TREE_OPTIONS_LIST = '/tree/getDemoOptions',
|
||||
TREE_OPTIONS_LIST = '/mock/tree/getDemoOptions',
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,13 +10,13 @@ enum Api {
|
|||
*/
|
||||
|
||||
export const getMenuList = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise((resolve) => {
|
||||
//为了兼容mock和接口数据
|
||||
defHttp.get<getMenuListResultModel>({ url: Api.GetMenuList }).then(res=>{
|
||||
if(Array.isArray(res)){
|
||||
resolve(res)
|
||||
}else{
|
||||
resolve(res.menu)
|
||||
resolve(res['menu'])
|
||||
}
|
||||
});
|
||||
})
|
||||
|
|
|
@ -6,6 +6,11 @@ export interface LoginParams {
|
|||
password: string;
|
||||
}
|
||||
|
||||
export interface ThirdLoginParams {
|
||||
token: string;
|
||||
thirdType: string;
|
||||
}
|
||||
|
||||
export interface RoleInfo {
|
||||
roleName: string;
|
||||
value: string;
|
||||
|
@ -30,11 +35,15 @@ export interface GetUserInfoModel {
|
|||
// 用户名
|
||||
username: string;
|
||||
// 真实名字
|
||||
realName: string;
|
||||
realname: string;
|
||||
// 头像
|
||||
avatar: string;
|
||||
// 介绍
|
||||
desc?: string;
|
||||
// 用户信息
|
||||
userInfo?: any;
|
||||
// 缓存字典项
|
||||
sysAllDictItems?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,3 +20,18 @@ export function uploadApi(
|
|||
params
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @description: Upload interface
|
||||
*/
|
||||
export function uploadImg(
|
||||
params: UploadFileParams,
|
||||
onUploadProgress: (progressEvent: ProgressEvent) => void
|
||||
) {
|
||||
return defHttp.uploadFile<UploadApiResult>(
|
||||
{
|
||||
url: `${uploadUrl}/sys/common/upload`,
|
||||
onUploadProgress,
|
||||
},
|
||||
params, {isReturnResponse:true}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,10 @@ enum Api {
|
|||
phoneLogin = '/sys/phoneLogin',
|
||||
Logout = '/sys/logout',
|
||||
GetUserInfo = '/sys/user/getUserInfo',
|
||||
// 获取系统权限
|
||||
// 1、查询用户拥有的按钮/表单访问权限
|
||||
// 2、所有权限
|
||||
// 3、系统安全模式
|
||||
GetPermCode = '/sys/permission/getPermCode',
|
||||
//新加的获取图形验证码的接口
|
||||
getInputCode = '/sys/randomImage',
|
||||
|
@ -20,10 +24,20 @@ enum Api {
|
|||
registerApi = '/sys/user/register',
|
||||
//校验用户接口
|
||||
checkOnlyUser = '/sys/user/checkOnlyUser',
|
||||
//SSO登录校验
|
||||
validateCasLogin = '/sys/cas/client/validateLogin',
|
||||
//校验手机号
|
||||
phoneVerify = '/sys/user/phoneVerification',
|
||||
//修改密码
|
||||
passwordChange = '/sys/user/passwordChange',
|
||||
//第三方登录
|
||||
thirdLogin = '/sys/thirdLogin/getLoginUser',
|
||||
//第三方登录
|
||||
getThirdCaptcha = '/sys/thirdSms',
|
||||
//获取二维码信息
|
||||
getLoginQrcode = '/sys/getLoginQrcode',
|
||||
//监控二维码扫描状态
|
||||
getQrcodeToken = '/sys/getQrcodeToken',
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,11 +74,11 @@ export function phoneLoginApi(params: LoginParams, mode: ErrorMessageMode = 'mod
|
|||
* @description: getUserInfo
|
||||
*/
|
||||
export function getUserInfo() {
|
||||
return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo });
|
||||
return defHttp.get<GetUserInfoModel>({ url: Api.GetUserInfo }, { errorMessageMode: 'none' });
|
||||
}
|
||||
|
||||
export function getPermCode() {
|
||||
return defHttp.get<string[]>({ url: Api.GetPermCode });
|
||||
return defHttp.get({ url: Api.GetPermCode });
|
||||
}
|
||||
|
||||
export function doLogout() {
|
||||
|
@ -80,7 +94,7 @@ export function getCodeInfo(currdatetime) {
|
|||
*/
|
||||
export function getCaptcha(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
defHttp.post({url: Api.getCaptcha,params},{isTransformResponse: false}).then(res=>{
|
||||
defHttp.post({url:Api.getCaptcha,params},{isTransformResponse: false}).then(res=>{
|
||||
console.log(res)
|
||||
if(res.success){
|
||||
resolve(true)
|
||||
|
@ -117,3 +131,56 @@ export const phoneVerify = (params) =>
|
|||
*/
|
||||
export const passwordChange = (params) =>
|
||||
defHttp.get({url: Api.passwordChange, params},{isTransformResponse:false});
|
||||
/**
|
||||
* @description: 第三方登录
|
||||
*/
|
||||
export function thirdLogin(params, mode: ErrorMessageMode = 'modal') {
|
||||
return defHttp.get<LoginResultModel>(
|
||||
{
|
||||
url: `${Api.thirdLogin}/${params.token}/${params.thirdType}`,
|
||||
},
|
||||
{
|
||||
errorMessageMode: mode,
|
||||
}
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @description: 获取第三方短信验证码
|
||||
*/
|
||||
export function setThirdCaptcha(params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
defHttp.post({url:Api.getThirdCaptcha,params},{isTransformResponse: false}).then(res=>{
|
||||
console.log(res)
|
||||
if(res.success){
|
||||
resolve(true)
|
||||
}else{
|
||||
createErrorModal({ title: '错误提示', content: res.message||'未知问题' });
|
||||
reject()
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录二维码信息
|
||||
*/
|
||||
export function getLoginQrcode() {
|
||||
let url = Api.getLoginQrcode
|
||||
return defHttp.get({ url: url });
|
||||
}
|
||||
|
||||
/**
|
||||
* 监控扫码状态
|
||||
*/
|
||||
export function getQrcodeToken(params) {
|
||||
let url = Api.getQrcodeToken
|
||||
return defHttp.get({ url: url,params});
|
||||
}
|
||||
|
||||
/**
|
||||
* SSO登录校验
|
||||
*/
|
||||
export async function validateCasLogin(params) {
|
||||
let url = Api.validateCasLogin
|
||||
return defHttp.get({ url: url,params});
|
||||
}
|
||||
|
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 99 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 10 KiB |
|
@ -87,6 +87,7 @@
|
|||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
transition: all 0.5s;
|
||||
line-height: normal;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { withInstall } from '/@/utils';
|
||||
import type { ExtractPropTypes } from 'vue';
|
||||
import button from './src/BasicButton.vue';
|
||||
import uploadButton from './src/UploadButton.vue';
|
||||
import popConfirmButton from './src/PopConfirmButton.vue';
|
||||
import { buttonProps } from './src/props';
|
||||
|
||||
export const Button = withInstall(button);
|
||||
export const UploadButton = withInstall(uploadButton);
|
||||
export const PopConfirmButton = withInstall(popConfirmButton);
|
||||
export declare type ButtonProps = Partial<ExtractPropTypes<typeof buttonProps>>;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
import Icon from '/@/components/Icon/src/Icon.vue';
|
||||
import { buttonProps } from './props';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
|
||||
const props = defineProps(buttonProps);
|
||||
// get component class
|
||||
const attrs = useAttrs({ excludeDefaultKeys: false });
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<a-upload name="file" :showUploadList="false" :customRequest="(file)=>onClick(file)">
|
||||
<Button :type="type" :class="getButtonClass" >
|
||||
<template #default="data">
|
||||
<Icon :icon="preIcon" v-if="preIcon" :size="iconSize" />
|
||||
<slot v-bind="data || {}"></slot>
|
||||
<Icon :icon="postIcon" v-if="postIcon" :size="iconSize" />
|
||||
</template>
|
||||
</Button>
|
||||
</a-upload>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
export default defineComponent({
|
||||
name: 'JUploadButton',
|
||||
inheritAttrs: false,
|
||||
});
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { computed, unref } from 'vue';
|
||||
import { Button } from 'ant-design-vue';
|
||||
import Icon from '/@/components/Icon/src/Icon.vue';
|
||||
import { buttonProps } from './props';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
const props = defineProps(buttonProps);
|
||||
// get component class
|
||||
const attrs = useAttrs({ excludeDefaultKeys: false });
|
||||
const getButtonClass = computed(() => {
|
||||
const { color, disabled } = props;
|
||||
return [
|
||||
{
|
||||
[`ant-btn-${color}`]: !!color,
|
||||
[`is-disabled`]: disabled,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
// get inherit binding value
|
||||
const getBindValue = computed(() => ({ ...unref(attrs), ...props }));
|
||||
</script>
|
|
@ -10,10 +10,12 @@ export const buttonProps = {
|
|||
* Text after icon.
|
||||
*/
|
||||
postIcon: { type: String },
|
||||
type: { type: String },
|
||||
/**
|
||||
* preIcon and postIcon icon size.
|
||||
* @default: 14
|
||||
*/
|
||||
iconSize: { type: Number, default: 14 },
|
||||
isUpload:{type:Boolean,default:false},
|
||||
onClick: { type: Function as PropType<(...args) => any>, default: null },
|
||||
};
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
import { withInstall } from '/@/utils';
|
||||
import cardList from './src/CardList.vue';
|
||||
|
||||
export const CardList = withInstall(cardList);
|
|
@ -0,0 +1,178 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<div class="bg-white mb-2 p-4">
|
||||
<BasicForm @register="registerForm" />
|
||||
</div>
|
||||
{{ sliderProp.width }}
|
||||
<div class="bg-white p-2">
|
||||
<List
|
||||
:grid="{ gutter: 5, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: grid }"
|
||||
:data-source="data"
|
||||
:pagination="paginationProp"
|
||||
>
|
||||
<template #header>
|
||||
<div class="flex justify-end space-x-2"
|
||||
><slot name="header"></slot>
|
||||
<Tooltip>
|
||||
<template #title>
|
||||
<div class="w-50">每行显示数量</div
|
||||
><Slider
|
||||
id="slider"
|
||||
v-bind="sliderProp"
|
||||
v-model:value="grid"
|
||||
@change="sliderChange"
|
||||
/></template>
|
||||
<Button><TableOutlined /></Button>
|
||||
</Tooltip>
|
||||
<Tooltip @click="fetch">
|
||||
<template #title>刷新</template>
|
||||
<Button><RedoOutlined /></Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<template #renderItem="{ item }">
|
||||
<ListItem>
|
||||
<Card>
|
||||
<template #title></template>
|
||||
<template #cover>
|
||||
<div :class="height">
|
||||
<Image :src="item.imgs[0]" />
|
||||
</div>
|
||||
</template>
|
||||
<template class="ant-card-actions" #actions>
|
||||
<!-- <SettingOutlined key="setting" />-->
|
||||
<EditOutlined key="edit" />
|
||||
<Dropdown
|
||||
:trigger="['hover']"
|
||||
:dropMenuList="[
|
||||
{
|
||||
text: '删除',
|
||||
event: '1',
|
||||
popConfirm: {
|
||||
title: '是否确认删除',
|
||||
confirm: handleDelete.bind(null, item.id),
|
||||
},
|
||||
},
|
||||
]"
|
||||
popconfirm
|
||||
>
|
||||
<EllipsisOutlined key="ellipsis" />
|
||||
</Dropdown>
|
||||
</template>
|
||||
|
||||
<CardMeta>
|
||||
<template #title>
|
||||
<TypographyText :content="item.name" :ellipsis="{ tooltip: item.address }" />
|
||||
</template>
|
||||
<template #avatar>
|
||||
<Avatar :src="item.avatar" />
|
||||
</template>
|
||||
<template #description>{{ item.time }}</template>
|
||||
</CardMeta>
|
||||
</Card>
|
||||
</ListItem>
|
||||
</template>
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import {
|
||||
EditOutlined,
|
||||
EllipsisOutlined,
|
||||
RedoOutlined,
|
||||
TableOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import { List, Card, Image, Typography, Tooltip, Slider, Avatar } from 'ant-design-vue';
|
||||
import { Dropdown } from '/@/components/Dropdown';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { Button } from '/@/components/Button';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { useSlider, grid } from './data';
|
||||
const ListItem = List.Item;
|
||||
const CardMeta = Card.Meta;
|
||||
const TypographyText = Typography.Text;
|
||||
// 获取slider属性
|
||||
const sliderProp = computed(() => useSlider(4));
|
||||
// 组件接收参数
|
||||
const props = defineProps({
|
||||
// 请求API的参数
|
||||
params: propTypes.object.def({}),
|
||||
//api
|
||||
api: propTypes.func,
|
||||
});
|
||||
//暴露内部方法
|
||||
const emit = defineEmits(['getMethod', 'delete']);
|
||||
//数据
|
||||
const data = ref([]);
|
||||
// 切换每行个数
|
||||
// cover图片自适应高度
|
||||
//修改pageSize并重新请求数据
|
||||
|
||||
const height = computed(() => {
|
||||
return `h-${120 - grid.value * 6}`;
|
||||
});
|
||||
//表单
|
||||
const [registerForm, { validate }] = useForm({
|
||||
schemas: [{ field: 'type', component: 'Input', label: '类型' }],
|
||||
labelWidth: 80,
|
||||
baseColProps: { span: 6 },
|
||||
actionColOptions: { span: 24 },
|
||||
autoSubmitOnEnter: true,
|
||||
submitFunc: handleSubmit,
|
||||
});
|
||||
//表单提交
|
||||
async function handleSubmit() {
|
||||
const data = await validate();
|
||||
await fetch(data);
|
||||
}
|
||||
function sliderChange(n) {
|
||||
pageSize.value = n * 4;
|
||||
fetch();
|
||||
}
|
||||
|
||||
// 自动请求并暴露内部方法
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
emit('getMethod', fetch);
|
||||
});
|
||||
|
||||
async function fetch(p = {}) {
|
||||
const { api, params } = props;
|
||||
if (api && isFunction(api)) {
|
||||
const res = await api({ ...params, page: page.value, pageSize: pageSize.value, ...p });
|
||||
data.value = res.items;
|
||||
total.value = res.total;
|
||||
}
|
||||
}
|
||||
//分页相关
|
||||
const page = ref(1);
|
||||
const pageSize = ref(36);
|
||||
const total = ref(0);
|
||||
const paginationProp = ref({
|
||||
showSizeChanger: false,
|
||||
showQuickJumper: true,
|
||||
pageSize,
|
||||
current: page,
|
||||
total,
|
||||
showTotal: (total) => `总 ${total} 条`,
|
||||
onChange: pageChange,
|
||||
onShowSizeChange: pageSizeChange,
|
||||
});
|
||||
|
||||
function pageChange(p, pz) {
|
||||
page.value = p;
|
||||
pageSize.value = pz;
|
||||
fetch();
|
||||
}
|
||||
function pageSizeChange(current, size) {
|
||||
pageSize.value = size;
|
||||
fetch();
|
||||
}
|
||||
|
||||
async function handleDelete(id) {
|
||||
emit('delete', id);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,25 @@
|
|||
import { ref } from 'vue';
|
||||
//每行个数
|
||||
export const grid = ref(12);
|
||||
// slider属性
|
||||
export const useSlider = (min = 6, max = 12) => {
|
||||
// 每行显示个数滑动条
|
||||
const getMarks = () => {
|
||||
const l = {};
|
||||
for (let i = min; i < max + 1; i++) {
|
||||
l[i] = {
|
||||
style: {
|
||||
color: '#fff',
|
||||
},
|
||||
label: i,
|
||||
};
|
||||
}
|
||||
return l;
|
||||
};
|
||||
return {
|
||||
min,
|
||||
max,
|
||||
marks: getMarks(),
|
||||
step: 1,
|
||||
};
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
export enum MODE {
|
||||
JSON = 'application/json',
|
||||
HTML = 'htmlmixed',
|
||||
JS = 'javascript',
|
||||
}
|
|
@ -186,7 +186,7 @@
|
|||
try {
|
||||
setModalProps({ confirmLoading: true });
|
||||
const result = await uploadApi({ name: 'file', file: blob, filename });
|
||||
emit('uploadSuccess', { source: previewSource.value, data: result.data });
|
||||
emit('uploadSuccess', { source: previewSource.value, data: result.data || result.message });
|
||||
closeModal();
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
|
|
|
@ -91,9 +91,9 @@
|
|||
}
|
||||
);
|
||||
|
||||
function handleUploadSuccess({ source }) {
|
||||
function handleUploadSuccess({ source,data }) {
|
||||
sourceValue.value = source;
|
||||
emit('change', source);
|
||||
emit('change', source, data);
|
||||
createMessage.success(t('component.cropper.uploadSuccess'));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
<template>
|
||||
<Dropdown :trigger="trigger" v-bind="$attrs">
|
||||
<a-dropdown :trigger="trigger" v-bind="$attrs">
|
||||
<span>
|
||||
<slot></slot>
|
||||
</span>
|
||||
<template #overlay>
|
||||
<Menu :selectedKeys="selectedKeys">
|
||||
<a-menu :selectedKeys="selectedKeys">
|
||||
<template v-for="item in dropMenuList" :key="`${item.event}`">
|
||||
<MenuItem
|
||||
v-bind="getAttr(item.event)"
|
||||
@click="handleClickMenu(item)"
|
||||
:disabled="item.disabled"
|
||||
<a-menu-item
|
||||
v-bind="getAttr(item.event)"
|
||||
@click="handleClickMenu(item)"
|
||||
:disabled="item.disabled"
|
||||
>
|
||||
<Popconfirm
|
||||
v-if="popconfirm && item.popConfirm"
|
||||
v-bind="getPopConfirmAttrs(item.popConfirm)"
|
||||
<a-popconfirm
|
||||
v-if="popconfirm && item.popConfirm"
|
||||
v-bind="getPopConfirmAttrs(item.popConfirm)"
|
||||
>
|
||||
<template #icon v-if="item.popConfirm.icon">
|
||||
<Icon :icon="item.popConfirm.icon" />
|
||||
|
@ -22,86 +22,75 @@
|
|||
<Icon :icon="item.icon" v-if="item.icon" />
|
||||
<span class="ml-1">{{ item.text }}</span>
|
||||
</div>
|
||||
</Popconfirm>
|
||||
</a-popconfirm>
|
||||
<template v-else>
|
||||
<Icon :icon="item.icon" v-if="item.icon" />
|
||||
<span class="ml-1">{{ item.text }}</span>
|
||||
</template>
|
||||
</MenuItem>
|
||||
<MenuDivider v-if="item.divider" :key="`d-${item.event}`" />
|
||||
</a-menu-item>
|
||||
<a-menu-divider v-if="item.divider" :key="`d-${item.event}`" />
|
||||
</template>
|
||||
</Menu>
|
||||
</a-menu>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script lang="ts" setup>
|
||||
import { computed, PropType } from 'vue';
|
||||
import type { DropMenu } from './typing';
|
||||
|
||||
import { defineComponent } from 'vue';
|
||||
import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
import { omit } from 'lodash-es';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BasicDropdown',
|
||||
components: {
|
||||
Dropdown,
|
||||
Menu,
|
||||
MenuItem: Menu.Item,
|
||||
MenuDivider: Menu.Divider,
|
||||
Icon,
|
||||
Popconfirm,
|
||||
},
|
||||
props: {
|
||||
popconfirm: Boolean,
|
||||
/**
|
||||
* the trigger mode which executes the drop-down action
|
||||
* @default ['hover']
|
||||
* @type string[]
|
||||
*/
|
||||
trigger: {
|
||||
type: [Array] as PropType<('contextmenu' | 'click' | 'hover')[]>,
|
||||
default: () => {
|
||||
return ['contextmenu'];
|
||||
},
|
||||
},
|
||||
dropMenuList: {
|
||||
type: Array as PropType<(DropMenu & Recordable)[]>,
|
||||
default: () => [],
|
||||
},
|
||||
selectedKeys: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
const ADropdown = Dropdown;
|
||||
const AMenu = Menu;
|
||||
const AMenuItem = Menu.Item;
|
||||
const AMenuDivider = Menu.Divider;
|
||||
const APopconfirm = Popconfirm;
|
||||
|
||||
const props = defineProps({
|
||||
popconfirm: Boolean,
|
||||
/**
|
||||
* the trigger mode which executes the drop-down action
|
||||
* @default ['hover']
|
||||
* @type string[]
|
||||
*/
|
||||
trigger: {
|
||||
type: [Array] as PropType<('contextmenu' | 'click' | 'hover')[]>,
|
||||
default: () => {
|
||||
return ['contextmenu'];
|
||||
},
|
||||
},
|
||||
emits: ['menuEvent'],
|
||||
setup(props, { emit }) {
|
||||
function handleClickMenu(item: DropMenu) {
|
||||
const { event } = item;
|
||||
const menu = props.dropMenuList.find((item) => `${item.event}` === `${event}`);
|
||||
emit('menuEvent', menu);
|
||||
item.onClick?.();
|
||||
}
|
||||
|
||||
const getPopConfirmAttrs = computed(() => {
|
||||
return (attrs) => {
|
||||
const originAttrs = omit(attrs, ['confirm', 'cancel', 'icon']);
|
||||
if (!attrs.onConfirm && attrs.confirm && isFunction(attrs.confirm))
|
||||
originAttrs['onConfirm'] = attrs.confirm;
|
||||
if (!attrs.onCancel && attrs.cancel && isFunction(attrs.cancel))
|
||||
originAttrs['onCancel'] = attrs.cancel;
|
||||
return originAttrs;
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
handleClickMenu,
|
||||
getPopConfirmAttrs,
|
||||
getAttr: (key: string | number) => ({ key }),
|
||||
};
|
||||
dropMenuList: {
|
||||
type: Array as PropType<(DropMenu & Recordable)[]>,
|
||||
default: () => [],
|
||||
},
|
||||
selectedKeys: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['menuEvent']);
|
||||
|
||||
function handleClickMenu(item: DropMenu) {
|
||||
const { event } = item;
|
||||
const menu = props.dropMenuList.find((item) => `${item.event}` === `${event}`);
|
||||
emit('menuEvent', menu);
|
||||
item.onClick?.();
|
||||
}
|
||||
|
||||
const getPopConfirmAttrs = computed(() => {
|
||||
return (attrs) => {
|
||||
const originAttrs = omit(attrs, ['confirm', 'cancel', 'icon']);
|
||||
if (!attrs.onConfirm && attrs.confirm && isFunction(attrs.confirm))
|
||||
originAttrs['onConfirm'] = attrs.confirm;
|
||||
if (!attrs.onCancel && attrs.cancel && isFunction(attrs.cancel))
|
||||
originAttrs['onCancel'] = attrs.cancel;
|
||||
return originAttrs;
|
||||
};
|
||||
});
|
||||
|
||||
const getAttr = (key: string | number) => ({ key });
|
||||
</script>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<div>
|
||||
<input
|
||||
ref="inputRef"
|
||||
type="file"
|
||||
v-show="false"
|
||||
accept=".xlsx, .xls"
|
||||
@change="handleInputClick"
|
||||
ref="inputRef"
|
||||
type="file"
|
||||
v-show="false"
|
||||
accept=".xlsx, .xls"
|
||||
@change="handleInputClick"
|
||||
/>
|
||||
<div @click="handleUpload">
|
||||
<slot></slot>
|
||||
|
@ -15,12 +15,25 @@
|
|||
<script lang="ts">
|
||||
import { defineComponent, ref, unref } from 'vue';
|
||||
import XLSX from 'xlsx';
|
||||
import { dateUtil } from '/@/utils/dateUtil';
|
||||
|
||||
import type { ExcelData } from './typing';
|
||||
export default defineComponent({
|
||||
name: 'ImportExcel',
|
||||
props: {
|
||||
// 日期时间格式。如果不提供或者提供空值,将返回原始Date对象
|
||||
dateFormat: {
|
||||
type: String,
|
||||
},
|
||||
// 时区调整。实验性功能,仅为了解决读取日期时间值有偏差的问题。目前仅提供了+08:00时区的偏差修正值
|
||||
// https://github.com/SheetJS/sheetjs/issues/1470#issuecomment-501108554
|
||||
timeZone: {
|
||||
type: Number,
|
||||
default: 8,
|
||||
},
|
||||
},
|
||||
emits: ['success', 'error'],
|
||||
setup(_, { emit }) {
|
||||
setup(props, { emit }) {
|
||||
const inputRef = ref<HTMLInputElement | null>(null);
|
||||
const loadingRef = ref<Boolean>(false);
|
||||
|
||||
|
@ -51,10 +64,28 @@
|
|||
*/
|
||||
function getExcelData(workbook: XLSX.WorkBook) {
|
||||
const excelData: ExcelData[] = [];
|
||||
const { dateFormat, timeZone } = props;
|
||||
for (const sheetName of workbook.SheetNames) {
|
||||
const worksheet = workbook.Sheets[sheetName];
|
||||
const header: string[] = getHeaderRow(worksheet);
|
||||
const results = XLSX.utils.sheet_to_json(worksheet);
|
||||
let results = XLSX.utils.sheet_to_json(worksheet, {
|
||||
raw: true,
|
||||
dateNF: dateFormat, //Not worked
|
||||
}) as object[];
|
||||
results = results.map((row: object) => {
|
||||
for (let field in row) {
|
||||
if (row[field] instanceof Date) {
|
||||
if (timeZone === 8) {
|
||||
row[field].setSeconds(row[field].getSeconds() + 43);
|
||||
}
|
||||
if (dateFormat) {
|
||||
row[field] = dateUtil(row[field]).format(dateFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
return row;
|
||||
});
|
||||
|
||||
excelData.push({
|
||||
header,
|
||||
results,
|
||||
|
@ -76,7 +107,7 @@
|
|||
reader.onload = async (e) => {
|
||||
try {
|
||||
const data = e.target && e.target.result;
|
||||
const workbook = XLSX.read(data, { type: 'array' });
|
||||
const workbook = XLSX.read(data, { type: 'array', cellDates: true });
|
||||
// console.log(workbook);
|
||||
/* DO SOMETHING WITH workbook HERE */
|
||||
const excelData = getExcelData(workbook);
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
import { withInstall } from '/@/utils';
|
||||
import flowChart from './src/FlowChart.vue';
|
||||
|
||||
export const FlowChart = withInstall(flowChart);
|
|
@ -1,158 +0,0 @@
|
|||
<template>
|
||||
<div class="h-full" :class="prefixCls">
|
||||
<FlowChartToolbar :prefixCls="prefixCls" v-if="toolbar" @view-data="handlePreview" />
|
||||
<div ref="lfElRef" class="h-full"></div>
|
||||
<BasicModal @register="register" title="流程数据" width="50%">
|
||||
<JsonPreview :data="graphData" />
|
||||
</BasicModal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { Ref } from 'vue';
|
||||
import type { Definition } from '@logicflow/core';
|
||||
import { defineComponent, ref, onMounted, unref, nextTick, computed, watch } from 'vue';
|
||||
import FlowChartToolbar from './FlowChartToolbar.vue';
|
||||
import LogicFlow from '@logicflow/core';
|
||||
import { Snapshot, BpmnElement, Menu, DndPanel, SelectionSelect } from '@logicflow/extension';
|
||||
import { useDesign } from '/@/hooks/web/useDesign';
|
||||
import { useAppStore } from '/@/store/modules/app';
|
||||
import { createFlowChartContext } from './useFlowContext';
|
||||
import { toLogicFlowData } from './adpterForTurbo';
|
||||
import { useModal, BasicModal } from '/@/components/Modal';
|
||||
import { JsonPreview } from '/@/components/CodeEditor';
|
||||
import { configDefaultDndPanel } from './config';
|
||||
import '@logicflow/core/dist/style/index.css';
|
||||
import '@logicflow/extension/lib/style/index.css';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FlowChart',
|
||||
components: { BasicModal, FlowChartToolbar, JsonPreview },
|
||||
props: {
|
||||
flowOptions: {
|
||||
type: Object as PropType<Definition>,
|
||||
default: () => ({}),
|
||||
},
|
||||
|
||||
data: {
|
||||
type: Object as PropType<any>,
|
||||
default: () => ({}),
|
||||
},
|
||||
|
||||
toolbar: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
patternItems: {
|
||||
type: Array,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const lfElRef = ref(null);
|
||||
const graphData = ref({});
|
||||
|
||||
const lfInstance = ref(null) as Ref<LogicFlow | null>;
|
||||
|
||||
const { prefixCls } = useDesign('flow-chart');
|
||||
const appStore = useAppStore();
|
||||
const [register, { openModal }] = useModal();
|
||||
createFlowChartContext({
|
||||
logicFlow: lfInstance as unknown as LogicFlow,
|
||||
});
|
||||
|
||||
const getFlowOptions = computed(() => {
|
||||
const { flowOptions } = props;
|
||||
|
||||
const defaultOptions: Partial<Definition> = {
|
||||
grid: true,
|
||||
background: {
|
||||
color: appStore.getDarkMode === 'light' ? '#f7f9ff' : '#151515',
|
||||
},
|
||||
keyboard: {
|
||||
enabled: true,
|
||||
},
|
||||
...flowOptions,
|
||||
};
|
||||
return defaultOptions as Definition;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
() => {
|
||||
onRender();
|
||||
}
|
||||
);
|
||||
|
||||
// TODO
|
||||
// watch(
|
||||
// () => appStore.getDarkMode,
|
||||
// () => {
|
||||
// init();
|
||||
// }
|
||||
// );
|
||||
|
||||
watch(
|
||||
() => unref(getFlowOptions),
|
||||
(options) => {
|
||||
unref(lfInstance)?.updateEditConfig(options);
|
||||
}
|
||||
);
|
||||
|
||||
// init logicFlow
|
||||
async function init() {
|
||||
await nextTick();
|
||||
|
||||
const lfEl = unref(lfElRef);
|
||||
if (!lfEl) {
|
||||
return;
|
||||
}
|
||||
LogicFlow.use(DndPanel);
|
||||
|
||||
// Canvas configuration
|
||||
LogicFlow.use(Snapshot);
|
||||
// Use the bpmn plug-in to introduce bpmn elements, which can be used after conversion in turbo
|
||||
LogicFlow.use(BpmnElement);
|
||||
// Start the right-click menu
|
||||
LogicFlow.use(Menu);
|
||||
LogicFlow.use(SelectionSelect);
|
||||
|
||||
lfInstance.value = new LogicFlow({
|
||||
...unref(getFlowOptions),
|
||||
container: lfEl,
|
||||
});
|
||||
const lf = unref(lfInstance)!;
|
||||
lf?.setDefaultEdgeType('line');
|
||||
onRender();
|
||||
lf?.setPatternItems(props.patternItems || configDefaultDndPanel(lf));
|
||||
}
|
||||
|
||||
async function onRender() {
|
||||
await nextTick();
|
||||
const lf = unref(lfInstance);
|
||||
if (!lf) {
|
||||
return;
|
||||
}
|
||||
const lFData = toLogicFlowData(props.data);
|
||||
lf.render(lFData);
|
||||
}
|
||||
|
||||
function handlePreview() {
|
||||
const lf = unref(lfInstance);
|
||||
if (!lf) {
|
||||
return;
|
||||
}
|
||||
graphData.value = unref(lf).getGraphData();
|
||||
openModal();
|
||||
}
|
||||
|
||||
onMounted(init);
|
||||
|
||||
return {
|
||||
register,
|
||||
prefixCls,
|
||||
lfElRef,
|
||||
handlePreview,
|
||||
graphData,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -1,162 +0,0 @@
|
|||
<template>
|
||||
<div :class="`${prefixCls}-toolbar`" class="flex items-center px-2 py-1">
|
||||
<template v-for="item in toolbarItemList" :key="item.type">
|
||||
<Tooltip placement="bottom" v-bind="item.disabled ? { visible: false } : {}">
|
||||
<template #title>{{ item.tooltip }}</template>
|
||||
<span :class="`${prefixCls}-toolbar__icon`" v-if="item.icon" @click="onControl(item)">
|
||||
<Icon
|
||||
:icon="item.icon"
|
||||
:class="item.disabled ? 'cursor-not-allowed disabeld' : 'cursor-pointer'"
|
||||
/>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Divider v-if="item.separate" type="vertical" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import type { ToolbarConfig } from './types';
|
||||
|
||||
import { defineComponent, ref, onUnmounted, unref, nextTick, watchEffect } from 'vue';
|
||||
import { Divider, Tooltip } from 'ant-design-vue';
|
||||
import { Icon } from '/@/components/Icon';
|
||||
|
||||
import { useFlowChartContext } from './useFlowContext';
|
||||
import { ToolbarTypeEnum } from './enum';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FlowChartToolbar',
|
||||
components: { Icon, Divider, Tooltip },
|
||||
props: {
|
||||
prefixCls: String,
|
||||
},
|
||||
emits: ['view-data'],
|
||||
setup(_, { emit }) {
|
||||
const toolbarItemList = ref<ToolbarConfig[]>([
|
||||
{
|
||||
type: ToolbarTypeEnum.ZOOM_IN,
|
||||
icon: 'codicon:zoom-out',
|
||||
tooltip: '缩小',
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.ZOOM_OUT,
|
||||
icon: 'codicon:zoom-in',
|
||||
tooltip: '放大',
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.RESET_ZOOM,
|
||||
icon: 'codicon:screen-normal',
|
||||
tooltip: '重置比例',
|
||||
},
|
||||
{ separate: true },
|
||||
{
|
||||
type: ToolbarTypeEnum.UNDO,
|
||||
icon: 'ion:arrow-undo-outline',
|
||||
tooltip: '后退',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.REDO,
|
||||
icon: 'ion:arrow-redo-outline',
|
||||
tooltip: '前进',
|
||||
disabled: true,
|
||||
},
|
||||
{ separate: true },
|
||||
{
|
||||
type: ToolbarTypeEnum.SNAPSHOT,
|
||||
icon: 'ion:download-outline',
|
||||
tooltip: '下载',
|
||||
},
|
||||
{
|
||||
type: ToolbarTypeEnum.VIEW_DATA,
|
||||
icon: 'carbon:document-view',
|
||||
tooltip: '查看数据',
|
||||
},
|
||||
]);
|
||||
|
||||
const { logicFlow } = useFlowChartContext();
|
||||
|
||||
function onHistoryChange({ data: { undoAble, redoAble } }) {
|
||||
const itemsList = unref(toolbarItemList);
|
||||
const undoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.UNDO);
|
||||
const redoIndex = itemsList.findIndex((item) => item.type === ToolbarTypeEnum.REDO);
|
||||
if (undoIndex !== -1) {
|
||||
unref(toolbarItemList)[undoIndex].disabled = !undoAble;
|
||||
}
|
||||
if (redoIndex !== -1) {
|
||||
unref(toolbarItemList)[redoIndex].disabled = !redoAble;
|
||||
}
|
||||
}
|
||||
|
||||
const onControl = (item) => {
|
||||
const lf = unref(logicFlow);
|
||||
if (!lf) {
|
||||
return;
|
||||
}
|
||||
switch (item.type) {
|
||||
case ToolbarTypeEnum.ZOOM_IN:
|
||||
lf.zoom();
|
||||
break;
|
||||
case ToolbarTypeEnum.ZOOM_OUT:
|
||||
lf.zoom(true);
|
||||
break;
|
||||
case ToolbarTypeEnum.RESET_ZOOM:
|
||||
lf.resetZoom();
|
||||
break;
|
||||
case ToolbarTypeEnum.UNDO:
|
||||
lf.undo();
|
||||
break;
|
||||
case ToolbarTypeEnum.REDO:
|
||||
lf.redo();
|
||||
break;
|
||||
case ToolbarTypeEnum.SNAPSHOT:
|
||||
lf.getSnapshot();
|
||||
break;
|
||||
case ToolbarTypeEnum.VIEW_DATA:
|
||||
emit('view-data');
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
watchEffect(async () => {
|
||||
if (unref(logicFlow)) {
|
||||
await nextTick();
|
||||
unref(logicFlow)?.on('history:change', onHistoryChange);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
unref(logicFlow)?.off('history:change', onHistoryChange);
|
||||
});
|
||||
return { toolbarItemList, onControl };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less">
|
||||
@prefix-cls: ~'@{namespace}-flow-chart-toolbar';
|
||||
|
||||
html[data-theme='dark'] {
|
||||
.lf-dnd {
|
||||
background: #080808;
|
||||
}
|
||||
}
|
||||
.@{prefix-cls} {
|
||||
height: 36px;
|
||||
background-color: @app-content-background;
|
||||
border-bottom: 1px solid @border-color-base;
|
||||
|
||||
.disabeld {
|
||||
color: @disabled-color;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
display: inline-block;
|
||||
padding: 2px 4px;
|
||||
margin-right: 10px;
|
||||
|
||||
&:hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,75 +0,0 @@
|
|||
const TurboType = {
|
||||
SEQUENCE_FLOW: 1,
|
||||
START_EVENT: 2,
|
||||
END_EVENT: 3,
|
||||
USER_TASK: 4,
|
||||
SERVICE_TASK: 5,
|
||||
EXCLUSIVE_GATEWAY: 6,
|
||||
};
|
||||
|
||||
function convertFlowElementToEdge(element) {
|
||||
const { incoming, outgoing, properties, key } = element;
|
||||
const { text, startPoint, endPoint, pointsList, logicFlowType } = properties;
|
||||
const edge = {
|
||||
id: key,
|
||||
type: logicFlowType,
|
||||
sourceNodeId: incoming[0],
|
||||
targetNodeId: outgoing[0],
|
||||
text,
|
||||
startPoint,
|
||||
endPoint,
|
||||
pointsList,
|
||||
properties: {},
|
||||
};
|
||||
const excludeProperties = ['startPoint', 'endPoint', 'pointsList', 'text', 'logicFlowType'];
|
||||
Object.keys(element.properties).forEach((property) => {
|
||||
if (excludeProperties.indexOf(property) === -1) {
|
||||
edge.properties[property] = element.properties[property];
|
||||
}
|
||||
});
|
||||
return edge;
|
||||
}
|
||||
|
||||
function convertFlowElementToNode(element) {
|
||||
const { properties, key } = element;
|
||||
const { x, y, text, logicFlowType } = properties;
|
||||
const node = {
|
||||
id: key,
|
||||
type: logicFlowType,
|
||||
x,
|
||||
y,
|
||||
text,
|
||||
properties: {},
|
||||
};
|
||||
const excludeProperties = ['x', 'y', 'text', 'logicFlowType'];
|
||||
Object.keys(element.properties).forEach((property) => {
|
||||
if (excludeProperties.indexOf(property) === -1) {
|
||||
node.properties[property] = element.properties[property];
|
||||
}
|
||||
});
|
||||
return node;
|
||||
}
|
||||
|
||||
export function toLogicFlowData(data) {
|
||||
const lfData: {
|
||||
// TODO type
|
||||
nodes: any[];
|
||||
edges: any[];
|
||||
} = {
|
||||
nodes: [],
|
||||
edges: [],
|
||||
};
|
||||
const list = data.flowElementList;
|
||||
list &&
|
||||
list.length > 0 &&
|
||||
list.forEach((element) => {
|
||||
if (element.type === TurboType.SEQUENCE_FLOW) {
|
||||
const edge = convertFlowElementToEdge(element);
|
||||
lfData.edges.push(edge);
|
||||
} else {
|
||||
const node = convertFlowElementToNode(element);
|
||||
lfData.nodes.push(node);
|
||||
}
|
||||
});
|
||||
return lfData;
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
export const nodeList = [
|
||||
{
|
||||
text: '开始',
|
||||
type: 'start',
|
||||
class: 'node-start',
|
||||
},
|
||||
{
|
||||
text: '矩形',
|
||||
type: 'rect',
|
||||
class: 'node-rect',
|
||||
},
|
||||
{
|
||||
type: 'user',
|
||||
text: '用户',
|
||||
class: 'node-user',
|
||||
},
|
||||
{
|
||||
type: 'push',
|
||||
text: '推送',
|
||||
class: 'node-push',
|
||||
},
|
||||
{
|
||||
type: 'download',
|
||||
text: '位置',
|
||||
class: 'node-download',
|
||||
},
|
||||
{
|
||||
type: 'end',
|
||||
text: '结束',
|
||||
class: 'node-end',
|
||||
},
|
||||
];
|
||||
|
||||
export const BpmnNode = [
|
||||
{
|
||||
type: 'bpmn:startEvent',
|
||||
text: '开始',
|
||||
class: 'bpmn-start',
|
||||
},
|
||||
{
|
||||
type: 'bpmn:endEvent',
|
||||
text: '结束',
|
||||
class: 'bpmn-end',
|
||||
},
|
||||
{
|
||||
type: 'bpmn:exclusiveGateway',
|
||||
text: '网关',
|
||||
class: 'bpmn-exclusiveGateway',
|
||||
},
|
||||
{
|
||||
type: 'bpmn:userTask',
|
||||
text: '用户',
|
||||
class: 'bpmn-user',
|
||||
},
|
||||
];
|
||||
|
||||
export function configDefaultDndPanel(lf) {
|
||||
return [
|
||||
{
|
||||
text: '选区',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAOVJREFUOBGtVMENwzAIjKP++2026ETdpv10iy7WFbqFyyW6GBywLCv5gI+Dw2Bluj1znuSjhb99Gkn6QILDY2imo60p8nsnc9bEo3+QJ+AKHfMdZHnl78wyTnyHZD53Zzx73MRSgYvnqgCUHj6gwdck7Zsp1VOrz0Uz8NbKunzAW+Gu4fYW28bUYutYlzSa7B84Fh7d1kjLwhcSdYAYrdkMQVpsBr5XgDGuXwQfQr0y9zwLda+DUYXLaGKdd2ZTtvbolaO87pdo24hP7ov16N0zArH1ur3iwJpXxm+v7oAJNR4JEP8DoAuSFEkYH7cAAAAASUVORK5CYII=',
|
||||
callback: () => {
|
||||
lf.updateEditConfig({
|
||||
stopMoveGraph: true,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'circle',
|
||||
text: '开始',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAnBJREFUOBGdVL1rU1EcPfdGBddmaZLiEhdx1MHZQXApraCzQ7GKLgoRBxMfcRELuihWKcXFRcEWF8HBf0DdDCKYRZpnl7p0svLe9Zzbd29eQhTbC8nv+9zf130AT63jvooOGS8Vf9Nt5zxba7sXQwODfkWpkbjTQfCGUd9gIp3uuPP8bZ946g56dYQvnBg+b1HB8VIQmMFrazKcKSvFW2dQTxJnJdQ77urmXWOMBCmXM2Rke4S7UAW+/8ywwFoewmBps2tu7mbTdp8VMOkIRAkKfrVawalJTtIliclFbaOBqa0M2xImHeVIfd/nKAfVq/LGnPss5Kh00VEdSzfwnBXPUpmykNss4lUI9C1ga+8PNrBD5YeqRY2Zz8PhjooIbfJXjowvQJBqkmEkVnktWhwu2SM7SMx7Cj0N9IC0oQXRo8xwAGzQms+xrB/nNSUWVveI48ayrFGyC2+E2C+aWrZHXvOuz+CiV6iycWe1Rd1Q6+QUG07nb5SbPrL4426d+9E1axKjY3AoRrlEeSQo2Eu0T6BWAAr6COhTcWjRaYfKG5csnvytvUr/WY4rrPMB53Uo7jZRjXaG6/CFfNMaXEu75nG47X+oepU7PKJvvzGDY1YLSKHJrK7vFUwXKkaxwhCW3u+sDFMVrIju54RYYbFKpALZAo7sB6wcKyyrd+aBMryMT2gPyD6GsQoRFkGHr14TthZni9ck0z+Pnmee460mHXbRAypKNy3nuMdrWgVKj8YVV8E7PSzp1BZ9SJnJAsXdryw/h5ctboUVi4AFiCd+lQaYMw5z3LGTBKjLQOeUF35k89f58Vv/tGh+l+PE/wG0rgfIUbZK5AAAAABJRU5ErkJggg==',
|
||||
},
|
||||
{
|
||||
type: 'rect',
|
||||
text: '用户任务',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==',
|
||||
cls: 'important-node',
|
||||
},
|
||||
{
|
||||
type: 'rect',
|
||||
text: '系统任务',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==',
|
||||
cls: 'import_icon',
|
||||
},
|
||||
{
|
||||
type: 'diamond',
|
||||
text: '条件判断',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAAHeEJUAAAAABGdBTUEAALGPC/xhBQAAAvVJREFUOBGNVEFrE0EU/mY3bQoiFlOkaUJrQUQoWMGePLX24EH0IIoHKQiCV0G8iE1covgLiqA/QTzVm1JPogc9tIJYFaQtlhQxqYjSpunu+L7JvmUTU3AgmTfvffPNN++9WSA1DO182f6xwILzD5btfAoQmwL5KJEwiQyVbSVZ0IgRyV6PTpIJ81E5ZvqfHQR0HUOBHW4L5Et2kQ6Zf7iAOhTFAA8s0pEP7AXO1uAA52SbqGk6h/6J45LaLhO64ByfcUzM39V7ZiAdS2yCePPEIQYvTUHqM/n7dgQNfBKWPjpF4ISk8q3J4nB11qw6X8l+FsF3EhlkEMfrjIer3wJTLwS2aCNcj4DbGxXTw00JmAuO+Ni6bBxVUCvS5d9aa04+so4pHW5jLTywuXAL7jJ+D06sl82Sgl2JuVBQn498zkc2bGKxULHjCnSMadBKYDYYHAtsby1EQ5lNGrQd4Y3v4Zo0XdGEmDno46yCM9Tk+RiJmUYHS/aXHPNTcjxcbTFna000PFJHIVZ5lFRqRpJWk9/+QtlOUYJj9HG5pVFEU7zqIYDVsw2s+AJaD8wTd2umgSCCyUxgGsS1Y6TBwXQQTFuZaHcd8gAGioE90hlsY+wMcs30RduYtxanjMGal8H5dMW67dmT1JFtYUEe8LiQLRsPZ6IIc7A4J5tqco3T0pnv/4u0kyzrYUq7gASuEyI8VXKvB9Odytv6jS/PNaZBln0nioJG/AVQRZvApOdhjj3Jt8QC8Im09SafwdBdvIpztpxWxpeKCC+EsFdS8DCyuCn2munFpL7ctHKp+Xc5cMybeIyMAN33SPL3ZR9QV1XVwLyzHm6Iv0/yeUuUb7PPlZC4D4HZkeu6dpF4v9j9MreGtMbxMMRLIcjJic9yHi7WQ3yVKzZVWUr5UrViJvn1FfUlwe/KYVfYyWRLSGNu16hR01U9IacajXPei0wx/5BqgInvJN+MMNtNme7ReU9SBbgntovn0kKHpFg7UogZvaZiOue/q1SBo9ktHzQAAAAASUVORK5CYII=',
|
||||
},
|
||||
{
|
||||
type: 'circle',
|
||||
text: '结束',
|
||||
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAA1BJREFUOBFtVE1IVUEYPXOf+tq40Y3vPcmFIdSjIorWoRG0ERWUgnb5FwVhYQSl72oUoZAboxKNFtWiwKRN0M+jpfSzqJAQclHo001tKkjl3emc8V69igP3znzfnO/M9zcDcKT67azmjYWTwl9Vn7Vumeqzj1DVb6cleQY4oAVnIOPb+mKAGxQmKI5CWNJ2aLPatxWa3aB9K7/fB+/Z0jUF6TmMlFLQqrkECWQzOZxYGjTlOl8eeKaIY5yHnFn486xBustDjWT6dG7pmjHOJd+33t0iitTPkK6tEvjxq4h2MozQ6WFSX/LkDUGfFwfhEZj1Auz/U4pyAi5Sznd7uKzznXeVHlI/Aywmk6j7fsUsEuCGADrWARXXwjxWQsUbIupDHJI7kF5dRktg0eN81IbiZXiTESic50iwS+t1oJgL83jAiBupLDCQqwziaWSoAFSeIR3P5Xv5az00wyIn35QRYTwdSYbz8pH8fxUUAtxnFvYmEmgI0wYXUXcCCSpeEVpXlsRhBnCEATxWylL9+EKCAYhe1NGstUa6356kS9NVvt3DU2fd+Wtbm/+lSbylJqsqkSm9CRhvoJVlvKPvF1RKY/FcPn5j4UfIMLn8D4UYb54BNsilTDXKnF4CfTobA0FpoW/LSp306wkXM+XaOJhZaFkcNM82ASNAWMrhrUbRfmyeI1FvRBTpN06WKxa9BK0o2E4Pd3zfBBEwPsv9sQBnmLVbLEIZ/Xe9LYwJu/Er17W6HYVBc7vmuk0xUQ+pqxdom5Fnp55SiytXLPYoMXNM4u4SNSCFWnrVIzKG3EGyMXo6n/BQOe+bX3FClY4PwydVhthOZ9NnS+ntiLh0fxtlUJHAuGaFoVmttpVMeum0p3WEXbcll94l1wM/gZ0Ccczop77VvN2I7TlsZCsuXf1WHvWEhjO8DPtyOVg2/mvK9QqboEth+7pD6NUQC1HN/TwvydGBARi9MZSzLE4b8Ru3XhX2PBxf8E1er2A6516o0w4sIA+lwURhAON82Kwe2iDAC1Watq4XHaGQ7skLcFOtI5lDxuM2gZe6WFIotPAhbaeYlU4to5cuarF1QrcZ/lwrLaCJl66JBocYZnrNlvm2+MBCTmUymPrYZVbjdlr/BxlMjmNmNI3SAAAAAElFTkSuQmCC',
|
||||
},
|
||||
];
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
export enum ToolbarTypeEnum {
|
||||
ZOOM_IN = 'zoomIn',
|
||||
ZOOM_OUT = 'zoomOut',
|
||||
RESET_ZOOM = 'resetZoom',
|
||||
|
||||
UNDO = 'undo',
|
||||
REDO = 'redo',
|
||||
|
||||
SNAPSHOT = 'snapshot',
|
||||
VIEW_DATA = 'viewData',
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
import { NodeConfig } from '@logicflow/core';
|
||||
import { ToolbarTypeEnum } from './enum';
|
||||
|
||||
export interface NodeItem extends NodeConfig {
|
||||
icon: string;
|
||||
}
|
||||
|
||||
export interface ToolbarConfig {
|
||||
type?: string | ToolbarTypeEnum;
|
||||
tooltip?: string | boolean;
|
||||
icon?: string;
|
||||
disabled?: boolean;
|
||||
separate?: boolean;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import type LogicFlow from '@logicflow/core';
|
||||
|
||||
import { provide, inject } from 'vue';
|
||||
|
||||
const key = Symbol('flow-chart');
|
||||
|
||||
type Instance = {
|
||||
logicFlow: LogicFlow;
|
||||
};
|
||||
|
||||
export function createFlowChartContext(instance: Instance) {
|
||||
provide(key, instance);
|
||||
}
|
||||
|
||||
export function useFlowChartContext(): Instance {
|
||||
return inject(key) as Instance;
|
||||
}
|
|
@ -7,8 +7,29 @@ export { useComponentRegister } from './src/hooks/useComponentRegister';
|
|||
export { useForm } from './src/hooks/useForm';
|
||||
|
||||
export { default as ApiSelect } from './src/components/ApiSelect.vue';
|
||||
export { default as JAreaLinkage } from './src/components/JAreaLinkage.vue';
|
||||
export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue';
|
||||
export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue';
|
||||
export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue';
|
||||
//Jeecg自定义组件
|
||||
export { default as JAreaLinkage } from './src/jeecg/components/JAreaLinkage.vue';
|
||||
export { default as JSelectUser } from './src/jeecg/components/JSelectUser.vue';
|
||||
export { default as JSelectDept } from './src/jeecg/components/JSelectDept.vue';
|
||||
export { default as JCodeEditor } from './src/jeecg/components/JCodeEditor.vue';
|
||||
export { default as JCategorySelect } from './src/jeecg/components/JCategorySelect.vue';
|
||||
export { default as JSelectMultiple } from './src/jeecg/components/JSelectMultiple.vue';
|
||||
export { default as JPopup } from './src/jeecg/components/JPopup.vue';
|
||||
export { default as JAreaSelect } from './src/jeecg/components/JAreaSelect.vue';
|
||||
export { JEasyCron, JEasyCronInner, JEasyCronModal } from '/@/components/Form/src/jeecg/components/JEasyCron'
|
||||
export { default as JCheckbox } from './src/jeecg/components/JCheckbox.vue';
|
||||
export { default as JInput } from './src/jeecg/components/JInput.vue';
|
||||
export { default as JEllipsis } from './src/jeecg/components/JEllipsis.vue';
|
||||
export { default as JDictSelectTag } from './src/jeecg/components/JDictSelectTag.vue';
|
||||
export { default as JTreeSelect } from './src/jeecg/components/JTreeSelect.vue';
|
||||
export { default as JSearchSelect } from './src/jeecg/components/JSearchSelect.vue';
|
||||
export { default as JSelectUserByDept } from './src/jeecg/components/JSelectUserByDept.vue';
|
||||
export { default as JEditor } from './src/jeecg/components/JEditor.vue';
|
||||
export { default as JImageUpload } from './src/jeecg/components/JImageUpload.vue';
|
||||
// Jeecg自定义校验
|
||||
export { JCronValidator } from '/@/components/Form/src/jeecg/components/JEasyCron'
|
||||
|
||||
export { BasicForm };
|
||||
|
|
|
@ -1,23 +1,9 @@
|
|||
<template>
|
||||
<Form
|
||||
v-bind="getBindValue"
|
||||
:class="getFormClass"
|
||||
ref="formElRef"
|
||||
:model="formModel"
|
||||
@keypress.enter="handleEnterPress"
|
||||
>
|
||||
<Form v-bind="getBindValue" :class="getFormClass" ref="formElRef" :model="formModel" @keypress.enter="handleEnterPress">
|
||||
<Row v-bind="getRow">
|
||||
<slot name="formHeader"></slot>
|
||||
<template v-for="schema in getSchema" :key="schema.field">
|
||||
<FormItem
|
||||
:tableAction="tableAction"
|
||||
:formActionType="formActionType"
|
||||
:schema="schema"
|
||||
:formProps="getProps"
|
||||
:allDefaultValues="defaultValueRef"
|
||||
:formModel="formModel"
|
||||
:setFormModel="setFormModel"
|
||||
>
|
||||
<FormItem :tableAction="tableAction" :formActionType="formActionType" :schema="schema" :formProps="getProps" :allDefaultValues="defaultValueRef" :formModel="formModel" :setFormModel="setFormModel">
|
||||
<template #[item]="data" v-for="item in Object.keys($slots)">
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
|
@ -25,10 +11,7 @@
|
|||
</template>
|
||||
|
||||
<FormAction v-bind="getFormActionBindProps" @toggle-advanced="handleToggleAdvanced">
|
||||
<template
|
||||
#[item]="data"
|
||||
v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']"
|
||||
>
|
||||
<template #[item]="data" v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']">
|
||||
<slot :name="item" v-bind="data || {}"></slot>
|
||||
</template>
|
||||
</FormAction>
|
||||
|
@ -72,8 +55,9 @@
|
|||
const modalFn = useModalContext();
|
||||
|
||||
const advanceState = reactive<AdvanceState>({
|
||||
isAdvanced: true,
|
||||
hideAdvanceBtn: false,
|
||||
// 默认是收起状态
|
||||
isAdvanced: false,
|
||||
hideAdvanceBtn: true,
|
||||
isLoad: false,
|
||||
actionSpan: 6,
|
||||
});
|
||||
|
|
|
@ -20,15 +20,42 @@ import {
|
|||
Rate,
|
||||
Divider,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import ApiRadioGroup from './components/ApiRadioGroup.vue';
|
||||
import RadioButtonGroup from './components/RadioButtonGroup.vue';
|
||||
import ApiSelect from './components/ApiSelect.vue';
|
||||
import JAreaLinkage from './components/JAreaLinkage.vue';
|
||||
import ApiTreeSelect from './components/ApiTreeSelect.vue';
|
||||
import { BasicUpload } from '/@/components/Upload';
|
||||
import { StrengthMeter } from '/@/components/StrengthMeter';
|
||||
import { IconPicker } from '/@/components/Icon';
|
||||
import { CountdownInput } from '/@/components/CountDown';
|
||||
//自定义组件
|
||||
import JAreaLinkage from './jeecg/components/JAreaLinkage.vue';
|
||||
import JSelectUser from './jeecg/components/JSelectUser.vue';
|
||||
import JSelectPosition from './jeecg/components/JSelectPosition.vue';
|
||||
import JSelectRole from './jeecg/components/JSelectRole.vue';
|
||||
import JImageUpload from './jeecg/components/JImageUpload.vue';
|
||||
import JDictSelectTag from './jeecg/components/JDictSelectTag.vue';
|
||||
import JSelectDept from './jeecg/components/JSelectDept.vue';
|
||||
import JAreaSelect from './jeecg/components/JAreaSelect.vue';
|
||||
import JEditor from './jeecg/components/JEditor.vue';
|
||||
import JMarkdownEditor from './jeecg/components/JMarkdownEditor.vue';
|
||||
import JSelectInput from './jeecg/components/JSelectInput.vue';
|
||||
import JCodeEditor from './jeecg/components/JCodeEditor.vue';
|
||||
import JCategorySelect from './jeecg/components/JCategorySelect.vue';
|
||||
import JSelectMultiple from './jeecg/components/JSelectMultiple.vue';
|
||||
import JPopup from './jeecg/components/JPopup.vue';
|
||||
import JSwitch from './jeecg/components/JSwitch.vue';
|
||||
import JTreeDict from './jeecg/components/JTreeDict.vue';
|
||||
import JInputPop from './jeecg/components/JInputPop.vue';
|
||||
import { JEasyCron } from './jeecg/components/JEasyCron'
|
||||
import JCheckbox from './jeecg/components/JCheckbox.vue';
|
||||
import JInput from './jeecg/components/JInput.vue';
|
||||
import JTreeSelect from './jeecg/components/JTreeSelect.vue';
|
||||
import JEllipsis from './jeecg/components/JEllipsis.vue';
|
||||
import JSelectUserByDept from './jeecg/components/JSelectUserByDept.vue';
|
||||
import JUpload from './jeecg/components/JUpload/JUpload.vue'
|
||||
import JSearchSelect from './jeecg/components/JSearchSelect.vue'
|
||||
import JAddInput from './jeecg/components/JAddInput.vue'
|
||||
|
||||
const componentMap = new Map<ComponentType, Component>();
|
||||
|
||||
|
@ -42,9 +69,9 @@ componentMap.set('AutoComplete', AutoComplete);
|
|||
|
||||
componentMap.set('Select', Select);
|
||||
componentMap.set('ApiSelect', ApiSelect);
|
||||
componentMap.set('JAreaLinkage', JAreaLinkage);
|
||||
componentMap.set('TreeSelect', TreeSelect);
|
||||
componentMap.set('ApiTreeSelect', ApiTreeSelect);
|
||||
componentMap.set('ApiRadioGroup', ApiRadioGroup);
|
||||
componentMap.set('Switch', Switch);
|
||||
componentMap.set('RadioButtonGroup', RadioButtonGroup);
|
||||
componentMap.set('RadioGroup', Radio.Group);
|
||||
|
@ -66,6 +93,35 @@ componentMap.set('InputCountDown', CountdownInput);
|
|||
componentMap.set('Upload', BasicUpload);
|
||||
componentMap.set('Divider', Divider);
|
||||
|
||||
//注册自定义组件
|
||||
componentMap.set('JAreaLinkage', JAreaLinkage);
|
||||
componentMap.set('JSelectPosition', JSelectPosition);
|
||||
componentMap.set('JSelectUser', JSelectUser);
|
||||
componentMap.set('JSelectRole', JSelectRole);
|
||||
componentMap.set('JImageUpload', JImageUpload);
|
||||
componentMap.set('JDictSelectTag', JDictSelectTag);
|
||||
componentMap.set('JSelectDept', JSelectDept);
|
||||
componentMap.set('JAreaSelect', JAreaSelect);
|
||||
componentMap.set('JEditor', JEditor);
|
||||
componentMap.set('JMarkdownEditor', JMarkdownEditor);
|
||||
componentMap.set('JSelectInput', JSelectInput);
|
||||
componentMap.set('JCodeEditor', JCodeEditor);
|
||||
componentMap.set('JCategorySelect', JCategorySelect);
|
||||
componentMap.set('JSelectMultiple', JSelectMultiple);
|
||||
componentMap.set('JPopup', JPopup);
|
||||
componentMap.set('JSwitch', JSwitch);
|
||||
componentMap.set('JTreeDict', JTreeDict);
|
||||
componentMap.set('JInputPop', JInputPop);
|
||||
componentMap.set('JEasyCron', JEasyCron);
|
||||
componentMap.set('JCheckbox', JCheckbox);
|
||||
componentMap.set('JInput', JInput);
|
||||
componentMap.set('JTreeSelect', JTreeSelect);
|
||||
componentMap.set('JEllipsis', JEllipsis);
|
||||
componentMap.set('JSelectUserByDept', JSelectUserByDept);
|
||||
componentMap.set('JUpload', JUpload);
|
||||
componentMap.set('JSearchSelect', JSearchSelect);
|
||||
componentMap.set('JAddInput', JAddInput);
|
||||
|
||||
export function add(compName: ComponentType, component: Component) {
|
||||
componentMap.set(compName, component);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
<!--
|
||||
* @Description:It is troublesome to implement radio button group in the form. So it is extracted independently as a separate component
|
||||
-->
|
||||
<template>
|
||||
<RadioGroup v-bind="attrs" v-model:value="state" button-style="solid" @change="handleChange">
|
||||
<template v-for="item in getOptions" :key="`${item.value}`">
|
||||
<RadioButton v-if="props.isBtn" :value="item.value" :disabled="item.disabled">
|
||||
{{ item.label }}
|
||||
</RadioButton>
|
||||
<Radio v-else :value="item.value" :disabled="item.disabled">
|
||||
{{ item.label }}
|
||||
</Radio>
|
||||
</template>
|
||||
</RadioGroup>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType, ref, watchEffect, computed, unref, watch } from 'vue';
|
||||
import { Radio } from 'ant-design-vue';
|
||||
import { isFunction } from '/@/utils/is';
|
||||
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { get, omit } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
type OptionsItem = { label: string; value: string | number | boolean; disabled?: boolean };
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ApiRadioGroup',
|
||||
components: {
|
||||
RadioGroup: Radio.Group,
|
||||
RadioButton: Radio.Button,
|
||||
Radio,
|
||||
},
|
||||
props: {
|
||||
api: {
|
||||
type: Function as PropType<(arg?: Recordable | string) => Promise<OptionsItem[]>>,
|
||||
default: null,
|
||||
},
|
||||
params: {
|
||||
type: [Object, String] as PropType<Recordable | string>,
|
||||
default: () => ({}),
|
||||
},
|
||||
value: {
|
||||
type: [String, Number, Boolean] as PropType<string | number | boolean>,
|
||||
},
|
||||
isBtn: {
|
||||
type: [Boolean] as PropType<boolean>,
|
||||
default: false,
|
||||
},
|
||||
numberToString: propTypes.bool,
|
||||
resultField: propTypes.string.def(''),
|
||||
labelField: propTypes.string.def('label'),
|
||||
valueField: propTypes.string.def('value'),
|
||||
immediate: propTypes.bool.def(true),
|
||||
},
|
||||
emits: ['options-change', 'change'],
|
||||
setup(props, { emit }) {
|
||||
const options = ref<OptionsItem[]>([]);
|
||||
const loading = ref(false);
|
||||
const isFirstLoad = ref(true);
|
||||
const emitData = ref<any[]>([]);
|
||||
const attrs = useAttrs();
|
||||
const { t } = useI18n();
|
||||
// Embedded in the form, just use the hook binding to perform form verification
|
||||
const [state] = useRuleFormItem(props);
|
||||
|
||||
// Processing options value
|
||||
const getOptions = computed(() => {
|
||||
const { labelField, valueField, numberToString } = props;
|
||||
|
||||
return unref(options).reduce((prev, next: Recordable) => {
|
||||
if (next) {
|
||||
const value = next[valueField];
|
||||
prev.push({
|
||||
label: next[labelField],
|
||||
value: numberToString ? `${value}` : value,
|
||||
...omit(next, [labelField, valueField]),
|
||||
});
|
||||
}
|
||||
return prev;
|
||||
}, [] as OptionsItem[]);
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
props.immediate && fetch();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.params,
|
||||
() => {
|
||||
!unref(isFirstLoad) && fetch();
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
async function fetch() {
|
||||
const api = props.api;
|
||||
if (!api || !isFunction(api)) return;
|
||||
options.value = [];
|
||||
try {
|
||||
loading.value = true;
|
||||
const res = await api(props.params);
|
||||
if (Array.isArray(res)) {
|
||||
options.value = res;
|
||||
emitChange();
|
||||
return;
|
||||
}
|
||||
if (props.resultField) {
|
||||
options.value = get(res, props.resultField) || [];
|
||||
}
|
||||
emitChange();
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function emitChange() {
|
||||
emit('options-change', unref(getOptions));
|
||||
}
|
||||
|
||||
function handleChange(_, ...args) {
|
||||
emitData.value = args;
|
||||
}
|
||||
|
||||
return { state, getOptions, attrs, loading, t, handleChange, props };
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<Select
|
||||
@dropdownVisibleChange="handleFetch"
|
||||
v-bind="attrs"
|
||||
v-bind="$attrs"
|
||||
@change="handleChange"
|
||||
:options="getOptions"
|
||||
v-model:value="state"
|
||||
|
@ -41,12 +41,7 @@
|
|||
},
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
value: propTypes.oneOfType([
|
||||
propTypes.object,
|
||||
propTypes.number,
|
||||
propTypes.string,
|
||||
propTypes.array,
|
||||
]),
|
||||
value: [Array, Object, String, Number],
|
||||
numberToString: propTypes.bool,
|
||||
api: {
|
||||
type: Function as PropType<(arg?: Recordable) => Promise<OptionsItem[]>>,
|
||||
|
@ -73,18 +68,17 @@
|
|||
const { t } = useI18n();
|
||||
|
||||
// Embedded in the form, just use the hook binding to perform form verification
|
||||
const [state] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
const [state, setState] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
|
||||
const getOptions = computed(() => {
|
||||
const { labelField, valueField, numberToString } = props;
|
||||
|
||||
return unref(options).reduce((prev, next: Recordable) => {
|
||||
if (next) {
|
||||
const value = next[valueField];
|
||||
prev.push({
|
||||
label: next[labelField],
|
||||
value: numberToString ? `${value}` : value,
|
||||
...omit(next, [labelField, valueField]),
|
||||
...omit(next, [labelField, valueField]),
|
||||
label: next[labelField],
|
||||
value: numberToString ? `${value}` : value,
|
||||
});
|
||||
}
|
||||
return prev;
|
||||
|
@ -123,6 +117,9 @@
|
|||
console.warn(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
//--@updateBy-begin----author:liusq---date:20210914------for:判断选择模式,multiple多选情况下的value值空的情况下需要设置为数组------
|
||||
unref(attrs).mode == 'multiple' && !Array.isArray(unref(state)) && setState([])
|
||||
//--@updateBy-end----author:liusq---date:20210914------for:判断选择模式,multiple多选情况下的value值空的情况下需要设置为数组------
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
watch(
|
||||
() => props.params,
|
||||
() => {
|
||||
isFirstLoaded.value && fetch();
|
||||
!unref(isFirstLoaded) && fetch();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
|
|
@ -2,16 +2,20 @@
|
|||
<a-col v-bind="actionColOpt" v-if="showActionButtonGroup">
|
||||
<div style="width: 100%" :style="{ textAlign: actionColOpt.style.textAlign }">
|
||||
<FormItem>
|
||||
<slot name="resetBefore"></slot>
|
||||
<Button type="default" class="mr-2" v-bind="getResetBtnOptions" @click="resetAction" v-if="showResetButton">
|
||||
{{ getResetBtnOptions.text }}
|
||||
</Button>
|
||||
<slot name="submitBefore"></slot>
|
||||
|
||||
<!-- update-begin-author:zyf Date:20211213 for:调换按钮前后位置-->
|
||||
<slot name="submitBefore"></slot>
|
||||
<Button type="primary" class="mr-2" v-bind="getSubmitBtnOptions" @click="submitAction" v-if="showSubmitButton">
|
||||
<Icon icon="ant-design:search-outlined"></Icon>
|
||||
{{ getSubmitBtnOptions.text }}
|
||||
</Button>
|
||||
|
||||
<slot name="resetBefore"></slot>
|
||||
<Button type="default" class="mr-2" v-bind="getResetBtnOptions" @click="resetAction" v-if="showResetButton">
|
||||
<Icon icon="ic:baseline-restart-alt"></Icon>
|
||||
{{ getResetBtnOptions.text }}
|
||||
</Button>
|
||||
<!-- update-end-author:zyf Date:20211213 for:调换按钮前后位置-->
|
||||
|
||||
<slot name="advanceBefore"></slot>
|
||||
<Button type="link" size="small" @click="toggleAdvanced" v-if="showAdvancedButton && !hideAdvanceBtn">
|
||||
{{ isAdvanced ? t('component.form.putAway') : t('component.form.unfold') }}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
<script lang="tsx">
|
||||
import type { PropType, Ref } from 'vue';
|
||||
import type { FormActionType, FormProps } from '../types/form';
|
||||
import type { FormSchema } from '../types/form';
|
||||
import type { ValidationRule } from 'ant-design-vue/lib/form/Form';
|
||||
import type { TableActionType } from '/@/components/Table';
|
||||
import { defineComponent, computed, unref, toRefs } from 'vue';
|
||||
import { Form, Col, Divider } from 'ant-design-vue';
|
||||
import { componentMap } from '../componentMap';
|
||||
import { BasicHelp } from '/@/components/Basic';
|
||||
import { isBoolean, isFunction, isNull } from '/@/utils/is';
|
||||
import { getSlot } from '/@/utils/helper/tsxHelper';
|
||||
import { createPlaceholderMessage, setComponentRuleType } from '../helper';
|
||||
import { upperFirst, cloneDeep } from 'lodash-es';
|
||||
import { useItemLabelWidth } from '../hooks/useLabelWidth';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import type {PropType, Ref} from 'vue';
|
||||
import type {FormActionType, FormProps} from '../types/form';
|
||||
import type {FormSchema} from '../types/form';
|
||||
import type {ValidationRule} from 'ant-design-vue/lib/form/Form';
|
||||
import type {TableActionType} from '/@/components/Table';
|
||||
import {defineComponent, computed, unref, toRefs} from 'vue';
|
||||
import {Form, Col, Divider} from 'ant-design-vue';
|
||||
import {componentMap} from '../componentMap';
|
||||
import {BasicHelp} from '/@/components/Basic';
|
||||
import {isBoolean, isFunction, isNull} from '/@/utils/is';
|
||||
import {getSlot} from '/@/utils/helper/tsxHelper';
|
||||
import {createPlaceholderMessage, setComponentRuleType} from '../helper';
|
||||
import {upperFirst, cloneDeep} from 'lodash-es';
|
||||
import {useItemLabelWidth} from '../hooks/useLabelWidth';
|
||||
import {useI18n} from '/@/hooks/web/useI18n';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BasicFormItem',
|
||||
|
@ -46,10 +46,10 @@
|
|||
type: Object as PropType<FormActionType>,
|
||||
},
|
||||
},
|
||||
setup(props, { slots }) {
|
||||
const { t } = useI18n();
|
||||
setup(props, {slots}) {
|
||||
const {t} = useI18n();
|
||||
|
||||
const { schema, formProps } = toRefs(props) as {
|
||||
const {schema, formProps} = toRefs(props) as {
|
||||
schema: Ref<FormSchema>;
|
||||
formProps: Ref<FormProps>;
|
||||
};
|
||||
|
@ -57,8 +57,8 @@
|
|||
const itemLabelWidthProp = useItemLabelWidth(schema, formProps);
|
||||
|
||||
const getValues = computed(() => {
|
||||
const { allDefaultValues, formModel, schema } = props;
|
||||
const { mergeDynamicData } = props.formProps;
|
||||
const {allDefaultValues, formModel, schema} = props;
|
||||
const {mergeDynamicData} = props.formProps;
|
||||
return {
|
||||
field: schema.field,
|
||||
model: formModel,
|
||||
|
@ -72,13 +72,13 @@
|
|||
});
|
||||
|
||||
const getComponentsProps = computed(() => {
|
||||
const { schema, tableAction, formModel, formActionType } = props;
|
||||
let { componentProps = {} } = schema;
|
||||
const {schema, tableAction, formModel, formActionType} = props;
|
||||
let {componentProps = {}} = schema;
|
||||
if (isFunction(componentProps)) {
|
||||
componentProps = componentProps({ schema, tableAction, formModel, formActionType }) ?? {};
|
||||
componentProps = componentProps({schema, tableAction, formModel, formActionType}) ?? {};
|
||||
}
|
||||
if (schema.component === 'Divider') {
|
||||
componentProps = Object.assign({ type: 'horizontal' }, componentProps, {
|
||||
componentProps = Object.assign({type: 'horizontal'}, componentProps, {
|
||||
orientation: 'left',
|
||||
plain: true,
|
||||
});
|
||||
|
@ -87,9 +87,9 @@
|
|||
});
|
||||
|
||||
const getDisable = computed(() => {
|
||||
const { disabled: globDisabled } = props.formProps;
|
||||
const { dynamicDisabled } = props.schema;
|
||||
const { disabled: itemDisabled = false } = unref(getComponentsProps);
|
||||
const {disabled: globDisabled} = props.formProps;
|
||||
const {dynamicDisabled} = props.schema;
|
||||
const {disabled: itemDisabled = false} = unref(getComponentsProps);
|
||||
let disabled = !!globDisabled || itemDisabled;
|
||||
if (isBoolean(dynamicDisabled)) {
|
||||
disabled = dynamicDisabled;
|
||||
|
@ -101,8 +101,8 @@
|
|||
});
|
||||
|
||||
function getShow(): { isShow: boolean; isIfShow: boolean } {
|
||||
const { show, ifShow } = props.schema;
|
||||
const { showAdvancedButton } = props.formProps;
|
||||
const {show, ifShow} = props.schema;
|
||||
const {showAdvancedButton} = props.formProps;
|
||||
const itemIsAdvanced = showAdvancedButton
|
||||
? isBoolean(props.schema.isAdvanced)
|
||||
? props.schema.isAdvanced
|
||||
|
@ -125,7 +125,7 @@
|
|||
isIfShow = ifShow(unref(getValues));
|
||||
}
|
||||
isShow = isShow && itemIsAdvanced;
|
||||
return { isShow, isIfShow };
|
||||
return {isShow, isIfShow};
|
||||
}
|
||||
|
||||
function handleRules(): ValidationRule[] {
|
||||
|
@ -143,7 +143,7 @@
|
|||
}
|
||||
|
||||
let rules: ValidationRule[] = cloneDeep(defRules) as ValidationRule[];
|
||||
const { rulesMessageJoinLabel: globalRulesMessageJoinLabel } = props.formProps;
|
||||
const {rulesMessageJoinLabel: globalRulesMessageJoinLabel} = props.formProps;
|
||||
|
||||
const joinLabel = Reflect.has(props.schema, 'rulesMessageJoinLabel')
|
||||
? rulesMessageJoinLabel
|
||||
|
@ -179,7 +179,7 @@
|
|||
const getRequired = isFunction(required) ? required(unref(getValues)) : required;
|
||||
|
||||
if ((!rules || rules.length === 0) && getRequired) {
|
||||
rules = [{ required: getRequired, validator }];
|
||||
rules = [{required: getRequired, validator}];
|
||||
}
|
||||
|
||||
const requiredRuleIndex: number = rules.findIndex(
|
||||
|
@ -188,7 +188,7 @@
|
|||
|
||||
if (requiredRuleIndex !== -1) {
|
||||
const rule = rules[requiredRuleIndex];
|
||||
const { isShow } = getShow();
|
||||
const {isShow} = getShow();
|
||||
if (!isShow) {
|
||||
rule.required = false;
|
||||
}
|
||||
|
@ -243,7 +243,7 @@
|
|||
};
|
||||
const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>;
|
||||
|
||||
const { autoSetPlaceHolder, size } = props.formProps;
|
||||
const {autoSetPlaceHolder, size} = props.formProps;
|
||||
const propsData: Recordable = {
|
||||
allowClear: true,
|
||||
getPopupContainer: (trigger: Element) => trigger.parentNode,
|
||||
|
@ -252,14 +252,16 @@
|
|||
disabled: unref(getDisable),
|
||||
};
|
||||
|
||||
const isCreatePlaceholder = !propsData.disabled && autoSetPlaceHolder;
|
||||
// RangePicker place is an array
|
||||
if (isCreatePlaceholder && component !== 'RangePicker' && component) {
|
||||
propsData.placeholder =
|
||||
unref(getComponentsProps)?.placeholder || createPlaceholderMessage(component);
|
||||
}
|
||||
propsData.codeField = field;
|
||||
propsData.formValues = unref(getValues);
|
||||
const isCreatePlaceholder = !propsData.disabled && autoSetPlaceHolder;
|
||||
// RangePicker place是一个数组
|
||||
if (isCreatePlaceholder && component !== 'RangePicker' && component) {
|
||||
//自动设置placeholder
|
||||
propsData.placeholder =
|
||||
unref(getComponentsProps)?.placeholder ||
|
||||
createPlaceholderMessage(component) + props.schema.label;
|
||||
}
|
||||
propsData.codeField = field;
|
||||
propsData.formValues = unref(getValues);
|
||||
|
||||
const bindValue: Recordable = {
|
||||
[valueField || (isCheck ? 'checked' : 'value')]: props.formModel[field],
|
||||
|
@ -275,15 +277,19 @@
|
|||
return <Comp {...compAttr} />;
|
||||
}
|
||||
const compSlot = isFunction(renderComponentContent)
|
||||
? { ...renderComponentContent(unref(getValues)) }
|
||||
? {...renderComponentContent(unref(getValues))}
|
||||
: {
|
||||
default: () => renderComponentContent,
|
||||
};
|
||||
return <Comp {...compAttr}>{compSlot}</Comp>;
|
||||
}
|
||||
|
||||
/**
|
||||
*渲染Label
|
||||
* @updateBy:zyf
|
||||
*/
|
||||
function renderLabelHelpMessage() {
|
||||
const { label, helpMessage, helpComponentProps, subLabel } = props.schema;
|
||||
const {label, helpMessage, helpComponentProps, subLabel} = props.schema;
|
||||
const renderLabel = subLabel ? (
|
||||
<span>
|
||||
{label} <span class="text-secondary">{subLabel}</span>
|
||||
|
@ -306,9 +312,9 @@
|
|||
}
|
||||
|
||||
function renderItem() {
|
||||
const { itemProps, slot, render, field, suffix, component } = props.schema;
|
||||
const { labelCol, wrapperCol } = unref(itemLabelWidthProp);
|
||||
const { colon } = props.formProps;
|
||||
const {itemProps, slot, render, field, suffix, component} = props.schema;
|
||||
const {labelCol, wrapperCol} = unref(itemLabelWidthProp);
|
||||
const {colon} = props.formProps;
|
||||
|
||||
if (component === 'Divider') {
|
||||
return (
|
||||
|
@ -332,7 +338,7 @@
|
|||
<Form.Item
|
||||
name={field}
|
||||
colon={colon}
|
||||
class={{ 'suffix-item': showSuffix }}
|
||||
class={{'suffix-item': showSuffix}}
|
||||
{...(itemProps as Recordable)}
|
||||
label={renderLabelHelpMessage()}
|
||||
rules={handleRules()}
|
||||
|
@ -340,7 +346,7 @@
|
|||
wrapperCol={wrapperCol}
|
||||
>
|
||||
<div style="display:flex">
|
||||
<div style="flex:1">{getContent()}</div>
|
||||
<div style="flex:1;">{getContent()}</div>
|
||||
{showSuffix && <span class="suffix">{getSuffix}</span>}
|
||||
</div>
|
||||
</Form.Item>
|
||||
|
@ -349,14 +355,14 @@
|
|||
}
|
||||
|
||||
return () => {
|
||||
const { colProps = {}, colSlot, renderColContent, component } = props.schema;
|
||||
const {colProps = {}, colSlot, renderColContent, component} = props.schema;
|
||||
if (!componentMap.has(component)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { baseColProps = {} } = props.formProps;
|
||||
const realColProps = { ...baseColProps, ...colProps };
|
||||
const { isIfShow, isShow } = getShow();
|
||||
const {baseColProps = {}} = props.formProps;
|
||||
const realColProps = {...baseColProps, ...colProps};
|
||||
const {isIfShow, isShow} = getShow();
|
||||
const values = unref(getValues);
|
||||
|
||||
const getContent = () => {
|
||||
|
|
|
@ -61,7 +61,7 @@ export default function ({
|
|||
{ immediate: true }
|
||||
);
|
||||
|
||||
function getAdvanced(itemCol: Partial<ColEx>, itemColSum = 0, isLastAction = false) {
|
||||
function getAdvanced(itemCol: Partial<ColEx>, itemColSum = 0, isLastAction = false, index = 0) {
|
||||
const width = unref(realWidthRef);
|
||||
|
||||
const mdWidth =
|
||||
|
@ -84,27 +84,41 @@ export default function ({
|
|||
itemColSum += xxlWidth;
|
||||
}
|
||||
|
||||
let autoAdvancedCol = (unref(getProps).autoAdvancedCol ?? 3)
|
||||
|
||||
if (isLastAction) {
|
||||
advanceState.hideAdvanceBtn = false;
|
||||
if (itemColSum <= BASIC_COL_LEN * 2) {
|
||||
// When less than or equal to 2 lines, the collapse and expand buttons are not displayed
|
||||
advanceState.hideAdvanceBtn = unref(getSchema).length <= autoAdvancedCol;
|
||||
// update-begin--author:sunjianlei---date:20211108---for: 注释掉该逻辑,使小于等于2行时,也显示展开收起按钮
|
||||
/* if (itemColSum <= BASIC_COL_LEN * 2) {
|
||||
// 小于等于2行时,不显示折叠和展开按钮
|
||||
advanceState.hideAdvanceBtn = true;
|
||||
advanceState.isAdvanced = true;
|
||||
} else if (
|
||||
} else */
|
||||
// update-end--author:sunjianlei---date:20211108---for: 注释掉该逻辑,使小于等于2行时,也显示展开收起按钮
|
||||
if (
|
||||
itemColSum > BASIC_COL_LEN * 2 &&
|
||||
itemColSum <= BASIC_COL_LEN * (unref(getProps).autoAdvancedLine || 3)
|
||||
) {
|
||||
advanceState.hideAdvanceBtn = false;
|
||||
|
||||
// More than 3 lines collapsed by default
|
||||
// 默认超过 3 行折叠
|
||||
} else if (!advanceState.isLoad) {
|
||||
advanceState.isLoad = true;
|
||||
advanceState.isAdvanced = !advanceState.isAdvanced;
|
||||
// update-begin--author:sunjianlei---date:20211108---for: 如果总列数大于 autoAdvancedCol,就默认折叠
|
||||
if (unref(getSchema).length > autoAdvancedCol) {
|
||||
advanceState.hideAdvanceBtn = false
|
||||
advanceState.isAdvanced = false
|
||||
}
|
||||
// update-end--author:sunjianlei---date:20211108---for: 如果总列数大于 autoAdvancedCol,就默认折叠
|
||||
}
|
||||
return { isAdvanced: advanceState.isAdvanced, itemColSum };
|
||||
}
|
||||
if (itemColSum > BASIC_COL_LEN * (unref(getProps).alwaysShowLines || 1)) {
|
||||
return { isAdvanced: advanceState.isAdvanced, itemColSum };
|
||||
} else if (!advanceState.isAdvanced && (index + 1) > autoAdvancedCol) {
|
||||
// 如果当前是收起状态,并且当前列下标 > autoAdvancedCol,就隐藏
|
||||
return { isAdvanced: false, itemColSum }
|
||||
} else {
|
||||
// The first line is always displayed
|
||||
return { isAdvanced: true, itemColSum };
|
||||
|
@ -116,7 +130,9 @@ export default function ({
|
|||
let realItemColSum = 0;
|
||||
const { baseColProps = {} } = unref(getProps);
|
||||
|
||||
for (const schema of unref(getSchema)) {
|
||||
const schemas = unref(getSchema)
|
||||
for (let i = 0; i < schemas.length; i++) {
|
||||
const schema = schemas[i]
|
||||
const { show, colProps } = schema;
|
||||
let isShow = true;
|
||||
|
||||
|
@ -139,7 +155,7 @@ export default function ({
|
|||
if (isShow && (colProps || baseColProps)) {
|
||||
const { itemColSum: sum, isAdvanced } = getAdvanced(
|
||||
{ ...baseColProps, ...colProps },
|
||||
itemColSum
|
||||
itemColSum, false, i,
|
||||
);
|
||||
|
||||
itemColSum = sum || 0;
|
||||
|
|
|
@ -1,117 +1,136 @@
|
|||
import type { FormProps, FormActionType, UseFormReturnType, FormSchema } from '../types/form';
|
||||
import type { NamePath } from 'ant-design-vue/lib/form/interface';
|
||||
import type { DynamicProps } from '/#/utils';
|
||||
import { handleRangeValue } from '../utils/formUtils';
|
||||
import { ref, onUnmounted, unref, nextTick, watch } from 'vue';
|
||||
import { isProdMode } from '/@/utils/env';
|
||||
import { error } from '/@/utils/log';
|
||||
import { getDynamicProps } from '/@/utils';
|
||||
import { getDynamicProps, getValueType } from '/@/utils';
|
||||
|
||||
export declare type ValidateFields = (nameList?: NamePath[]) => Promise<Recordable>;
|
||||
|
||||
type Props = Partial<DynamicProps<FormProps>>;
|
||||
|
||||
export function useForm(props?: Props): UseFormReturnType {
|
||||
const formRef = ref<Nullable<FormActionType>>(null);
|
||||
const loadedRef = ref<Nullable<boolean>>(false);
|
||||
const formRef = ref<Nullable<FormActionType>>(null);
|
||||
const loadedRef = ref<Nullable<boolean>>(false);
|
||||
|
||||
async function getForm() {
|
||||
const form = unref(formRef);
|
||||
if (!form) {
|
||||
error(
|
||||
'The form instance has not been obtained, please make sure that the form has been rendered when performing the form operation!'
|
||||
);
|
||||
async function getForm() {
|
||||
const form = unref(formRef);
|
||||
if (!form) {
|
||||
error(
|
||||
'The form instance has not been obtained, please make sure that the form has been rendered when performing the form operation!'
|
||||
);
|
||||
}
|
||||
await nextTick();
|
||||
return form as FormActionType;
|
||||
}
|
||||
await nextTick();
|
||||
return form as FormActionType;
|
||||
}
|
||||
|
||||
function register(instance: FormActionType) {
|
||||
isProdMode() &&
|
||||
onUnmounted(() => {
|
||||
formRef.value = null;
|
||||
loadedRef.value = null;
|
||||
});
|
||||
if (unref(loadedRef) && isProdMode() && instance === unref(formRef)) return;
|
||||
function register(instance: FormActionType) {
|
||||
isProdMode() &&
|
||||
onUnmounted(() => {
|
||||
formRef.value = null;
|
||||
loadedRef.value = null;
|
||||
});
|
||||
if (unref(loadedRef) && isProdMode() && instance === unref(formRef)) return;
|
||||
|
||||
formRef.value = instance;
|
||||
loadedRef.value = true;
|
||||
formRef.value = instance;
|
||||
loadedRef.value = true;
|
||||
|
||||
watch(
|
||||
() => props,
|
||||
() => {
|
||||
props && instance.setProps(getDynamicProps(props));
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
}
|
||||
watch(
|
||||
() => props,
|
||||
() => {
|
||||
props && instance.setProps(getDynamicProps(props));
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const methods: FormActionType = {
|
||||
scrollToField: async (name: NamePath, options?: ScrollOptions | undefined) => {
|
||||
const form = await getForm();
|
||||
form.scrollToField(name, options);
|
||||
},
|
||||
setProps: async (formProps: Partial<FormProps>) => {
|
||||
const form = await getForm();
|
||||
form.setProps(formProps);
|
||||
},
|
||||
const methods: FormActionType = {
|
||||
scrollToField: async (name: NamePath, options?: ScrollOptions | undefined) => {
|
||||
const form = await getForm();
|
||||
form.scrollToField(name, options);
|
||||
},
|
||||
setProps: async (formProps: Partial<FormProps>) => {
|
||||
const form = await getForm();
|
||||
form.setProps(formProps);
|
||||
},
|
||||
|
||||
updateSchema: async (data: Partial<FormSchema> | Partial<FormSchema>[]) => {
|
||||
const form = await getForm();
|
||||
form.updateSchema(data);
|
||||
},
|
||||
updateSchema: async (data: Partial<FormSchema> | Partial<FormSchema>[]) => {
|
||||
const form = await getForm();
|
||||
form.updateSchema(data);
|
||||
},
|
||||
|
||||
resetSchema: async (data: Partial<FormSchema> | Partial<FormSchema>[]) => {
|
||||
const form = await getForm();
|
||||
form.resetSchema(data);
|
||||
},
|
||||
resetSchema: async (data: Partial<FormSchema> | Partial<FormSchema>[]) => {
|
||||
const form = await getForm();
|
||||
form.resetSchema(data);
|
||||
},
|
||||
|
||||
clearValidate: async (name?: string | string[]) => {
|
||||
const form = await getForm();
|
||||
form.clearValidate(name);
|
||||
},
|
||||
clearValidate: async (name?: string | string[]) => {
|
||||
const form = await getForm();
|
||||
form.clearValidate(name);
|
||||
},
|
||||
|
||||
resetFields: async () => {
|
||||
getForm().then(async (form) => {
|
||||
await form.resetFields();
|
||||
});
|
||||
},
|
||||
resetFields: async () => {
|
||||
getForm().then(async (form) => {
|
||||
await form.resetFields();
|
||||
});
|
||||
},
|
||||
|
||||
removeSchemaByFiled: async (field: string | string[]) => {
|
||||
unref(formRef)?.removeSchemaByFiled(field);
|
||||
},
|
||||
removeSchemaByFiled: async (field: string | string[]) => {
|
||||
unref(formRef)?.removeSchemaByFiled(field);
|
||||
},
|
||||
|
||||
// TODO promisify
|
||||
getFieldsValue: <T>() => {
|
||||
return unref(formRef)?.getFieldsValue() as T;
|
||||
},
|
||||
// TODO promisify
|
||||
getFieldsValue: <T>() => {
|
||||
return unref(formRef)?.getFieldsValue() as T;
|
||||
},
|
||||
|
||||
setFieldsValue: async <T>(values: T) => {
|
||||
const form = await getForm();
|
||||
form.setFieldsValue<T>(values);
|
||||
},
|
||||
setFieldsValue: async <T>(values: T) => {
|
||||
const form = await getForm();
|
||||
form.setFieldsValue<T>(values);
|
||||
},
|
||||
|
||||
appendSchemaByField: async (
|
||||
schema: FormSchema,
|
||||
prefixField: string | undefined,
|
||||
first: boolean
|
||||
) => {
|
||||
const form = await getForm();
|
||||
form.appendSchemaByField(schema, prefixField, first);
|
||||
},
|
||||
appendSchemaByField: async (
|
||||
schema: FormSchema,
|
||||
prefixField: string | undefined,
|
||||
first: boolean
|
||||
) => {
|
||||
const form = await getForm();
|
||||
form.appendSchemaByField(schema, prefixField, first);
|
||||
},
|
||||
|
||||
submit: async (): Promise<any> => {
|
||||
const form = await getForm();
|
||||
return form.submit();
|
||||
},
|
||||
submit: async (): Promise<any> => {
|
||||
const form = await getForm();
|
||||
return form.submit();
|
||||
},
|
||||
|
||||
/**
|
||||
* 表单验证并返回表单值
|
||||
* @update:添加表单值转换逻辑
|
||||
* @updateBy:zyf
|
||||
* @updateDate:2021-09-02
|
||||
*/
|
||||
validate: async (nameList?: NamePath[]): Promise<Recordable> => {
|
||||
const form = await getForm();
|
||||
return form.validate(nameList);
|
||||
let values = form.validate(nameList).then((values) => {
|
||||
for (let key in values) {
|
||||
if (values[key] instanceof Array) {
|
||||
let valueType = getValueType(props, key);
|
||||
if (valueType === 'string') {
|
||||
values[key] = values[key].join(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
//--@updateBy-begin----author:liusq---date:20210916------for:处理区域事件字典信息------
|
||||
return handleRangeValue(props,values);
|
||||
//--@updateBy-end----author:liusq---date:20210916------for:处理区域事件字典信息------
|
||||
});
|
||||
return values;
|
||||
},
|
||||
|
||||
validateFields: async (nameList?: NamePath[]): Promise<Recordable> => {
|
||||
const form = await getForm();
|
||||
return form.validateFields(nameList);
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { FormProps, FormSchema, FormActionType } from '../types/form';
|
|||
import type { NamePath } from 'ant-design-vue/lib/form/interface';
|
||||
import { unref, toRaw } from 'vue';
|
||||
import { isArray, isFunction, isObject, isString } from '/@/utils/is';
|
||||
import { deepMerge } from '/@/utils';
|
||||
import { deepMerge, getValueType } from '/@/utils';
|
||||
import { dateItemType, handleInputNumberValue } from '../helper';
|
||||
import { dateUtil } from '/@/utils/dateUtil';
|
||||
import { cloneDeep, uniqBy } from 'lodash-es';
|
||||
|
@ -240,6 +240,17 @@ export function useFormEvents({
|
|||
if (!formEl) return;
|
||||
try {
|
||||
const values = await validate();
|
||||
//update-begin---author:zhangdaihao Date:20140212 for:[bug号]树机构调整------------
|
||||
//--updateBy-begin----author:zyf---date:20211206------for:对查询表单提交的数组处理成字符串------
|
||||
for (let key in values) {
|
||||
if (values[key] instanceof Array) {
|
||||
let valueType = getValueType(getProps, key);
|
||||
if (valueType === 'string') {
|
||||
values[key] = values[key].join(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
//--updateBy-end----author:zyf---date:20211206------for:对查询表单提交的数组处理成字符串------
|
||||
const res = handleFormValues(values);
|
||||
emit('submit', res);
|
||||
} catch (error) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import { unref } from 'vue';
|
|||
import type { Ref, ComputedRef } from 'vue';
|
||||
import type { FormProps, FormSchema } from '../types/form';
|
||||
import { set } from 'lodash-es';
|
||||
import { handleRangeValue } from '/@/components/Form/src/utils/formUtils';
|
||||
|
||||
interface UseFormValuesContext {
|
||||
defaultValueRef: Ref<any>;
|
||||
|
@ -42,33 +43,9 @@ export function useFormValues({
|
|||
}
|
||||
set(res, key, value);
|
||||
}
|
||||
return handleRangeTimeValue(res);
|
||||
return handleRangeValue(getProps,res);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Processing time interval parameters
|
||||
*/
|
||||
function handleRangeTimeValue(values: Recordable) {
|
||||
const fieldMapToTime = unref(getProps).fieldMapToTime;
|
||||
|
||||
if (!fieldMapToTime || !Array.isArray(fieldMapToTime)) {
|
||||
return values;
|
||||
}
|
||||
|
||||
for (const [field, [startTimeKey, endTimeKey], format = 'YYYY-MM-DD'] of fieldMapToTime) {
|
||||
if (!field || !startTimeKey || !endTimeKey || !values[field]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const [startTime, endTime]: string[] = values[field];
|
||||
|
||||
values[startTimeKey] = dateUtil(startTime).format(format);
|
||||
values[endTimeKey] = dateUtil(endTime).format(format);
|
||||
Reflect.deleteProperty(values, field);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
function initDefault() {
|
||||
const schemas = unref(getSchema);
|
||||
|
|
|
@ -16,8 +16,14 @@ export function useItemLabelWidth(schemaItemRef: Ref<FormSchema>, propsRef: Ref<
|
|||
wrapperCol: globWrapperCol,
|
||||
} = unref(propsRef);
|
||||
|
||||
// update-begin--author:sunjianlei---date:20211104---for: 禁用全局 labelWidth,不自动设置 textAlign --------
|
||||
if (disabledLabelWidth) {
|
||||
return { labelCol, wrapperCol }
|
||||
}
|
||||
// update-begin--author:sunjianlei---date:20211104---for: 禁用全局 labelWidth,不自动设置 textAlign --------
|
||||
|
||||
// If labelWidth is set globally, all items setting
|
||||
if ((!globalLabelWidth && !labelWidth && !globalLabelCol) || disabledLabelWidth) {
|
||||
if ((!globalLabelWidth && !labelWidth && !globalLabelCol)) {
|
||||
labelCol.style = {
|
||||
textAlign: 'left',
|
||||
};
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
<template>
|
||||
<div v-for="(param, index) in dynamicInput.params" :key="index" style="display: flex">
|
||||
<a-input placeholder="请输入参数key" v-model:value="param.label" style="width: 30%;margin-bottom: 5px" @input="emitChange"/>
|
||||
<a-input placeholder="请输入参数value" v-model:value="param.value" style="width: 30%;margin: 0 0 5px 5px" @input="emitChange"/>
|
||||
<MinusCircleOutlined
|
||||
v-if="dynamicInput.params.length > 1"
|
||||
class="dynamic-delete-button"
|
||||
@click="remove(param)"
|
||||
style="width: 50px"
|
||||
></MinusCircleOutlined>
|
||||
</div>
|
||||
<div>
|
||||
<a-button type="dashed" style="width: 60%" @click="add">
|
||||
<PlusOutlined/>
|
||||
新增
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {MinusCircleOutlined, PlusOutlined} from '@ant-design/icons-vue';
|
||||
import {defineComponent, reactive, ref, UnwrapRef, watchEffect} from 'vue';
|
||||
import {propTypes} from '/@/utils/propTypes';
|
||||
import { isEmpty } from '/@/utils/is'
|
||||
import { tryOnMounted, tryOnUnmounted } from '@vueuse/core';
|
||||
interface Params {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'JAddInput',
|
||||
props: {
|
||||
value: propTypes.string.def('')
|
||||
},
|
||||
emits: ['change', 'update:value'],
|
||||
setup(props, {emit}) {
|
||||
//input动态数据
|
||||
const dynamicInput: UnwrapRef<{ params: Params[] }> = reactive({params: []});
|
||||
//删除Input
|
||||
const remove = (item: Params) => {
|
||||
let index = dynamicInput.params.indexOf(item);
|
||||
if (index !== -1) {
|
||||
dynamicInput.params.splice(index, 1);
|
||||
}
|
||||
emitChange()
|
||||
};
|
||||
//新增Input
|
||||
const add = () => {
|
||||
dynamicInput.params.push({
|
||||
label: '',
|
||||
value: '',
|
||||
});
|
||||
emitChange()
|
||||
};
|
||||
|
||||
//监听传入数据value
|
||||
watchEffect(() => {
|
||||
initVal();
|
||||
});
|
||||
|
||||
/**
|
||||
* 初始化数值
|
||||
*/
|
||||
function initVal() {
|
||||
console.log("props.value",props.value)
|
||||
dynamicInput.params = [];
|
||||
if(props.value && props.value.indexOf("{")==0){
|
||||
let jsonObj = JSON.parse(props.value);
|
||||
Object.keys(jsonObj).forEach((key) => {
|
||||
dynamicInput.params.push({label: key, value: jsonObj[key]});
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 数值改变
|
||||
*/
|
||||
function emitChange() {
|
||||
let obj = {};
|
||||
if (dynamicInput.params.length > 0) {
|
||||
dynamicInput.params.forEach(item => {
|
||||
obj[item['label']] = item['value']
|
||||
})
|
||||
}
|
||||
emit("change", isEmpty(obj)?'': JSON.stringify(obj));
|
||||
emit("update:value",isEmpty(obj)?'': JSON.stringify(obj))
|
||||
}
|
||||
|
||||
return {
|
||||
dynamicInput,
|
||||
emitChange,
|
||||
remove,
|
||||
add,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
MinusCircleOutlined,
|
||||
PlusOutlined,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
.dynamic-delete-button {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
top: 4px;
|
||||
font-size: 24px;
|
||||
color: #999;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.dynamic-delete-button:hover {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.dynamic-delete-button[disabled] {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
|
@ -4,7 +4,7 @@
|
|||
<script lang="ts">
|
||||
import {defineComponent, PropType, ref,reactive, watchEffect, computed, unref, watch, onMounted} from 'vue';
|
||||
import {Cascader} from 'ant-design-vue';
|
||||
import {provinceAndCityData, regionData, provinceAndCityDataPlus, regionDataPlus, CodeToText, TextToCode} from "../utils/areaDataUtil";
|
||||
import {provinceAndCityData, regionData, provinceAndCityDataPlus, regionDataPlus, CodeToText, TextToCode} from "../../utils/areaDataUtil";
|
||||
import {useRuleFormItem} from "/@/hooks/component/useFormItem";
|
||||
import {propTypes} from "/@/utils/propTypes";
|
||||
import {useAttrs} from "/@/hooks/core/useAttrs";
|
|
@ -0,0 +1,153 @@
|
|||
<template>
|
||||
<div class="area-select">
|
||||
<!--省份-->
|
||||
<a-select v-model:value="province" @change="proChange" allowClear>
|
||||
<template v-for="item in provinceOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">{{ item.label }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
<!--城市-->
|
||||
<a-select v-if="level>=2" v-model:value="city" @change="cityChange">
|
||||
<template v-for="item in cityOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">{{ item.label }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
<!--地区-->
|
||||
<a-select v-if="level>=3" v-model:value="area" @change="areaChange">
|
||||
<template v-for="item in areaOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">{{ item.label }}</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted, onUnmounted, toRefs} from 'vue';
|
||||
import {propTypes} from "/@/utils/propTypes";
|
||||
import {useRuleFormItem} from '/@/hooks/component/useFormItem';
|
||||
import {provinceOptions, getDataByCode, getRealCode} from "../../utils/areaDataUtil";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'JAreaSelect',
|
||||
props: {
|
||||
value: [Array, String],
|
||||
province: [String],
|
||||
city: [String],
|
||||
area: [String],
|
||||
level: propTypes.number.def(3),
|
||||
},
|
||||
emits: ['change','update:value'],
|
||||
setup(props, {emit, refs}) {
|
||||
const emitData = ref<any[]>([]);
|
||||
//下拉框的选择值
|
||||
const pca = reactive({
|
||||
province: '',
|
||||
city: '',
|
||||
area: '',
|
||||
});
|
||||
//表单值
|
||||
const [state] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
//城市下拉框的选项
|
||||
const cityOptions = computed(() => {
|
||||
return pca.province ? getDataByCode(pca.province) : [];
|
||||
});
|
||||
//地区下拉框的选项
|
||||
const areaOptions = computed(() => {
|
||||
return pca.city ? getDataByCode(pca.city) : [];
|
||||
});
|
||||
/**
|
||||
* 监听props值
|
||||
*/
|
||||
watchEffect(() => {
|
||||
props && initValue();
|
||||
});
|
||||
|
||||
/**
|
||||
* 监听组件值变化
|
||||
*/
|
||||
watch(pca, (newVal) => {
|
||||
if(!props.value){
|
||||
emit("update:province",pca.province);
|
||||
emit("update:city",pca.city);
|
||||
emit("update:area",pca.area);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 数据初始化
|
||||
*/
|
||||
function initValue() {
|
||||
if (props.value) {
|
||||
//传参是数组的情况下的处理
|
||||
if (Array.isArray(props.value)) {
|
||||
pca.province = props.value[0];
|
||||
pca.city = props.value[1] ? props.value[1] : '';
|
||||
pca.area = props.value[2] ? props.value[2] : '';
|
||||
} else {
|
||||
//传参是数值
|
||||
let valueArr = getRealCode(props.value, props.level);
|
||||
if (valueArr) {
|
||||
pca.province = valueArr[0];
|
||||
pca.city = props.level >= 2 && valueArr[1] ? valueArr[1] : '';
|
||||
pca.area = props.level >= 3 && valueArr[2] ? valueArr[2] : '';
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//绑定三个数据的情况
|
||||
pca.province = props.province?props.province:'';
|
||||
pca.city = props.city?props.city:'';
|
||||
pca.area = props.area?props.area:'';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 省份change事件
|
||||
*/
|
||||
function proChange(val) {
|
||||
pca.city = (val && getDataByCode(val)[0]?.value);
|
||||
pca.area = (pca.city && getDataByCode(pca.city)[0]?.value);
|
||||
state.value = props.level <= 1 ? val : (props.level <= 2 ? pca.city : pca.area);
|
||||
emit("update:value",unref(state));
|
||||
}
|
||||
|
||||
/**
|
||||
* 城市change事件
|
||||
*/
|
||||
function cityChange(val) {
|
||||
pca.area = (val && getDataByCode(val)[0]?.value);
|
||||
state.value = props.level <= 2 ? val : pca.area;
|
||||
emit("update:value",unref(state));
|
||||
}
|
||||
|
||||
/**
|
||||
* 区域change事件
|
||||
*/
|
||||
function areaChange(val) {
|
||||
state.value = val;
|
||||
emit("update:value",unref(state));
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(pca),
|
||||
provinceOptions,
|
||||
cityOptions,
|
||||
areaOptions,
|
||||
proChange,
|
||||
cityChange,
|
||||
areaChange
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.area-select {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
.ant-select{
|
||||
width: 33.3%;
|
||||
}
|
||||
|
||||
.ant-select:not(:first-child) {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,256 @@
|
|||
<!--下拉树-->
|
||||
<template>
|
||||
<a-tree-select
|
||||
allowClear
|
||||
labelInValue
|
||||
style="width: 100%"
|
||||
:disabled="disabled"
|
||||
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
|
||||
:placeholder="placeholder"
|
||||
:loadData="asyncLoadTreeData"
|
||||
:value="treeValue"
|
||||
:treeData="treeData"
|
||||
:multiple="multiple"
|
||||
@change="onChange">
|
||||
</a-tree-select>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, unref, watch } from 'vue';
|
||||
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import { loadDictItem, loadTreeData } from '/@/api/common/api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createMessage, createErrorModal } = useMessage();
|
||||
export default defineComponent({
|
||||
name: 'JCategorySelect',
|
||||
components: {},
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
value: propTypes.oneOfType([
|
||||
propTypes.string,
|
||||
propTypes.array,
|
||||
]),
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择',
|
||||
required: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: false,
|
||||
},
|
||||
condition: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false,
|
||||
},
|
||||
// 是否支持多选
|
||||
multiple: {
|
||||
type: [Boolean,String],
|
||||
default: false,
|
||||
},
|
||||
loadTriggleChange: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: false,
|
||||
},
|
||||
pid: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false,
|
||||
},
|
||||
pcode: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false,
|
||||
},
|
||||
back: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
emits: ['options-change', 'change'],
|
||||
setup(props, { emit, refs }) {
|
||||
console.info(props);
|
||||
const emitData = ref<any[]>([]);
|
||||
const treeData = ref<any[]>([]);
|
||||
const treeValue = ref('');
|
||||
const attrs = useAttrs();
|
||||
const [state] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
watch(
|
||||
() => props.value,
|
||||
() => {
|
||||
loadItemByCode();
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
watch(
|
||||
() => props.pcode,
|
||||
() => {
|
||||
loadRoot();
|
||||
},
|
||||
{ deep: true, immediate: true },
|
||||
);
|
||||
|
||||
function loadRoot() {
|
||||
let param = {
|
||||
pid: props.pid,
|
||||
pcode: !props.pcode ? '0' : props.pcode,
|
||||
condition: props.condition,
|
||||
};
|
||||
console.info(param);
|
||||
loadTreeData(param).then(res => {
|
||||
for (let i of res) {
|
||||
i.value = i.key;
|
||||
if (i.leaf == false) {
|
||||
i.isLeaf = false;
|
||||
} else if (i.leaf == true) {
|
||||
i.isLeaf = true;
|
||||
}
|
||||
}
|
||||
treeData.value = res;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function loadItemByCode() {
|
||||
if (!props.value || props.value == '0') {
|
||||
treeValue.value = [];
|
||||
} else {
|
||||
loadDictItem({ ids: props.value }).then(res => {
|
||||
let values = props.value.split(',');
|
||||
treeValue.value = res.map((item, index) => ({
|
||||
key: values[index],
|
||||
value: values[index],
|
||||
label: item,
|
||||
}));
|
||||
onLoadTriggleChange(res[0]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onLoadTriggleChange(text) {
|
||||
//只有单选才会触发
|
||||
if (!props.multiple && props.loadTriggleChange) {
|
||||
backValue(props.value, text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function backValue(value, label) {
|
||||
let obj = {};
|
||||
if (props.back) {
|
||||
obj[props.back] = label;
|
||||
}
|
||||
emit('change', value, obj);
|
||||
}
|
||||
|
||||
function asyncLoadTreeData(treeNode) {
|
||||
let dataRef = treeNode.dataRef;
|
||||
return new Promise((resolve) => {
|
||||
if (treeNode.children.length > 0) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
let pid = dataRef.key;
|
||||
console.info(treeNode);
|
||||
let param = {
|
||||
pid: pid,
|
||||
condition: props.condition,
|
||||
};
|
||||
loadTreeData(param).then(res => {
|
||||
if (res) {
|
||||
for (let i of res) {
|
||||
i.value = i.key;
|
||||
if (i.leaf == false) {
|
||||
i.isLeaf = false;
|
||||
} else if (i.leaf == true) {
|
||||
i.isLeaf = true;
|
||||
}
|
||||
}
|
||||
addChildren(pid, res, treeData.value);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addChildren(pid, children, treeArray) {
|
||||
console.info('treeArray', treeArray);
|
||||
if (treeArray && treeArray.length > 0) {
|
||||
for (let item of treeArray) {
|
||||
if (item.key == pid) {
|
||||
if (!children || children.length == 0) {
|
||||
item.isLeaf = true;
|
||||
} else {
|
||||
item.children = children;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
addChildren(pid, children, item.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onChange(value) {
|
||||
if (!value) {
|
||||
emit('change', '');
|
||||
treeValue.value = '';
|
||||
} else if (Array.isArray(value)) {
|
||||
let labels = [];
|
||||
let values = value.map(item => {
|
||||
labels.push(item.label);
|
||||
return item.value;
|
||||
});
|
||||
backValue(values.join(','), labels.join(','));
|
||||
treeValue.value = value;
|
||||
} else {
|
||||
backValue(value.value, value.label);
|
||||
treeValue.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
function getCurrTreeData() {
|
||||
return treeData;
|
||||
}
|
||||
|
||||
function validateProp() {
|
||||
let mycondition = props.condition;
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!mycondition) {
|
||||
resolve();
|
||||
} else {
|
||||
try {
|
||||
let test = JSON.parse(mycondition);
|
||||
if (typeof test == 'object' && test) {
|
||||
resolve();
|
||||
} else {
|
||||
createMessage.error('组件JTreeSelect-condition传值有误,需要一个json字符串!');
|
||||
reject();
|
||||
}
|
||||
} catch (e) {
|
||||
createMessage.error('组件JTreeSelect-condition传值有误,需要一个json字符串!');
|
||||
reject();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
state,
|
||||
attrs,
|
||||
onChange,
|
||||
treeData,
|
||||
treeValue,
|
||||
asyncLoadTreeData,
|
||||
};
|
||||
},
|
||||
})
|
||||
;
|
||||
</script>
|
|
@ -0,0 +1,78 @@
|
|||
<template>
|
||||
<a-checkbox-group v-bind="attrs" v-model:value="checkboxArray" :options="checkOptions" @change="handleChange"></a-checkbox-group>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent, computed, watch, watchEffect, ref, unref} from 'vue';
|
||||
import {propTypes} from "/@/utils/propTypes";
|
||||
import {useAttrs} from '/@/hooks/core/useAttrs';
|
||||
import {initDictOptions} from "/@/utils/dict/index"
|
||||
|
||||
export default defineComponent({
|
||||
name: 'JCheckbox',
|
||||
props: {
|
||||
value: propTypes.string,
|
||||
dictCode: propTypes.string,
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
emits: ['change', 'update:value'],
|
||||
setup(props, {emit}) {
|
||||
const attrs = useAttrs();
|
||||
//checkbox选项
|
||||
const checkOptions = ref<any[]>([]);
|
||||
//checkbox数值
|
||||
const checkboxArray = ref<any[]>([]);
|
||||
/**
|
||||
* 监听value
|
||||
*/
|
||||
watchEffect(() => {
|
||||
props.value && (checkboxArray.value = props.value ? props.value.split(",") : []);
|
||||
});
|
||||
/**
|
||||
* 监听字典code
|
||||
*/
|
||||
watchEffect(() => {
|
||||
props && initOptions();
|
||||
});
|
||||
|
||||
/**
|
||||
* 初始化选项
|
||||
*/
|
||||
async function initOptions() {
|
||||
//根据options, 初始化选项
|
||||
if (props.options && props.options.length > 0) {
|
||||
checkOptions.value = props.options;
|
||||
return;
|
||||
}
|
||||
//根据字典Code, 初始化选项
|
||||
if(props.dictCode){
|
||||
const dictData = await initDictOptions(props.dictCode);
|
||||
checkOptions.value = dictData.reduce((prev, next) => {
|
||||
if (next) {
|
||||
const value = next['value'];
|
||||
prev.push({
|
||||
label: next['text'],
|
||||
value: value,
|
||||
});
|
||||
}
|
||||
return prev;
|
||||
}, []);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change事件
|
||||
* @param $event
|
||||
*/
|
||||
function handleChange($event) {
|
||||
emit('update:value', $event.join(','));
|
||||
emit('change', $event.join(','));
|
||||
}
|
||||
|
||||
return {checkboxArray, checkOptions, attrs, handleChange};
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,246 @@
|
|||
<template>
|
||||
<div v-bind="boxBindProps">
|
||||
<!-- 全屏按钮 -->
|
||||
<a-icon v-if="fullScreen" class="full-screen-icon" :type="fullScreenIcon" @click="onToggleFullScreen"/>
|
||||
<textarea ref="textarea" v-bind="getBindValue"></textarea>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent, onMounted, reactive, ref, watch, unref, computed} from 'vue';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { useRuleFormItem } from '/@/hooks/component/useFormItem';
|
||||
// 引入全局实例
|
||||
import _CodeMirror, { EditorFromTextArea } from 'codemirror'
|
||||
// 核心样式
|
||||
import 'codemirror/lib/codemirror.css';
|
||||
// 引入主题后还需要在 options 中指定主题才会生效
|
||||
import 'codemirror/theme/cobalt.css';
|
||||
// 需要引入具体的语法高亮库才会有对应的语法高亮效果
|
||||
import 'codemirror/mode/javascript/javascript.js';
|
||||
import 'codemirror/mode/css/css.js';
|
||||
import 'codemirror/mode/xml/xml.js';
|
||||
import 'codemirror/mode/clike/clike.js';
|
||||
import 'codemirror/mode/markdown/markdown.js';
|
||||
import 'codemirror/mode/python/python.js';
|
||||
import 'codemirror/mode/r/r.js';
|
||||
import 'codemirror/mode/shell/shell.js';
|
||||
import 'codemirror/mode/sql/sql.js';
|
||||
import 'codemirror/mode/swift/swift.js';
|
||||
import 'codemirror/mode/vue/vue.js';
|
||||
// 折叠资源引入:开始
|
||||
import "codemirror/addon/fold/foldgutter.css";
|
||||
import "codemirror/addon/fold/foldcode.js";
|
||||
import "codemirror/addon/fold/brace-fold.js";
|
||||
import "codemirror/addon/fold/comment-fold.js";
|
||||
import "codemirror/addon/fold/indent-fold.js";
|
||||
import "codemirror/addon/fold/foldgutter.js";
|
||||
// 折叠资源引入:结束
|
||||
//光标行背景高亮,配置里面也需要styleActiveLine设置为true
|
||||
import "codemirror/addon/selection/active-line.js";
|
||||
// 支持代码自动补全
|
||||
import "codemirror/addon/hint/show-hint.css";
|
||||
import "codemirror/addon/hint/show-hint.js";
|
||||
import "codemirror/addon/hint/anyword-hint.js";
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import {useDesign} from '/@/hooks/web/useDesign'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'JCodeEditor',
|
||||
// 不将 attrs 的属性绑定到 html 标签上
|
||||
inheritAttrs: false,
|
||||
components: {},
|
||||
props: {
|
||||
value: propTypes.string.def(''),
|
||||
height:propTypes.string.def('auto'),
|
||||
disabled: propTypes.bool.def(false),
|
||||
// 是否显示全屏按钮
|
||||
fullScreen: propTypes.bool.def(false),
|
||||
// 全屏以后的z-index
|
||||
zIndex: propTypes.any.def(999),
|
||||
},
|
||||
emits: ['change', 'update:value'],
|
||||
setup(props, { emit }) {
|
||||
const { prefixCls } = useDesign('code-editer');
|
||||
const CodeMirror = window.CodeMirror || _CodeMirror;
|
||||
const emitData = ref<object>();
|
||||
//表单值
|
||||
const [state] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
const textarea = ref<HTMLTextAreaElement>();
|
||||
let coder: Nullable<EditorFromTextArea> = null
|
||||
const attrs = useAttrs();
|
||||
const height =ref(props.height);
|
||||
const options = reactive({
|
||||
// 缩进格式
|
||||
tabSize: 2,
|
||||
// 主题,对应主题库 JS 需要提前引入
|
||||
theme: 'cobalt',
|
||||
smartIndent: true, // 是否智能缩进
|
||||
// 显示行号
|
||||
lineNumbers: true,
|
||||
line: true,
|
||||
// 启用代码折叠相关功能:开始
|
||||
foldGutter: true,
|
||||
lineWrapping: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "CodeMirror-lint-markers"],
|
||||
// 启用代码折叠相关功能:结束
|
||||
// 光标行高亮
|
||||
styleActiveLine: true,
|
||||
});
|
||||
let innerValue = ''
|
||||
// 全屏状态
|
||||
const isFullScreen = ref(false)
|
||||
const fullScreenIcon = computed(() => isFullScreen.value ? 'fullscreen-exit' : 'fullscreen')
|
||||
// 外部盒子参数
|
||||
const boxBindProps = computed(() => {
|
||||
let _props = {
|
||||
class: [
|
||||
prefixCls, 'full-screen-parent', 'auto-height',
|
||||
{
|
||||
'full-screen': isFullScreen.value,
|
||||
},
|
||||
],
|
||||
style: {},
|
||||
}
|
||||
if (isFullScreen.value) {
|
||||
_props.style['z-index'] = props.zIndex
|
||||
}
|
||||
return _props
|
||||
})
|
||||
/**
|
||||
* 监听组件值
|
||||
*/
|
||||
watch(() => props.value, () => {
|
||||
if (innerValue != props.value) {
|
||||
setValue(props.value, false);
|
||||
}
|
||||
});
|
||||
onMounted(() => {
|
||||
initialize();
|
||||
});
|
||||
|
||||
/**
|
||||
* 组件赋值
|
||||
* @param value
|
||||
* @param trigger 是否触发 change 事件
|
||||
*/
|
||||
function setValue(value: string, trigger = true) {
|
||||
coder?.setValue(value ?? '')
|
||||
innerValue = value
|
||||
trigger && emitChange(innerValue)
|
||||
}
|
||||
|
||||
//编辑器值修改事件
|
||||
function onChange(obj) {
|
||||
innerValue = obj.getValue() ?? '';
|
||||
if (props.value != innerValue) {
|
||||
emitChange(innerValue)
|
||||
}
|
||||
}
|
||||
|
||||
function emitChange(value) {
|
||||
emit('change', value);
|
||||
emit('update:value', value);
|
||||
}
|
||||
|
||||
//组件初始化
|
||||
function initialize() {
|
||||
coder = CodeMirror.fromTextArea(textarea.value!, options);
|
||||
//绑定值修改事件
|
||||
coder.on('change', onChange);
|
||||
// 初始化成功时赋值一次
|
||||
setValue(innerValue, false)
|
||||
}
|
||||
|
||||
// 切换全屏状态
|
||||
function onToggleFullScreen() {
|
||||
isFullScreen.value = !isFullScreen.value
|
||||
}
|
||||
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
||||
return {
|
||||
state,
|
||||
textarea,
|
||||
boxBindProps,
|
||||
getBindValue,
|
||||
setValue,
|
||||
isFullScreen,
|
||||
fullScreenIcon,
|
||||
onToggleFullScreen,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
//noinspection LessUnresolvedVariable
|
||||
@prefix-cls: ~'@{namespace}-code-editer';
|
||||
.@{prefix-cls} {
|
||||
|
||||
&.auto-height {
|
||||
.CodeMirror {
|
||||
height: v-bind(height) !important;
|
||||
min-height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 全屏样式 */
|
||||
|
||||
&.full-screen-parent {
|
||||
position: relative;
|
||||
|
||||
.full-screen-icon {
|
||||
opacity: 0;
|
||||
color: black;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 24px;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
z-index: 9;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.3s;
|
||||
padding: 2px 0 0 1.5px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.full-screen-icon {
|
||||
opacity: 1;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.88);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.full-screen {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 8px;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.full-screen-icon {
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
|
||||
.full-screen-child,
|
||||
.CodeMirror {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.full-screen-child {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,107 @@
|
|||
<template>
|
||||
<a-radio-group v-if="compType===CompTypeEnum.Radio" v-bind="attrs" v-model:value="state" @change="handleChange">
|
||||
<template v-for="item in dictOptions" :key="`${item.value}`">
|
||||
<a-radio :value="item.value">
|
||||
{{ item.label }}
|
||||
</a-radio>
|
||||
</template>
|
||||
</a-radio-group>
|
||||
|
||||
<a-radio-group v-else-if="compType===CompTypeEnum.RadioButton" v-bind="attrs" v-model:value="state" buttonStyle="solid" @change="handleChange">
|
||||
<template v-for="item in dictOptions" :key="`${item.value}`">
|
||||
<a-radio-button :value="item.value">
|
||||
{{ item.label }}
|
||||
</a-radio-button>
|
||||
</template>
|
||||
</a-radio-group>
|
||||
|
||||
<a-select v-else-if="compType===CompTypeEnum.Select" :placeholder="placeholder" v-bind="attrs" v-model:value="state" @change="handleChange">
|
||||
<a-select-option v-if="showChooseOption" :value="undefined">请选择</a-select-option>
|
||||
<template v-for="item in dictOptions" :key="`${item.value}`">
|
||||
<a-select-option :value="item.value">
|
||||
<span style="display: inline-block;width: 100%" :title=" item.label ">
|
||||
{{ item.label }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</template>
|
||||
</a-select>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted} from 'vue';
|
||||
import {propTypes} from "/@/utils/propTypes";
|
||||
import {useAttrs} from "/@/hooks/core/useAttrs";
|
||||
import {initDictOptions} from "/@/utils/dict/index"
|
||||
import {get, omit} from 'lodash-es';
|
||||
import {useRuleFormItem} from '/@/hooks/component/useFormItem';
|
||||
import {CompTypeEnum} from '/@/enums/CompTypeEnum.ts';
|
||||
export default defineComponent({
|
||||
name: 'JDictSelectTag',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
value: propTypes.oneOfType([
|
||||
propTypes.string,
|
||||
propTypes.number,
|
||||
propTypes.array,
|
||||
]),
|
||||
dictCode: propTypes.string,
|
||||
type: propTypes.string,
|
||||
placeholder: propTypes.string,
|
||||
stringToNumber: propTypes.bool,
|
||||
getPopupContainer: {
|
||||
type: Function,
|
||||
default: (node) => node.parentNode
|
||||
},
|
||||
// 是否显示【请选择】选项
|
||||
showChooseOption: propTypes.bool.def(true),
|
||||
},
|
||||
emits: ['options-change', 'change'],
|
||||
setup(props, {emit, refs}) {
|
||||
const emitData = ref<any[]>([]);
|
||||
const dictOptions = ref<any[]>([]);
|
||||
const attrs = useAttrs();
|
||||
const [state] = useRuleFormItem(props, 'value', 'change', emitData);
|
||||
const getBindValue = Object.assign({}, unref(props), unref(attrs));
|
||||
//组件类型
|
||||
const compType = computed(() => {
|
||||
return (!props.type || props.type === "list") ? 'select' : props.type;
|
||||
});
|
||||
/**
|
||||
* 监听字典code
|
||||
*/
|
||||
watchEffect(() => {
|
||||
props.dictCode && initDictData();
|
||||
});
|
||||
|
||||
async function initDictData() {
|
||||
let {dictCode, stringToNumber} = props;
|
||||
//根据字典Code, 初始化字典数组
|
||||
const dictData = await initDictOptions(dictCode);
|
||||
dictOptions.value = dictData.reduce((prev, next) => {
|
||||
if (next) {
|
||||
const value = next['value'];
|
||||
prev.push({
|
||||
label: next['text'] || next['label'],
|
||||
value: stringToNumber ? +value : value,
|
||||
...omit(next, ['text', 'value']),
|
||||
});
|
||||
}
|
||||
return prev;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function handleChange(e) {
|
||||
emitData.value = [e?.target?.value || e];
|
||||
}
|
||||
|
||||
return {
|
||||
state,
|
||||
compType,
|
||||
attrs,
|
||||
getBindValue,
|
||||
dictOptions,
|
||||
CompTypeEnum,
|
||||
handleChange
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,305 @@
|
|||
<template>
|
||||
<div :class="`${prefixCls}`">
|
||||
<div class="content">
|
||||
<a-tabs :size="`small`" v-model:activeKey="activeKey">
|
||||
<a-tab-pane tab="秒" key="second" v-if="!hideSecond">
|
||||
<SecondUI v-model:value="second" :disabled="disabled"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="分" key="minute">
|
||||
<MinuteUI v-model:value="minute" :disabled="disabled"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="时" key="hour">
|
||||
<HourUI v-model:value="hour" :disabled="disabled"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="日" key="day">
|
||||
<DayUI v-model:value="day" :week="week" :disabled="disabled"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="月" key="month">
|
||||
<MonthUI v-model:value="month" :disabled="disabled"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="周" key="week">
|
||||
<WeekUI v-model:value="week" :day="day" :disabled="disabled"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="年" key="year" v-if="!hideYear && !hideSecond">
|
||||
<YearUI v-model:value="year" :disabled="disabled"/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
<a-divider/>
|
||||
<!-- 执行时间预览 -->
|
||||
<a-row :gutter="8">
|
||||
<a-col :span="18" style="margin-top: 22px;">
|
||||
<a-row :gutter="8">
|
||||
<a-col :span="8" style="margin-bottom: 12px;">
|
||||
<a-input v-model:value="inputValues.second" @blur="onInputBlur">
|
||||
<template #addonBefore>
|
||||
<span class="allow-click" @click="activeKey='second'">秒</span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="8" style="margin-bottom: 12px;">
|
||||
<a-input v-model:value="inputValues.minute" @blur="onInputBlur">
|
||||
<template #addonBefore>
|
||||
<span class="allow-click" @click="activeKey='minute'">分</span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="8" style="margin-bottom: 12px;">
|
||||
<a-input v-model:value="inputValues.hour" @blur="onInputBlur">
|
||||
<template #addonBefore>
|
||||
<span class="allow-click" @click="activeKey='hour'">时</span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="8" style="margin-bottom: 12px;">
|
||||
<a-input v-model:value="inputValues.day" @blur="onInputBlur">
|
||||
<template #addonBefore>
|
||||
<span class="allow-click" @click="activeKey='day'">日</span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="8" style="margin-bottom: 12px;">
|
||||
<a-input v-model:value="inputValues.month" @blur="onInputBlur">
|
||||
<template #addonBefore>
|
||||
<span class="allow-click" @click="activeKey='month'">月</span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="8" style="margin-bottom: 12px;">
|
||||
<a-input v-model:value="inputValues.week" @blur="onInputBlur">
|
||||
<template #addonBefore>
|
||||
<span class="allow-click" @click="activeKey='week'">周</span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-input v-model:value="inputValues.year" @blur="onInputBlur">
|
||||
<template #addonBefore>
|
||||
<span class="allow-click" @click="activeKey='year'">年</span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
<a-col :span="16">
|
||||
<a-input v-model:value="inputValues.cron" @blur="onInputCronBlur">
|
||||
<template #addonBefore>
|
||||
<a-tooltip title="Cron表达式">式</a-tooltip>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<div>近十次执行时间(不含年)</div>
|
||||
<a-textarea type="textarea" :value="preTimeList" :rows="5"/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive, ref, watch, provide } from 'vue'
|
||||
import { useDesign } from '/@/hooks/web/useDesign'
|
||||
import CronParser from 'cron-parser'
|
||||
import SecondUI from './tabs/SecondUI.vue'
|
||||
import MinuteUI from './tabs/MinuteUI.vue'
|
||||
import HourUI from './tabs/HourUI.vue'
|
||||
import DayUI from './tabs/DayUI.vue'
|
||||
import MonthUI from './tabs/MonthUI.vue'
|
||||
import WeekUI from './tabs/WeekUI.vue'
|
||||
import YearUI from './tabs/YearUI.vue'
|
||||
import { cronEmits, cronProps } from './easy.cron.data'
|
||||
import { dateFormat, simpleDebounce } from '/@/utils/common/compUtils'
|
||||
|
||||
const { prefixCls } = useDesign('easy-cron-inner')
|
||||
provide('prefixCls', prefixCls)
|
||||
const emit = defineEmits([...cronEmits])
|
||||
const props = defineProps({ ...cronProps })
|
||||
const activeKey = ref(props.hideSecond ? 'minute' : 'second')
|
||||
const second = ref('*')
|
||||
const minute = ref('*')
|
||||
const hour = ref('*')
|
||||
const day = ref('*')
|
||||
const month = ref('*')
|
||||
const week = ref('?')
|
||||
const year = ref('*')
|
||||
const inputValues = reactive({ second: '', minute: '', hour: '', day: '', month: '', week: '', year: '', cron: '' })
|
||||
const preTimeList = ref('执行预览,会忽略年份参数。')
|
||||
|
||||
// cron表达式
|
||||
const cronValueInner = computed(() => {
|
||||
let result: string[] = []
|
||||
if (!props.hideSecond) {
|
||||
result.push(second.value ? second.value : '*')
|
||||
}
|
||||
result.push(minute.value ? minute.value : '*')
|
||||
result.push(hour.value ? hour.value : '*')
|
||||
result.push(day.value ? day.value : '*')
|
||||
result.push(month.value ? month.value : '*')
|
||||
result.push(week.value ? week.value : '?')
|
||||
if (!props.hideYear && !props.hideSecond) result.push(year.value ? year.value : '*')
|
||||
return result.join(' ')
|
||||
})
|
||||
// 不含年
|
||||
const cronValueNoYear = computed(() => {
|
||||
const v = cronValueInner.value
|
||||
if (props.hideYear || props.hideSecond) return v
|
||||
const vs = v.split(' ')
|
||||
if (vs.length >= 6) {
|
||||
// 转成 Quartz 的规则
|
||||
vs[5] = convertWeekToQuartz(vs[5])
|
||||
}
|
||||
return vs.slice(0, vs.length - 1).join(' ')
|
||||
})
|
||||
const calTriggerList = simpleDebounce(calTriggerListInner, 500)
|
||||
|
||||
watch(() => props.value, (newVal) => {
|
||||
if (newVal === cronValueInner.value) {
|
||||
return
|
||||
}
|
||||
formatValue()
|
||||
})
|
||||
|
||||
|
||||
watch(cronValueInner, (newValue) => {
|
||||
calTriggerList()
|
||||
emitValue(newValue)
|
||||
assignInput()
|
||||
})
|
||||
|
||||
// watch(minute, () => {
|
||||
// if (second.value === '*') {
|
||||
// second.value = '0'
|
||||
// }
|
||||
// })
|
||||
// watch(hour, () => {
|
||||
// if (minute.value === '*') {
|
||||
// minute.value = '0'
|
||||
// }
|
||||
// })
|
||||
// watch(day, () => {
|
||||
// if (day.value !== '?' && hour.value === '*') {
|
||||
// hour.value = '0'
|
||||
// }
|
||||
// })
|
||||
// watch(week, () => {
|
||||
// if (week.value !== '?' && hour.value === '*') {
|
||||
// hour.value = '0'
|
||||
// }
|
||||
// })
|
||||
// watch(month, () => {
|
||||
// if (day.value === '?' && week.value === '*') {
|
||||
// week.value = '1'
|
||||
// } else if (week.value === '?' && day.value === '*') {
|
||||
// day.value = '1'
|
||||
// }
|
||||
// })
|
||||
// watch(year, () => {
|
||||
// if (month.value === '*') {
|
||||
// month.value = '1'
|
||||
// }
|
||||
// })
|
||||
|
||||
assignInput()
|
||||
formatValue()
|
||||
calTriggerListInner()
|
||||
|
||||
function assignInput() {
|
||||
inputValues.second = second.value
|
||||
inputValues.minute = minute.value
|
||||
inputValues.hour = hour.value
|
||||
inputValues.day = day.value
|
||||
inputValues.month = month.value
|
||||
inputValues.week = week.value
|
||||
inputValues.year = year.value
|
||||
inputValues.cron = cronValueInner.value
|
||||
}
|
||||
|
||||
function formatValue() {
|
||||
if (!props.value) return
|
||||
const values = props.value.split(' ').filter(item => !!item)
|
||||
if (!values || values.length <= 0) return
|
||||
let i = 0
|
||||
if (!props.hideSecond) second.value = values[i++]
|
||||
if (values.length > i) minute.value = values[i++]
|
||||
if (values.length > i) hour.value = values[i++]
|
||||
if (values.length > i) day.value = values[i++]
|
||||
if (values.length > i) month.value = values[i++]
|
||||
if (values.length > i) week.value = values[i++]
|
||||
if (values.length > i) year.value = values[i]
|
||||
assignInput()
|
||||
}
|
||||
|
||||
// Quartz 的规则:
|
||||
// 1 = 周日,2 = 周一,3 = 周二,4 = 周三,5 = 周四,6 = 周五,7 = 周六
|
||||
function convertWeekToQuartz(week: string) {
|
||||
let convert = (v: string) => {
|
||||
if (v === '0') {
|
||||
return '1'
|
||||
}
|
||||
if (v === '1') {
|
||||
return '0'
|
||||
}
|
||||
return (Number.parseInt(v) - 1).toString()
|
||||
}
|
||||
// 匹配示例 1-7 or 1/7
|
||||
let patten1 = /^([0-7])([-/])([0-7])$/
|
||||
// 匹配示例 1,4,7
|
||||
let patten2 = /^([0-7])(,[0-7])+$/
|
||||
if (/^[0-7]$/.test(week)) {
|
||||
return convert(week)
|
||||
} else if (patten1.test(week)) {
|
||||
return week.replace(patten1, ($0, before, separator, after) => {
|
||||
if (separator === '/') {
|
||||
return convert(before) + separator + after
|
||||
} else {
|
||||
return convert(before) + separator + convert(after)
|
||||
}
|
||||
})
|
||||
} else if (patten2.test(week)) {
|
||||
return week.split(',').map(v => convert(v)).join(',')
|
||||
}
|
||||
return week
|
||||
}
|
||||
|
||||
function calTriggerListInner() {
|
||||
// 设置了回调函数
|
||||
if (props.remote) {
|
||||
props.remote(cronValueInner.value, +new Date(), v => {
|
||||
preTimeList.value = v
|
||||
})
|
||||
return
|
||||
}
|
||||
const format = 'yyyy-MM-dd hh:mm:ss'
|
||||
const options = {
|
||||
currentDate: dateFormat(new Date(), format),
|
||||
}
|
||||
const iter = CronParser.parseExpression(cronValueNoYear.value, options)
|
||||
const result: string[] = []
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
result.push(dateFormat(new Date(iter.next() as any), format))
|
||||
}
|
||||
preTimeList.value = result.length > 0 ? result.join('\n') : '无执行时间'
|
||||
}
|
||||
|
||||
function onInputBlur() {
|
||||
second.value = inputValues.second
|
||||
minute.value = inputValues.minute
|
||||
hour.value = inputValues.hour
|
||||
day.value = inputValues.day
|
||||
month.value = inputValues.month
|
||||
week.value = inputValues.week
|
||||
year.value = inputValues.year
|
||||
}
|
||||
|
||||
function onInputCronBlur(event) {
|
||||
emitValue(event.target.value)
|
||||
}
|
||||
|
||||
function emitValue(value) {
|
||||
emit('change', value)
|
||||
emit('update:value', value)
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
@import "easy.cron.inner";
|
||||
</style>
|
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<div :class="`${prefixCls}`">
|
||||
<a-input :placeholder="placeholder" v-model:value="editCronValue" :disabled="disabled">
|
||||
<template #addonAfter>
|
||||
<a class="open-btn" :disabled="disabled?'disabled':null" @click="showConfigModal">
|
||||
<Icon icon="ant-design:setting-outlined"/>
|
||||
<span>选择</span>
|
||||
</a>
|
||||
</template>
|
||||
</a-input>
|
||||
<EasyCronModal
|
||||
@register="registerModal"
|
||||
v-model:value="editCronValue"
|
||||
:exeStartTime="exeStartTime"
|
||||
:hideYear="hideYear"
|
||||
:remote="remote"
|
||||
:hideSecond="hideSecond"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import { useDesign } from '/@/hooks/web/useDesign'
|
||||
import { useModal } from '/@/components/Modal'
|
||||
import { propTypes } from '/@/utils/propTypes'
|
||||
import Icon from '/@/components/Icon/src/Icon.vue'
|
||||
import EasyCronModal from './EasyCronModal.vue'
|
||||
import { cronEmits, cronProps } from './easy.cron.data'
|
||||
|
||||
const { prefixCls } = useDesign('easy-cron-input')
|
||||
const emit = defineEmits([...cronEmits])
|
||||
const props = defineProps({
|
||||
...cronProps,
|
||||
placeholder: propTypes.string.def('请输入cron表达式'),
|
||||
exeStartTime: propTypes.oneOfType([
|
||||
propTypes.number,
|
||||
propTypes.string,
|
||||
propTypes.object,
|
||||
]).def(0),
|
||||
})
|
||||
const [registerModal, { openModal }] = useModal()
|
||||
const editCronValue = ref(props.value)
|
||||
|
||||
watch(() => props.value, (newVal) => {
|
||||
if (newVal !== editCronValue.value) {
|
||||
editCronValue.value = newVal
|
||||
}
|
||||
})
|
||||
watch(editCronValue, (newVal) => {
|
||||
emit('change', newVal)
|
||||
emit('update:value', newVal)
|
||||
})
|
||||
|
||||
function showConfigModal() {
|
||||
if (!props.disabled) {
|
||||
openModal()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import "easy.cron.input";
|
||||
</style>
|