chore: eslint

pull/5/head
xingyu 2023-04-27 17:49:24 +08:00
parent f11a881dda
commit 50eb1647a2
580 changed files with 2962 additions and 3115 deletions

View File

@ -1,9 +0,0 @@
// .lintstagedrc.js
module.exports = {
'*.{js,jsx,ts,tsx}': ['prettier --cache --ignore-unknown --write', 'eslint --cache --fix'],
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --cache --write--parser json'],
'package.json': ['prettier --cache --write'],
'*.vue': ['prettier --write', 'eslint --cache --fix', 'stylelint --fix'],
'*.{scss,less,styl,html}': ['prettier --cache --ignore-unknown --write', 'stylelint --fix'],
'*.md': ['prettier --cache --ignore-unknown --write'],
};

View File

@ -1,91 +0,0 @@
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const scopes = fs
.readdirSync(path.resolve(__dirname, 'src'), { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name.replace(/s$/, ''));
// precomputed scope
const scopeComplete = execSync('git status --porcelain || true')
.toString()
.trim()
.split('\n')
.find((r) => ~r.indexOf('M src'))
?.replace(/(\/)/g, '%%')
?.match(/src%%((\w|-)*)/)?.[1]
?.replace(/s$/, '');
/** @type {import('cz-git').UserConfig} */
module.exports = {
ignores: [(commit) => commit.includes('init')],
extends: ['@commitlint/config-conventional'],
rules: {
'body-leading-blank': [2, 'always'],
'footer-leading-blank': [1, 'always'],
'header-max-length': [2, 'always', 108],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never'],
'subject-case': [0],
'type-enum': [
2,
'always',
['feat', 'fix', 'perf', 'style', 'docs', 'test', 'refactor', 'build', 'ci', 'chore', 'revert', 'wip', 'workflow', 'types', 'release'],
],
},
prompt: {
/** @use `yarn commit :f` */
alias: {
f: 'docs: fix typos',
r: 'docs: update README',
s: 'style: update code format',
b: 'build: bump dependencies',
c: 'chore: update config',
},
customScopesAlign: !scopeComplete ? 'top' : 'bottom',
defaultScope: scopeComplete,
scopes: [...scopes, 'mock'],
allowEmptyIssuePrefixs: false,
allowCustomIssuePrefixs: false,
// English
typesAppend: [
{ value: 'wip', name: 'wip: work in process' },
{ value: 'workflow', name: 'workflow: workflow improvements' },
{ value: 'types', name: 'types: type definition file changes' },
],
// 中英文对照版
// messages: {
// type: '选择你要提交的类型 :',
// scope: '选择一个提交范围 (可选):',
// customScope: '请输入自定义的提交范围 :',
// subject: '填写简短精炼的变更描述 :\n',
// body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n',
// breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n',
// footerPrefixsSelect: '选择关联issue前缀 (可选):',
// customFooterPrefixs: '输入自定义issue前缀 :',
// footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
// confirmCommit: '是否提交或修改commit ?',
// },
// types: [
// { value: 'feat', name: 'feat: 新增功能' },
// { value: 'fix', name: 'fix: 修复缺陷' },
// { value: 'docs', name: 'docs: 文档变更' },
// { value: 'style', name: 'style: 代码格式' },
// { value: 'refactor', name: 'refactor: 代码重构' },
// { value: 'perf', name: 'perf: 性能优化' },
// { value: 'test', name: 'test: 添加疏漏测试或已有测试改动' },
// { value: 'build', name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)' },
// { value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
// { value: 'revert', name: 'revert: 回滚 commit' },
// { value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)' },
// { value: 'wip', name: 'wip: 正在开发中' },
// { value: 'workflow', name: 'workflow: 工作流程改进' },
// { value: 'types', name: 'types: 类型定义文件修改' },
// ],
// emptyScopesAlias: 'empty: 不填写',
// customScopesAlias: 'custom: 自定义',
},
};

View File

@ -1,27 +0,0 @@
module.exports = {
printWidth: 140,
// tab宽度为2空格
tabWidth: 2,
semi: true,
vueIndentScriptAndStyle: false,
singleQuote: true,
trailingComma: 'all',
proseWrap: 'never',
htmlWhitespaceSensitivity: 'strict',
endOfLine: 'auto',
plugins: ['prettier-plugin-packagejson'],
overrides: [
{
files: '.*rc',
options: {
parser: 'json',
},
},
{
files: '*.html',
options: {
parser: 'html',
},
},
],
};

View File

@ -7,14 +7,15 @@
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import 'dayjs/locale/zh-cn';
import { ConfigProvider } from 'ant-design-vue';
import { computed } from 'vue';
import { AppProvider } from '@/components/Application';
import { useTitle } from '@/hooks/web/useTitle';
import { useLocale } from '@/locales/useLocale';
import { useAppStore } from '@/store/modules/app';
import 'dayjs/locale/zh-cn';
// support Multi-language
const { getAntdLocale } = useLocale();

View File

@ -1,6 +1,7 @@
import { defHttp } from '@/utils/http/axios';
import { TentantNameVO } from './model/loginModel';
import { getRefreshToken } from '@/utils/auth';
import { defHttp } from '@/utils/http/axios';
import { TentantNameVO } from './model/loginModel';
enum Api {
Login = '/system/auth/login',

View File

@ -1,4 +1,5 @@
import { defHttp } from '@/utils/http/axios';
import { getMenuListResultModel } from './model/menuModel';
enum Api {

View File

@ -1,9 +1,9 @@
export type UserLoginVO = {
export interface UserLoginVO {
username: string;
password: string;
captchaVerification: string;
};
}
export type TentantNameVO = {
export interface TentantNameVO {
id: number;
};
}

View File

@ -1,4 +1,5 @@
import type { RouteMeta } from 'vue-router';
export interface RouteItem {
path: string;
component: any;

View File

@ -79,8 +79,8 @@ export function updateUserPwdApi(oldPassword: string, newPassword: string) {
return defHttp.put({
url: Api.updateUserPwdApi,
data: {
oldPassword: oldPassword,
newPassword: newPassword,
oldPassword,
newPassword,
},
});
}
@ -91,7 +91,6 @@ export function uploadAvatarApi(data) {
url: Api.uploadAvatarApi,
headers: {
'Content-type': ContentTypeEnum.FORM_DATA,
// @ts-ignore
ignoreCancelToken: true,
},
data,

View File

@ -1,9 +1,11 @@
import { UploadApiResult } from './model/uploadModel';
import { defHttp } from '@/utils/http/axios';
import { UploadFileParams } from '@/types/axios';
import { useGlobSetting } from '@/hooks/setting';
import { AxiosProgressEvent } from 'axios';
import { useGlobSetting } from '@/hooks/setting';
import { defHttp } from '@/utils/http/axios';
import { UploadFileParams } from '#/axios';
import { UploadApiResult } from './model/uploadModel';
const { uploadUrl = '' } = useGlobSetting();
/**

View File

@ -1,7 +1,7 @@
import { defHttp } from '@/utils/http/axios';
import { LoginParams, LoginResultModel, GetUserInfoModel } from './model/userModel';
import { ErrorMessageMode } from '#/axios';
import { ErrorMessageMode } from '@/types/axios';
import { GetUserInfoModel, LoginParams, LoginResultModel } from './model/userModel';
enum Api {
Login = '/system/auth/login',

View File

@ -1,6 +1,6 @@
import { defHttp } from '@/utils/http/axios';
export type FormVO = {
export interface FormVO {
id: number;
name: string;
conf: string;
@ -8,7 +8,7 @@ export type FormVO = {
status: number;
remark: string;
createTime: string;
};
}
// 创建工作流的表单定义
export function createForm(data: FormVO) {

View File

@ -1,6 +1,6 @@
import { defHttp } from '@/utils/http/axios';
export type LeaveVO = {
export interface LeaveVO {
id: number;
result: number;
type: number;
@ -9,7 +9,7 @@ export type LeaveVO = {
startTime: string;
endTime: string;
createTime: string;
};
}
// 创建请假申请
export function createLeave(data: LeaveVO) {

View File

@ -1,13 +1,13 @@
import { defHttp } from '@/utils/http/axios';
export type ProcessDefinitionVO = {
export interface ProcessDefinitionVO {
id: string;
version: number;
deploymentTIme: string;
suspensionState: number;
};
}
export type ModelVO = {
export interface ModelVO {
id: number;
formName: string;
key: string;
@ -22,7 +22,7 @@ export type ModelVO = {
status: number;
remark: string;
createTime: string;
};
}
export function getModelPage(params) {
return defHttp.get({ url: '/bpm/model/page', params });
@ -39,8 +39,8 @@ export function updateModel(data: ModelVO) {
// 任务状态修改
export function updateModelState(id: number, state: number) {
const data = {
id: id,
state: state,
id,
state,
};
return defHttp.put({ url: '/bpm/model/update-state', data });
}

View File

@ -1,10 +1,10 @@
import { defHttp } from '@/utils/http/axios';
export type task = {
export interface task {
id: string;
name: string;
};
export type ProcessInstanceVO = {
}
export interface ProcessInstanceVO {
id: number;
name: string;
processDefinitionId: string;
@ -17,7 +17,7 @@ export type ProcessInstanceVO = {
businessKey: string;
createTime: string;
endTime: string;
};
}
export function getMyProcessInstancePage(params) {
return defHttp.get({ url: '/bpm/process-instance/my-page', params });
@ -29,8 +29,8 @@ export function createProcessInstance(data: ProcessInstanceVO) {
export function cancelProcessInstance(id: number, reason: string) {
const data = {
id: id,
reason: reason,
id,
reason,
};
return defHttp.delete({ url: '/bpm/process-instance/cancel', data });
}

View File

@ -1,4 +1,4 @@
export type FormVO = {
export interface FormVO {
id: number;
name: string;
conf: string;
@ -6,26 +6,26 @@ export type FormVO = {
status: number;
remark: string;
createTime: string;
};
}
export type TaskProcessVO = {
export interface TaskProcessVO {
id: string;
name: string;
startUserId: number;
startUserNickname: string;
processDefinitionId: string;
};
}
export type TaskTodoVO = {
export interface TaskTodoVO {
id: string;
name: string;
claimTime: string;
createTime: string;
suspensionState: number;
processInstance: TaskProcessVO;
};
}
export type TaskDoneVO = {
export interface TaskDoneVO {
id: string;
name: string;
claimTime: string;
@ -36,4 +36,4 @@ export type TaskDoneVO = {
result: number;
reason: string;
processInstance: TaskProcessVO;
};
}

View File

@ -1,6 +1,6 @@
import { defHttp } from '@/utils/http/axios';
export type TaskAssignVO = {
export interface TaskAssignVO {
id: number;
modelId: string;
processDefinitionId: string;
@ -8,7 +8,7 @@ export type TaskAssignVO = {
taskDefinitionName: string;
options: string[];
type: number;
};
}
export function getTaskAssignRuleList(params) {
return defHttp.get({ url: '/bpm/task-assign-rule/list', params });

View File

@ -1,6 +1,6 @@
import { defHttp } from '@/utils/http/axios';
export type UserGroupVO = {
export interface UserGroupVO {
id: number;
name: string;
description: string;
@ -8,7 +8,7 @@ export type UserGroupVO = {
status: number;
remark: string;
createTime: string;
};
}
// 创建用户组
export function createUserGroup(data: UserGroupVO) {

View File

@ -1,5 +1,6 @@
import { defHttp } from '@/utils/http/axios';
import type { CodegenUpdateReqVO, CodegenCreateListReqVO } from './types';
import type { CodegenCreateListReqVO, CodegenUpdateReqVO } from './types';
// 查询列表代码生成表定义
export function getCodegenTablePage(params) {

View File

@ -1,4 +1,4 @@
export type CodegenTableVO = {
export interface CodegenTableVO {
id: number;
tableId: number;
isParentMenuIdValid: boolean;
@ -16,9 +16,9 @@ export type CodegenTableVO = {
updateTime: Date;
templateType: number;
parentMenuId: number;
};
}
export type CodegenColumnVO = {
export interface CodegenColumnVO {
id: number;
tableId: number;
columnName: string;
@ -38,24 +38,24 @@ export type CodegenColumnVO = {
listOperationCondition: string;
listOperationResult: number;
htmlType: string;
};
export type DatabaseTableVO = {
}
export interface DatabaseTableVO {
name: string;
comment: string;
};
export type CodegenDetailVO = {
}
export interface CodegenDetailVO {
table: CodegenTableVO;
columns: CodegenColumnVO[];
};
export type CodegenPreviewVO = {
}
export interface CodegenPreviewVO {
filePath: string;
code: string;
};
export type CodegenUpdateReqVO = {
}
export interface CodegenUpdateReqVO {
table: CodegenTableVO;
columns: CodegenColumnVO[];
};
export type CodegenCreateListReqVO = {
}
export interface CodegenCreateListReqVO {
dataSourceConfigId: number;
tableNames: string[];
};
}

View File

@ -1,5 +1,6 @@
import { defHttp } from '@/utils/http/axios';
import type { DictDataVO, DictDataPageReqVO, DictDataExportReqVO } from './types';
import type { DictDataExportReqVO, DictDataPageReqVO, DictDataVO } from './types';
// 查询字典数据(精简)列表
export function listSimpleDictData() {

View File

@ -1,5 +1,6 @@
import { defHttp } from '@/utils/http/axios';
import type { DictTypeVO, DictTypePageReqVO, DictTypeExportReqVO } from './types';
import type { DictTypeExportReqVO, DictTypePageReqVO, DictTypeVO } from './types';
// 查询字典(精简)列表
export function listSimpleDictType() {

View File

@ -1,6 +1,7 @@
import { defHttp } from '@/utils/http/axios';
import qs from 'qs';
import { defHttp } from '@/utils/http/axios';
// 获得站内信分页
export function getNotifyMessagePage(params) {
return defHttp.get({ url: '/system/notify-message/page', params });

View File

@ -9,7 +9,7 @@ export interface OperateLogVO {
name: string;
type: number;
content: string;
exts: Map<String, Object>;
exts: Map<string, Object>;
defHttpMethod: string;
defHttpUrl: string;
userIp: string;

View File

@ -18,7 +18,7 @@ export interface SmsTemplateVO {
export interface SendSmsReqVO {
mobile: string;
templateCode: string;
templateParams: Map<String, Object>;
templateParams: Map<string, Object>;
}
export interface SmsTemplatePageReqVO {

View File

@ -1,11 +1,11 @@
import { withInstall } from '@/utils';
import appDarkModeToggle from './src/AppDarkModeToggle.vue';
import appLocalePicker from './src/AppLocalePicker.vue';
import appLogo from './src/AppLogo.vue';
import appProvider from './src/AppProvider.vue';
import appSearch from './src/search/AppSearch.vue';
import appSizePicker from './src/AppSizePicker.vue';
import appLocalePicker from './src/AppLocalePicker.vue';
import appDarkModeToggle from './src/AppDarkModeToggle.vue';
import appSearch from './src/search/AppSearch.vue';
export { useAppProviderContext } from './src/useAppContext';

View File

@ -7,12 +7,13 @@
</template>
<script lang="ts" setup>
import { computed, unref } from 'vue';
import { SvgIcon } from '@/components/Icon';
import { useDesign } from '@/hooks/web/useDesign';
import { useRootSetting } from '@/hooks/setting/useRootSetting';
import { updateHeaderBgColor, updateSidebarBgColor } from '@/logics/theme/updateBackground';
import { updateDarkTheme } from '@/logics/theme/dark';
import { ThemeEnum } from '@/enums/appEnum';
import { useRootSetting } from '@/hooks/setting/useRootSetting';
import { useDesign } from '@/hooks/web/useDesign';
import { updateDarkTheme } from '@/logics/theme/dark';
import { updateHeaderBgColor, updateSidebarBgColor } from '@/logics/theme/updateBackground';
const { prefixCls } = useDesign('dark-switch');
const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();

View File

@ -4,8 +4,8 @@
:trigger="['click']"
:dropMenuList="localeList"
:selectedKeys="selectedKeys"
@menu-event="handleMenuEvent"
overlayClassName="app-locale-picker-overlay"
@menu-event="handleMenuEvent"
>
<span class="cursor-pointer flex items-center">
<Icon icon="ion:language" />
@ -14,13 +14,14 @@
</Dropdown>
</template>
<script lang="ts" setup>
import type { LocaleType } from '@/types/config';
import { computed, ref, unref, watchEffect } from 'vue';
import type { DropMenu } from '@/components/Dropdown';
import { ref, watchEffect, unref, computed } from 'vue';
import { Dropdown } from '@/components/Dropdown';
import { Icon } from '@/components/Icon';
import { useLocale } from '@/locales/useLocale';
import { localeList } from '@/settings/localeSetting';
import type { LocaleType } from '#/config';
const props = defineProps({
/**

View File

@ -1,18 +1,19 @@
<template>
<div class="anticon" :class="getAppLogoClass" @click="goHome">
<img src="@/assets/images/logo.png" />
<div class="ml-2 truncate md:opacity-100" :class="getTitleClass" v-show="showTitle">
<div v-show="showTitle" class="ml-2 truncate md:opacity-100" :class="getTitleClass">
{{ title }}
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, unref } from 'vue';
import { PageEnum } from '@/enums/pageEnum';
import { useGlobSetting } from '@/hooks/setting';
import { useGo } from '@/hooks/web/usePage';
import { useMenuSetting } from '@/hooks/setting/useMenuSetting';
import { useDesign } from '@/hooks/web/useDesign';
import { PageEnum } from '@/enums/pageEnum';
import { useGo } from '@/hooks/web/usePage';
const props = defineProps({
//

View File

@ -1,10 +1,12 @@
<script lang="ts">
import { defineComponent, toRefs, ref, unref } from 'vue';
import { createAppProviderContext } from './useAppContext';
import { defineComponent, ref, toRefs, unref } from 'vue';
import { MenuModeEnum, MenuTypeEnum } from '@/enums/menuEnum';
import { createBreakpointListen } from '@/hooks/event/useBreakpoint';
import { prefixCls } from '@/settings/designSetting';
import { useAppStore } from '@/store/modules/app';
import { MenuModeEnum, MenuTypeEnum } from '@/enums/menuEnum';
import { createAppProviderContext } from './useAppContext';
const props = {
/**

View File

@ -4,8 +4,8 @@
:trigger="['click']"
:dropMenuList="sizeList"
:selectedKeys="selectedKeys"
@menu-event="handleMenuEvent"
overlayClassName="app-locale-picker-overlay"
@menu-event="handleMenuEvent"
>
<span class="cursor-pointer flex items-center">
<Icon icon="mdi:format-size" />
@ -14,13 +14,14 @@
</Dropdown>
</template>
<script lang="ts" setup>
import type { AppSizeType } from '@/types/config';
import { computed, ref, unref, watchEffect } from 'vue';
import type { DropMenu } from '@/components/Dropdown';
import { ref, watchEffect, unref, computed } from 'vue';
import { Dropdown } from '@/components/Dropdown';
import { Icon } from '@/components/Icon';
import { sizeList } from '@/settings/sizeSetting';
import { useAppStore } from '@/store/modules/app';
import type { AppSizeType } from '#/config';
const appStore = useAppStore();

View File

@ -1,10 +1,12 @@
<script lang="tsx">
import { defineComponent, ref, unref } from 'vue';
import { Tooltip } from 'ant-design-vue';
import { SearchOutlined } from '@ant-design/icons-vue';
import AppSearchModal from './AppSearchModal.vue';
import { Tooltip } from 'ant-design-vue';
import { defineComponent, ref, unref } from 'vue';
import { useI18n } from '@/hooks/web/useI18n';
import AppSearchModal from './AppSearchModal.vue';
export default defineComponent({
name: 'AppSearch',
setup() {

View File

@ -11,9 +11,11 @@
</template>
<script lang="ts" setup>
import AppSearchKeyItem from './AppSearchKeyItem.vue';
import { useDesign } from '@/hooks/web/useDesign';
import { useI18n } from '@/hooks/web/useI18n';
import AppSearchKeyItem from './AppSearchKeyItem.vue';
const { prefixCls } = useDesign('app-search-footer');
const { t } = useI18n();
</script>

View File

@ -5,6 +5,7 @@
</template>
<script lang="ts" setup>
import { Icon } from '@/components/Icon';
defineProps({
icon: String,
});

View File

@ -1,10 +1,10 @@
<template>
<Teleport to="body">
<transition name="zoom-fade" mode="out-in">
<div :class="getClass" @click.stop v-if="visible">
<div :class="`${prefixCls}-content`" v-click-outside="handleClose">
<div v-if="visible" :class="getClass" @click.stop>
<div v-click-outside="handleClose" :class="`${prefixCls}-content`">
<div :class="`${prefixCls}-input__wrapper`">
<a-input :class="`${prefixCls}-input`" :placeholder="t('common.searchText')" ref="inputRef" allow-clear @change="handleSearch">
<a-input ref="inputRef" :class="`${prefixCls}-input`" :placeholder="t('common.searchText')" allow-clear @change="handleSearch">
<template #prefix>
<SearchOutlined />
</template>
@ -14,24 +14,24 @@
</span>
</div>
<div :class="`${prefixCls}-not-data`" v-show="getIsNotData">
<div v-show="getIsNotData" :class="`${prefixCls}-not-data`">
{{ t('component.app.searchNotData') }}
</div>
<ul :class="`${prefixCls}-list`" v-show="!getIsNotData" ref="scrollWrap">
<ul v-show="!getIsNotData" ref="scrollWrap" :class="`${prefixCls}-list`">
<li
:ref="setRefs(index)"
v-for="(item, index) in searchResult"
:ref="setRefs(index)"
:key="item.path"
:data-index="index"
@mouseenter="handleMouseenter"
@click="handleEnter"
:class="[
`${prefixCls}-list__item`,
{
[`${prefixCls}-list__item--active`]: activeIndex === index,
},
]"
@mouseenter="handleMouseenter"
@click="handleEnter"
>
<div :class="`${prefixCls}-list__item-icon`">
<Icon :icon="item.icon || 'mdi:form-select'" :size="20" />
@ -52,16 +52,18 @@
</template>
<script lang="ts" setup>
import { computed, unref, ref, watch, nextTick } from 'vue';
import { SearchOutlined } from '@ant-design/icons-vue';
import AppSearchFooter from './AppSearchFooter.vue';
import { computed, nextTick, ref, unref, watch } from 'vue';
import { Icon } from '@/components/Icon';
import vClickOutside from '@/directives/clickOutside';
import { useDesign } from '@/hooks/web/useDesign';
import { useRefs } from '@/hooks/core/useRefs';
import { useMenuSearch } from './useMenuSearch';
import { useI18n } from '@/hooks/web/useI18n';
import { useAppInject } from '@/hooks/web/useAppInject';
import { useDesign } from '@/hooks/web/useDesign';
import { useI18n } from '@/hooks/web/useI18n';
import AppSearchFooter from './AppSearchFooter.vue';
import { useMenuSearch } from './useMenuSearch';
const props = defineProps({
visible: { type: Boolean },

View File

@ -1,12 +1,13 @@
import type { Menu } from '@/router/types';
import { ref, onBeforeMount, unref, Ref, nextTick } from 'vue';
import { getMenus } from '@/router/menus';
import { cloneDeep } from 'lodash-es';
import { filter, forEach } from '@/utils/helper/treeHelper';
import { useGo } from '@/hooks/web/usePage';
import { useScrollTo } from '@/hooks/event/useScrollTo';
import { onKeyStroke, useDebounceFn } from '@vueuse/core';
import { cloneDeep } from 'lodash-es';
import { nextTick, onBeforeMount, Ref, ref, unref } from 'vue';
import { useScrollTo } from '@/hooks/event/useScrollTo';
import { useI18n } from '@/hooks/web/useI18n';
import { useGo } from '@/hooks/web/usePage';
import { getMenus } from '@/router/menus';
import type { Menu } from '@/router/types';
import { filter, forEach } from '@/utils/helper/treeHelper';
export interface SearchResult {
name: string;

View File

@ -1,4 +1,5 @@
import { InjectionKey, Ref } from 'vue';
import { createContext, useContext } from '@/hooks/core/useContext';
export interface AppProviderContextProps {

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import authority from './src/Authority.vue';
export const Authority = withInstall(authority);

View File

@ -3,6 +3,7 @@
-->
<script lang="ts">
import { defineComponent } from 'vue';
import { RoleEnum } from '@/enums/roleEnum';
import { usePermission } from '@/hooks/web/usePermission';
import { getSlot } from '@/utils/helper/tsxHelper';

View File

@ -1,7 +1,8 @@
import { withInstall } from '@/utils';
import basicArrow from './src/BasicArrow.vue';
import basicTitle from './src/BasicTitle.vue';
import basicHelp from './src/BasicHelp.vue';
import basicTitle from './src/BasicTitle.vue';
export const BasicArrow = withInstall(basicArrow);
export const BasicTitle = withInstall(basicTitle);

View File

@ -5,6 +5,7 @@
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { Icon } from '@/components/Icon';
import { useDesign } from '@/hooks/web/useDesign';

View File

@ -1,12 +1,13 @@
<script lang="tsx">
import type { CSSProperties } from 'vue';
import { defineComponent, computed, unref } from 'vue';
import { Tooltip } from 'ant-design-vue';
import { InfoCircleOutlined } from '@ant-design/icons-vue';
import { getPopupContainer } from '@/utils';
import { isString, isArray } from '@/utils/is';
import { getSlot } from '@/utils/helper/tsxHelper';
import { Tooltip } from 'ant-design-vue';
import type { CSSProperties } from 'vue';
import { computed, defineComponent, unref } from 'vue';
import { useDesign } from '@/hooks/web/useDesign';
import { getPopupContainer } from '@/utils';
import { getSlot } from '@/utils/helper/tsxHelper';
import { isArray, isString } from '@/utils/is';
const props = {
/**

View File

@ -1,14 +1,16 @@
<template>
<span :class="getClass">
<slot></slot>
<BasicHelp :class="`${prefixCls}-help`" v-if="helpMessage" :text="helpMessage" />
<BasicHelp v-if="helpMessage" :class="`${prefixCls}-help`" :text="helpMessage" />
</span>
</template>
<script lang="ts" setup>
import { useSlots, computed } from 'vue';
import BasicHelp from './BasicHelp.vue';
import { computed, useSlots } from 'vue';
import { useDesign } from '@/hooks/web/useDesign';
import BasicHelp from './BasicHelp.vue';
const props = defineProps({
/**
* Help text list or string

View File

@ -1,5 +1,7 @@
import { withInstall } from '@/utils';
import type { ExtractPropTypes } from 'vue';
import { withInstall } from '@/utils';
import button from './src/BasicButton.vue';
import popConfirmButton from './src/PopConfirmButton.vue';
import { buttonProps } from './src/props';

View File

@ -1,19 +1,21 @@
<template>
<Button v-bind="getBindValue" :class="getButtonClass" @click="onClick">
<template #default="data">
<Icon :icon="preIcon" v-if="preIcon" :size="iconSize" />
<Icon v-if="preIcon" :icon="preIcon" :size="iconSize" />
<slot v-bind="data || {}"></slot>
<Icon :icon="postIcon" v-if="postIcon" :size="iconSize" />
<Icon v-if="postIcon" :icon="postIcon" :size="iconSize" />
</template>
</Button>
</template>
<script lang="ts" setup name="AButton" extends="Button" indeterminate="false">
import { Button } from 'ant-design-vue';
import { computed, unref } from 'vue';
import { Icon } from '@/components/Icon';
import { buttonProps } from './props';
import { useAttrs } from '@/hooks/core/useAttrs';
import { buttonProps } from './props';
const props = defineProps(buttonProps);
// get component class
const attrs = useAttrs({ excludeDefaultKeys: false });

View File

@ -1,11 +1,13 @@
<script lang="ts">
import { computed, defineComponent, h, unref } from 'vue';
import BasicButton from './BasicButton.vue';
import { Popconfirm } from 'ant-design-vue';
import { extendSlots } from '@/utils/helper/tsxHelper';
import { omit } from 'lodash-es';
import { computed, defineComponent, h, unref } from 'vue';
import { useAttrs } from '@/hooks/core/useAttrs';
import { useI18n } from '@/hooks/web/useI18n';
import { extendSlots } from '@/utils/helper/tsxHelper';
import BasicButton from './BasicButton.vue';
const props = {
/**

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import cardList from './src/CardList.vue';
export const CardList = withInstall(cardList);

View File

@ -6,8 +6,8 @@
<div class="p-2 bg-white">
<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>
<div class="flex justify-end space-x-2">
<slot name="header"></slot>
<Tooltip>
<template #title>
<div class="w-50">每行显示数量</div>
@ -68,15 +68,18 @@
</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 { Avatar, Card, Image, List, Slider, Tooltip, Typography } from 'ant-design-vue';
import { computed, onMounted, ref } from 'vue';
import { Button } from '@/components/Button';
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';
import { propTypes } from '@/utils/propTypes';
import { grid, useSlider } from './data';
const ListItem = List.Item;
const CardMeta = Card.Meta;
const TypographyText = Typography.Text;

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import codeEditor from './src/CodeEditor.vue';
import jsonPreview from './src/json-preview/JsonPreview.vue';

View File

@ -1,12 +1,14 @@
<template>
<div class="h-full">
<CodeMirrorEditor :value="getValue" @change="handleValueChange" :mode="mode" :readonly="readonly" />
<CodeMirrorEditor :value="getValue" :mode="mode" :readonly="readonly" @change="handleValueChange" />
</div>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import CodeMirrorEditor from './codemirror/CodeMirror.vue';
import { isString } from '@/utils/is';
import CodeMirrorEditor from './codemirror/CodeMirror.vue';
import { MODE } from './typing';
const props = defineProps({

View File

@ -1,14 +1,8 @@
<template>
<div class="relative !h-full w-full overflow-hidden" ref="el"></div>
<div ref="el" class="relative !h-full w-full overflow-hidden"></div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted, watchEffect, watch, unref, nextTick } from 'vue';
import { useDebounceFn } from '@vueuse/core';
import { useAppStore } from '@/store/modules/app';
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn';
import CodeMirror from 'codemirror';
import { MODE } from './../typing';
// css
import './codemirror.css';
import 'codemirror/theme/idea.css';
@ -18,6 +12,15 @@ import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/css/css';
import 'codemirror/mode/htmlmixed/htmlmixed';
import { useDebounceFn } from '@vueuse/core';
import CodeMirror from 'codemirror';
import { nextTick, onMounted, onUnmounted, ref, unref, watch, watchEffect } from 'vue';
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn';
import { useAppStore } from '@/store/modules/app';
import { MODE } from './../typing';
const props = defineProps({
mode: {
type: String as PropType<MODE>,

View File

@ -1,13 +1,13 @@
import CodeMirror from 'codemirror';
import './codemirror.css';
import 'codemirror/theme/idea.css';
import 'codemirror/theme/material-palenight.css';
// import 'codemirror/addon/lint/lint.css';
// modes
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/css/css';
import 'codemirror/mode/htmlmixed/htmlmixed';
import CodeMirror from 'codemirror';
// addons
// import 'codemirror/addon/edit/closebrackets';
// import 'codemirror/addon/edit/closetag';

View File

@ -3,9 +3,10 @@
</template>
<script lang="ts" setup>
import VueJsonPretty from 'vue-json-pretty';
import 'vue-json-pretty/lib/styles.css';
import VueJsonPretty from 'vue-json-pretty';
defineProps({
data: Object,
});

View File

@ -1,7 +1,8 @@
import { withInstall } from '@/utils';
import collapseContainer from './src/collapse/CollapseContainer.vue';
import scrollContainer from './src/ScrollContainer.vue';
import lazyContainer from './src/LazyContainer.vue';
import scrollContainer from './src/ScrollContainer.vue';
export const CollapseContainer = withInstall(collapseContainer);
export const ScrollContainer = withInstall(scrollContainer);

View File

@ -1,18 +1,19 @@
<template>
<transition-group class="h-full w-full" v-bind="$attrs" ref="elRef" :name="transitionName" :tag="tag" mode="out-in">
<div key="component" v-if="state.isInit">
<transition-group v-bind="$attrs" ref="elRef" class="h-full w-full" :name="transitionName" :tag="tag" mode="out-in">
<div v-if="state.isInit" key="component">
<slot :loading="state.loading"></slot>
</div>
<div key="skeleton" v-else>
<slot name="skeleton" v-if="$slots.skeleton"></slot>
<div v-else key="skeleton">
<slot v-if="$slots.skeleton" name="skeleton"></slot>
<Skeleton v-else />
</div>
</transition-group>
</template>
<script lang="ts" setup name="LazyContainer" inheritAttrs="false">
import { reactive, onMounted, ref, toRef } from 'vue';
import { Skeleton } from 'ant-design-vue';
import { useTimeoutFn } from '@vueuse/core';
import { Skeleton } from 'ant-design-vue';
import { onMounted, reactive, ref, toRef } from 'vue';
import { useIntersectionObserver } from '@/hooks/event/useIntersectionObserver';
interface State {

View File

@ -5,7 +5,8 @@
</template>
<script lang="ts" setup name="ScrollContainer">
import { ref, unref, nextTick } from 'vue';
import { nextTick, ref, unref } from 'vue';
import { Scrollbar, ScrollbarType } from '@/components/Scrollbar';
import { useScrollTo } from '@/hooks/event/useScrollTo';

View File

@ -1,12 +1,14 @@
<script lang="tsx">
import { ref, unref, defineComponent, type PropType, type ExtractPropTypes } from 'vue';
import { isNil } from 'lodash-es';
import { Skeleton } from 'ant-design-vue';
import { CollapseTransition } from '@/components/Transition';
import CollapseHeader from './CollapseHeader.vue';
import { triggerWindowResize } from '@/utils/event';
import { useTimeoutFn } from '@vueuse/core';
import { Skeleton } from 'ant-design-vue';
import { isNil } from 'lodash-es';
import { defineComponent, type ExtractPropTypes, type PropType, ref, unref } from 'vue';
import { CollapseTransition } from '@/components/Transition';
import { useDesign } from '@/hooks/web/useDesign';
import { triggerWindowResize } from '@/utils/event';
import CollapseHeader from './CollapseHeader.vue';
const collapseContainerProps = {
title: { type: String, default: '' },

View File

@ -1,7 +1,8 @@
<script lang="tsx">
import { defineComponent, computed, unref, type ExtractPropTypes } from 'vue';
import { useDesign } from '@/hooks/web/useDesign';
import { computed, defineComponent, type ExtractPropTypes, unref } from 'vue';
import { BasicArrow, BasicTitle } from '@/components/Basic';
import { useDesign } from '@/hooks/web/useDesign';
const collapseHeaderProps = {
prefixCls: String,

View File

@ -1,3 +1,2 @@
export { createContextMenu, destroyContextMenu } from './src/createContextMenu';
export * from './src/typing';

View File

@ -1,9 +1,11 @@
<script lang="tsx">
import type { ContextMenuItem, ItemContentProps, Axis } from './typing';
import type { FunctionalComponent, CSSProperties } from 'vue';
import { defineComponent, nextTick, onMounted, computed, ref, unref, onUnmounted } from 'vue';
import { Divider, Menu } from 'ant-design-vue';
import type { CSSProperties, FunctionalComponent } from 'vue';
import { computed, defineComponent, nextTick, onMounted, onUnmounted, ref, unref } from 'vue';
import { Icon } from '@/components/Icon';
import { Menu, Divider } from 'ant-design-vue';
import type { Axis, ContextMenuItem, ItemContentProps } from './typing';
const prefixCls = 'context-menu';

View File

@ -1,8 +1,10 @@
import contextMenuVue from './ContextMenu.vue';
import { isClient } from '@/utils/is';
import { CreateContextOptions, ContextMenuProps } from './typing';
import { createVNode, render } from 'vue';
import { isClient } from '@/utils/is';
import contextMenuVue from './ContextMenu.vue';
import { ContextMenuProps, CreateContextOptions } from './typing';
const menuManager: {
domList: Element[];
resolve: Fn;

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import countButton from './src/CountButton.vue';
import countdownInput from './src/CountdownInput.vue';

View File

@ -1,14 +1,16 @@
<template>
<Button v-bind="$attrs" :disabled="isStart" @click="handleStart" :loading="loading">
<Button v-bind="$attrs" :disabled="isStart" :loading="loading" @click="handleStart">
{{ getButtonText }}
</Button>
</template>
<script lang="ts" setup name="CountButton">
import { ref, watchEffect, computed, unref } from 'vue';
import { Button } from 'ant-design-vue';
import { useCountdown } from './useCountdown';
import { isFunction } from '@/utils/is';
import { computed, ref, unref, watchEffect } from 'vue';
import { useI18n } from '@/hooks/web/useI18n';
import { isFunction } from '@/utils/is';
import { useCountdown } from './useCountdown';
const props = defineProps({
value: { type: [Object, Number, String, Array] },

View File

@ -3,15 +3,17 @@
<template #addonAfter>
<CountButton :size="size" :count="count" :value="state" :beforeStartFunc="sendCodeApi" />
</template>
<template #[item]="data" v-for="item in Object.keys($slots).filter((k) => k !== 'addonAfter')">
<template v-for="item in Object.keys($slots).filter((k) => k !== 'addonAfter')" #[item]="data">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</a-input>
</template>
<script lang="ts" setup name="CountDownInput" inheritAttrs="false">
import CountButton from './CountButton.vue';
import { useDesign } from '@/hooks/web/useDesign';
import { useRuleFormItem } from '@/hooks/component/useFormItem';
import { useDesign } from '@/hooks/web/useDesign';
import CountButton from './CountButton.vue';
const props = defineProps({
value: { type: String },
size: { type: String, validator: (v: string) => ['default', 'large', 'small'].includes(v) },

View File

@ -1,5 +1,5 @@
import { ref, unref } from 'vue';
import { tryOnUnmounted } from '@vueuse/core';
import { ref, unref } from 'vue';
export function useCountdown(count: number) {
const currentCount = ref(count);

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import countTo from './src/CountTo.vue';
export const CountTo = withInstall(countTo);

View File

@ -4,8 +4,9 @@
</span>
</template>
<script lang="ts" setup name="CountTo">
import { ref, computed, watchEffect, unref, onMounted, watch } from 'vue';
import { useTransition, TransitionPresets } from '@vueuse/core';
import { TransitionPresets, useTransition } from '@vueuse/core';
import { computed, onMounted, ref, unref, watch, watchEffect } from 'vue';
import { isNumber } from '@/utils/is';
const emit = defineEmits(['onStarted', 'onFinished']);

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import cropperImage from './src/Cropper.vue';
import avatarCropper from './src/CropperAvatar.vue';

View File

@ -1,12 +1,12 @@
<template>
<BasicModal
v-bind="$attrs"
@register="register"
:title="t('component.cropper.modalTitle')"
width="800px"
:canFullscreen="false"
@ok="handleOk"
:okText="t('component.cropper.okText')"
@register="register"
@ok="handleOk"
>
<div :class="prefixCls">
<div :class="`${prefixCls}-left`">
@ -77,7 +77,7 @@
</div>
<div :class="`${prefixCls}-right`">
<div :class="`${prefixCls}-preview`">
<img :src="previewSource" v-if="previewSource" :alt="t('component.cropper.preview')" />
<img v-if="previewSource" :src="previewSource" :alt="t('component.cropper.preview')" />
</div>
<template v-if="previewSource">
<div :class="`${prefixCls}-group`">
@ -92,17 +92,23 @@
</BasicModal>
</template>
<script lang="ts" setup name="CropperModal">
import type { CropendResult, Cropper } from './typing';
import { Avatar, Space, Tooltip, Upload } from 'ant-design-vue';
import { ref } from 'vue';
import CropperImage from './Cropper.vue';
import { Space, Upload, Avatar, Tooltip } from 'ant-design-vue';
import { useDesign } from '@/hooks/web/useDesign';
import { BasicModal, useModalInner } from '@/components/Modal';
import { useDesign } from '@/hooks/web/useDesign';
import { useI18n } from '@/hooks/web/useI18n';
import { dataURLtoBlob } from '@/utils/file/base64Conver';
import { isFunction } from '@/utils/is';
import { useI18n } from '@/hooks/web/useI18n';
type apiFunParams = { file: Blob; name: string; filename: string };
import CropperImage from './Cropper.vue';
import type { CropendResult, Cropper } from './typing';
interface apiFunParams {
file: Blob;
name: string;
filename: string;
}
const emit = defineEmits(['uploadSuccess', 'register']);
@ -165,7 +171,7 @@ async function handleOk() {
const result = await uploadApi({ name: 'file', file: blob, filename });
emit('uploadSuccess', { source: previewSource.value, data: result.url });
} else {
emit('uploadSuccess', { source: previewSource.value, data: blob, filename: filename });
emit('uploadSuccess', { source: previewSource.value, data: blob, filename });
}
closeModal();
} finally {

View File

@ -4,12 +4,13 @@
</div>
</template>
<script lang="ts" setup name="CropperImage">
import { CSSProperties, useAttrs } from 'vue';
import { onMounted, ref, unref, computed, onUnmounted } from 'vue';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
import { useDesign } from '@/hooks/web/useDesign';
import { useDebounceFn } from '@vueuse/core';
import Cropper from 'cropperjs';
import { computed, CSSProperties, onMounted, onUnmounted, ref, unref, useAttrs } from 'vue';
import { useDesign } from '@/hooks/web/useDesign';
const emit = defineEmits(['cropend', 'ready', 'cropendError']);
const attrs = useAttrs();
@ -121,13 +122,13 @@ function croppered() {
if (!cropper.value) {
return;
}
let imgInfo = cropper.value.getData();
const imgInfo = cropper.value.getData();
const canvas = props.circled ? getRoundedCanvas() : cropper.value.getCroppedCanvas();
canvas.toBlob((blob) => {
if (!blob) {
return;
}
let fileReader: FileReader = new FileReader();
const fileReader: FileReader = new FileReader();
fileReader.readAsDataURL(blob);
fileReader.onloadend = (e) => {
emit('cropend', {

View File

@ -4,24 +4,26 @@
<div :class="`${prefixCls}-image-mask`" :style="getImageWrapperStyle">
<Icon icon="ant-design:cloud-upload-outlined" :size="getIconWidth" :style="getImageWrapperStyle" color="#d6d6d6" />
</div>
<img :src="sourceValue" v-if="sourceValue" alt="avatar" />
<img v-if="sourceValue" :src="sourceValue" alt="avatar" />
</div>
<a-button :class="`${prefixCls}-upload-btn`" @click="openModal" v-if="showBtn" v-bind="btnProps">
<a-button v-if="showBtn" :class="`${prefixCls}-upload-btn`" v-bind="btnProps" @click="openModal">
{{ btnText ? btnText : t('component.cropper.selectImage') }}
</a-button>
<CopperModal @register="register" @upload-success="handleUploadSuccess" :uploadApi="uploadApi" :src="sourceValue" />
<CopperModal :uploadApi="uploadApi" :src="sourceValue" @register="register" @upload-success="handleUploadSuccess" />
</div>
</template>
<script lang="ts" setup name="CropperAvatar">
import { computed, CSSProperties, unref, ref, watchEffect, watch } from 'vue';
import CopperModal from './CopperModal.vue';
import { useDesign } from '@/hooks/web/useDesign';
import { useModal } from '@/components/Modal';
import { useMessage } from '@/hooks/web/useMessage';
import { useI18n } from '@/hooks/web/useI18n';
import { computed, CSSProperties, ref, unref, watch, watchEffect } from 'vue';
import type { ButtonProps } from '@/components/Button';
import { Icon } from '@/components/Icon';
import { useModal } from '@/components/Modal';
import { useDesign } from '@/hooks/web/useDesign';
import { useI18n } from '@/hooks/web/useI18n';
import { useMessage } from '@/hooks/web/useMessage';
import CopperModal from './CopperModal.vue';
const emit = defineEmits(['update:value', 'change']);

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import description from './src/Description.vue';
export * from './src/typing';

View File

@ -1,16 +1,18 @@
<script lang="tsx">
import type { DescriptionProps, DescInstance, DescItem } from './typing';
import type { DescriptionsProps } from 'ant-design-vue/es/descriptions';
import type { CSSProperties } from 'vue';
import type { CollapseContainerOptions } from '@/components/Container';
import { defineComponent, computed, ref, unref, toRefs } from 'vue';
import { get } from 'lodash-es';
import { Descriptions } from 'ant-design-vue';
import type { DescriptionsProps } from 'ant-design-vue/es/descriptions';
import { get } from 'lodash-es';
import type { CSSProperties } from 'vue';
import { computed, defineComponent, ref, toRefs, unref } from 'vue';
import type { CollapseContainerOptions } from '@/components/Container';
import { CollapseContainer } from '@/components/Container';
import { useDesign } from '@/hooks/web/useDesign';
import { isFunction } from '@/utils/is';
import { getSlot } from '@/utils/helper/tsxHelper';
import { useAttrs } from '@/hooks/core/useAttrs';
import { useDesign } from '@/hooks/web/useDesign';
import { getSlot } from '@/utils/helper/tsxHelper';
import { isFunction } from '@/utils/is';
import type { DescInstance, DescItem, DescriptionProps } from './typing';
const props = {
useCollapse: { type: Boolean, default: true },

View File

@ -1,6 +1,7 @@
import type { VNode, CSSProperties } from 'vue';
import type { CollapseContainerOptions } from '@/components/Container';
import type { DescriptionsProps } from 'ant-design-vue/es/descriptions';
import type { CSSProperties, VNode } from 'vue';
import type { CollapseContainerOptions } from '@/components/Container';
export interface DescItem {
labelMinWidth?: number;

View File

@ -1,7 +1,9 @@
import type { DescriptionProps, DescInstance, UseDescReturnType } from './typing';
import { ref, getCurrentInstance, unref } from 'vue';
import { getCurrentInstance, ref, unref } from 'vue';
import { isProdMode } from '@/utils/env';
import type { DescInstance, DescriptionProps, UseDescReturnType } from './typing';
export function useDescription(props?: Partial<DescriptionProps>): UseDescReturnType {
if (!getCurrentInstance()) {
throw new Error('useDescription() can only be used inside setup() or functional components!');

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import dictTag from './src/DictTag.vue';
export const DictTag = withInstall(dictTag);

View File

@ -1,7 +1,8 @@
<script lang="tsx">
import { defineComponent, PropType, ref } from 'vue';
import { isHexColor } from '@/utils/color';
import { Tag } from 'ant-design-vue';
import { defineComponent, PropType, ref } from 'vue';
import { isHexColor } from '@/utils/color';
import { DictDataType, getBoolDictOptions, getDictOptions, getStrDictOptions } from '@/utils/dict';
export default defineComponent({

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import basicDrawer from './src/BasicDrawer.vue';
export const BasicDrawer = withInstall(basicDrawer);

View File

@ -1,6 +1,6 @@
<template>
<Drawer :class="prefixCls" @close="onClose" v-bind="getBindValues">
<template #title v-if="!$slots.title">
<Drawer :class="prefixCls" v-bind="getBindValues" @close="onClose">
<template v-if="!$slots.title" #title>
<DrawerHeader :title="(getMergeProps.title as any)" :isDetail="isDetail" :showDetailBack="showDetailBack" @close="onClose">
<template #titleToolbar>
<slot name="titleToolbar"></slot>
@ -11,30 +11,32 @@
<slot name="title"></slot>
</template>
<ScrollContainer :style="getScrollContentStyle" v-loading="getLoading" :loading-tip="loadingText || t('common.loadingText')">
<ScrollContainer v-loading="getLoading" :style="getScrollContentStyle" :loading-tip="loadingText || t('common.loadingText')">
<slot></slot>
</ScrollContainer>
<DrawerFooter v-bind="getProps" @close="onClose" @ok="handleOk" :height="getFooterHeight">
<template #[item]="data" v-for="item in Object.keys($slots)">
<DrawerFooter v-bind="getProps" :height="getFooterHeight" @close="onClose" @ok="handleOk">
<template v-for="item in Object.keys($slots)" #[item]="data">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</DrawerFooter>
</Drawer>
</template>
<script lang="ts" setup inheritAttrs="false">
import type { DrawerInstance, DrawerProps } from './typing';
import type { CSSProperties } from 'vue';
import { ref, computed, watch, unref, nextTick, toRaw, getCurrentInstance } from 'vue';
import { Drawer } from 'ant-design-vue';
import type { CSSProperties } from 'vue';
import { computed, getCurrentInstance, nextTick, ref, toRaw, unref, watch } from 'vue';
import { ScrollContainer } from '@/components/Container';
import { useAttrs } from '@/hooks/core/useAttrs';
import { useDesign } from '@/hooks/web/useDesign';
import { useI18n } from '@/hooks/web/useI18n';
import { isFunction, isNumber } from '@/utils/is';
import { deepMerge } from '@/utils';
import { isFunction, isNumber } from '@/utils/is';
import DrawerFooter from './components/DrawerFooter.vue';
import DrawerHeader from './components/DrawerHeader.vue';
import { ScrollContainer } from '@/components/Container';
import { basicProps } from './props';
import { useDesign } from '@/hooks/web/useDesign';
import { useAttrs } from '@/hooks/core/useAttrs';
import type { DrawerInstance, DrawerProps } from './typing';
const props = defineProps(basicProps);
const emit = defineEmits(['visible-change', 'ok', 'close', 'register']);
@ -47,7 +49,7 @@ const { t } = useI18n();
const { prefixVar, prefixCls } = useDesign('basic-drawer');
const drawerInstance: DrawerInstance = {
setDrawerProps: setDrawerProps,
setDrawerProps,
emitVisible: undefined,
};

View File

@ -1,12 +1,12 @@
<template>
<div :class="prefixCls" :style="getStyle" v-if="showFooter || $slots.footer">
<div v-if="showFooter || $slots.footer" :class="prefixCls" :style="getStyle">
<template v-if="!$slots.footer">
<slot name="insertFooter"></slot>
<a-button v-bind="cancelButtonProps" @click="handleClose" class="mr-2" v-if="showCancelBtn">
<a-button v-if="showCancelBtn" v-bind="cancelButtonProps" class="mr-2" @click="handleClose">
{{ cancelText }}
</a-button>
<slot name="centerFooter"></slot>
<a-button :type="okType" @click="handleOk" v-bind="okButtonProps" class="mr-2" :loading="confirmLoading" v-if="showOkBtn">
<a-button v-if="showOkBtn" :type="okType" v-bind="okButtonProps" class="mr-2" :loading="confirmLoading" @click="handleOk">
{{ okText }}
</a-button>
<slot name="appendFooter"></slot>
@ -20,7 +20,9 @@
<script lang="ts" setup name="BasicDrawerFooter">
import type { CSSProperties } from 'vue';
import { computed } from 'vue';
import { useDesign } from '@/hooks/web/useDesign';
import { footerProps } from '../props';
const props = defineProps({

View File

@ -4,9 +4,9 @@
{{ !$slots.title ? title : '' }}
</BasicTitle>
<div :class="[prefixCls, `${prefixCls}--detail`]" v-else>
<div v-else :class="[prefixCls, `${prefixCls}--detail`]">
<span :class="`${prefixCls}__twrap`">
<span @click="handleClose" v-if="showDetailBack">
<span v-if="showDetailBack" @click="handleClose">
<ArrowLeftOutlined :class="`${prefixCls}__back`" />
</span>
<span v-if="title">{{ title }}</span>
@ -18,8 +18,9 @@
</div>
</template>
<script lang="ts" setup name="BasicDrawerHeader">
import { BasicTitle } from '@/components/Basic';
import { ArrowLeftOutlined } from '@ant-design/icons-vue';
import { BasicTitle } from '@/components/Basic';
import { useDesign } from '@/hooks/web/useDesign';
import { propTypes } from '@/utils/propTypes';

View File

@ -1,4 +1,5 @@
import { useI18n } from '@/hooks/web/useI18n';
const { t } = useI18n();
export const footerProps = {

View File

@ -1,5 +1,6 @@
import type { ButtonProps } from 'ant-design-vue/lib/button/buttonTypes';
import type { CSSProperties, VNodeChild, ComputedRef } from 'vue';
import type { ComputedRef, CSSProperties, VNodeChild } from 'vue';
import type { ScrollContainerOptions } from '@/components/Container';
export interface DrawerInstance {

View File

@ -1,11 +1,13 @@
import type { UseDrawerReturnType, DrawerInstance, ReturnMethods, DrawerProps, UseDrawerInnerReturnType } from './typing';
import { ref, getCurrentInstance, unref, reactive, watchEffect, nextTick, toRaw, computed } from 'vue';
import { isProdMode } from '@/utils/env';
import { isFunction } from '@/utils/is';
import { tryOnUnmounted } from '@vueuse/core';
import { isEqual } from 'lodash-es';
import { computed, getCurrentInstance, nextTick, reactive, ref, toRaw, unref, watchEffect } from 'vue';
import { isProdMode } from '@/utils/env';
import { isFunction } from '@/utils/is';
import { error } from '@/utils/log';
import type { DrawerInstance, DrawerProps, ReturnMethods, UseDrawerInnerReturnType, UseDrawerReturnType } from './typing';
const dataTransferRef = reactive<any>({});
const visibleData = reactive<{ [key: number]: boolean }>({});
@ -60,7 +62,7 @@ export function useDrawer(): UseDrawerReturnType {
openDrawer: <T = any>(visible = true, data?: T, openOnSet = true): void => {
getInstance()?.setDrawerProps({
visible: visible,
visible,
});
if (!data) return;

View File

@ -1,4 +1,5 @@
import { withInstall } from '@/utils';
import dropdown from './src/Dropdown.vue';
export * from './src/typing';

View File

@ -6,18 +6,18 @@
<template #overlay>
<a-menu :selectedKeys="selectedKeys">
<template v-for="item in dropMenuList" :key="`${item.event}`">
<a-menu-item v-bind="getAttr(item.event)" @click="handleClickMenu(item)" :disabled="item.disabled">
<a-menu-item v-bind="getAttr(item.event)" :disabled="item.disabled" @click="handleClickMenu(item)">
<a-popconfirm v-if="popconfirm && item.popConfirm" v-bind="getPopConfirmAttrs(item.popConfirm)">
<template #icon v-if="item.popConfirm.icon">
<template v-if="item.popConfirm.icon" #icon>
<Icon :icon="item.popConfirm.icon" />
</template>
<div>
<Icon :icon="item.icon" v-if="item.icon" />
<Icon v-if="item.icon" :icon="item.icon" />
<span class="ml-1">{{ item.text }}</span>
</div>
</a-popconfirm>
<template v-else>
<Icon :icon="item.icon" v-if="item.icon" />
<Icon v-if="item.icon" :icon="item.icon" />
<span class="ml-1">{{ item.text }}</span>
</template>
</a-menu-item>
@ -29,13 +29,15 @@
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import type { DropMenu } from './typing';
import { Dropdown, Menu, Popconfirm } from 'ant-design-vue';
import { Icon } from '@/components/Icon';
import { omit } from 'lodash-es';
import { computed } from 'vue';
import { Icon } from '@/components/Icon';
import { isFunction } from '@/utils/is';
import type { DropMenu } from './typing';
const ADropdown = Dropdown;
const AMenu = Menu;
const AMenuItem = Menu.Item;

View File

@ -1,8 +1,9 @@
import { withInstall } from '@/utils';
import impExcel from './src/ImportExcel.vue';
import expExcelModal from './src/ExportExcelModal.vue';
import impExcel from './src/ImportExcel.vue';
export const ImpExcel = withInstall(impExcel);
export const ExpExcelModal = withInstall(expExcelModal);
export { aoaToSheetXlsx, jsonToSheetXlsx } from './src/Export2Excel';
export * from './src/typing';
export { jsonToSheetXlsx, aoaToSheetXlsx } from './src/Export2Excel';

View File

@ -1,6 +1,7 @@
import * as xlsx from 'xlsx';
import type { WorkBook } from 'xlsx';
import type { JsonToSheet, AoAToSheet } from './typing';
import * as xlsx from 'xlsx';
import type { AoAToSheet, JsonToSheet } from './typing';
const { utils, writeFile } = xlsx;

View File

@ -4,11 +4,12 @@
</BasicModal>
</template>
<script lang="ts" setup>
import type { ExportModalResult } from './typing';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, FormSchema, useForm } from '@/components/Form';
import { BasicModal, useModalInner } from '@/components/Modal';
import { useI18n } from '@/hooks/web/useI18n';
import type { ExportModalResult } from './typing';
const { t } = useI18n();
const emit = defineEmits(['success', 'register']);
const schemas: FormSchema[] = [

View File

@ -1,6 +1,6 @@
<template>
<div>
<input ref="inputRef" type="file" v-show="false" accept=".xlsx, .xls" @change="handleInputClick" />
<input v-show="false" ref="inputRef" type="file" accept=".xlsx, .xls" @change="handleInputClick" />
<div @click="handleUpload">
<slot></slot>
</div>
@ -9,7 +9,9 @@
<script lang="ts" setup name="ImportExcel">
import { ref, unref } from 'vue';
import * as XLSX from 'xlsx';
import { dateUtil } from '@/utils/dateUtil';
import type { ExcelData } from './typing';
const props = defineProps({
@ -32,8 +34,8 @@ const props = defineProps({
const emit = defineEmits(['success', 'error', 'cancel']);
const inputRef = ref<HTMLInputElement | null>(null);
const loadingRef = ref<Boolean>(false);
const cancelRef = ref<Boolean>(true);
const loadingRef = ref<boolean>(false);
const cancelRef = ref<boolean>(true);
function shapeWorkSheel(sheet: XLSX.WorkSheet, range: XLSX.Range) {
let str = ' ',
@ -106,7 +108,7 @@ function getExcelData(workbook: XLSX.WorkBook) {
dateNF: dateFormat, //Not worked
}) as object[];
results = results.map((row: object) => {
for (let field in row) {
for (const field in row) {
if (row[field] instanceof Date) {
if (timeZone === 8) {
row[field].setSeconds(row[field].getSeconds() + 43);

View File

@ -1,4 +1,4 @@
import type { JSON2SheetOpts, WritingOptions, BookType } from 'xlsx';
import type { BookType, JSON2SheetOpts, WritingOptions } from 'xlsx';
export interface ExcelData<T = any> {
header: string[];

View File

@ -1,17 +1,15 @@
import BasicForm from './src/BasicForm.vue';
export { default as ApiCascader } from './src/components/ApiCascader.vue';
export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue';
export { default as ApiSelect } from './src/components/ApiSelect.vue';
export { default as ApiTransfer } from './src/components/ApiTransfer.vue';
export { default as ApiTree } from './src/components/ApiTree.vue';
export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue';
export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue';
export { useComponentRegister } from './src/hooks/useComponentRegister';
export { useForm } from './src/hooks/useForm';
export * from './src/types/form';
export * from './src/types/formItem';
export { useComponentRegister } from './src/hooks/useComponentRegister';
export { useForm } from './src/hooks/useForm';
export { default as ApiSelect } from './src/components/ApiSelect.vue';
export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue';
export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue';
export { default as ApiTree } from './src/components/ApiTree.vue';
export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue';
export { default as ApiCascader } from './src/components/ApiCascader.vue';
export { default as ApiTransfer } from './src/components/ApiTransfer.vue';
export { BasicForm };

View File

@ -1,5 +1,5 @@
<template>
<Form v-bind="getBindValue" :class="getFormClass" ref="formElRef" :model="formModel" @keypress.enter="handleEnterPress">
<Form v-bind="getBindValue" ref="formElRef" :class="getFormClass" :model="formModel" @keypress.enter="handleEnterPress">
<Row v-bind="getRow">
<slot name="formHeader"></slot>
<template v-for="schema in getSchema" :key="schema.field">
@ -13,14 +13,14 @@
:formModel="formModel"
:setFormModel="setFormModel"
>
<template #[item]="data" v-for="item in Object.keys($slots)">
<template v-for="item in Object.keys($slots)" #[item]="data">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</FormItem>
</template>
<FormAction v-bind="getFormActionBindProps" @toggle-advanced="handleToggleAdvanced">
<template #[item]="data" v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']">
<template v-for="item in ['resetBefore', 'submitBefore', 'advanceBefore', 'advanceAfter']" #[item]="data">
<slot :name="item" v-bind="data || {}"></slot>
</template>
</FormAction>
@ -29,32 +29,28 @@
</Form>
</template>
<script lang="ts" setup name="BasicForm">
import type { FormActionType, FormProps, FormSchema } from './types/form';
import type { AdvanceState } from './types/hooks';
import { Ref, useAttrs } from 'vue';
import { reactive, ref, computed, unref, onMounted, watch, nextTick } from 'vue';
import { useDebounceFn } from '@vueuse/core';
import { Form, Row } from 'ant-design-vue';
import FormItem from './components/FormItem.vue';
import FormAction from './components/FormAction.vue';
import { dateItemType } from './helper';
import { dateUtil } from '@/utils/dateUtil';
import { cloneDeep } from 'lodash-es';
import { computed, nextTick, onMounted, reactive, Ref, ref, unref, useAttrs, watch } from 'vue';
import { useModalContext } from '@/components/Modal';
import { useDesign } from '@/hooks/web/useDesign';
// import { cloneDeep } from 'lodash-es';
import { deepMerge } from '@/utils';
import { dateUtil } from '@/utils/dateUtil';
import { useFormValues } from './hooks/useFormValues';
import FormAction from './components/FormAction.vue';
import FormItem from './components/FormItem.vue';
import { dateItemType } from './helper';
import useAdvanced from './hooks/useAdvanced';
import { useFormEvents } from './hooks/useFormEvents';
import { createFormContext } from './hooks/useFormContext';
import { useAutoFocus } from './hooks/useAutoFocus';
import { useModalContext } from '@/components/Modal';
import { useDebounceFn } from '@vueuse/core';
import { createFormContext } from './hooks/useFormContext';
import { useFormEvents } from './hooks/useFormEvents';
import { useFormValues } from './hooks/useFormValues';
import { basicProps } from './props';
import { useDesign } from '@/hooks/web/useDesign';
import { cloneDeep } from 'lodash-es';
import type { FormActionType, FormProps, FormSchema } from './types/form';
import type { AdvanceState } from './types/hooks';
const props = defineProps(basicProps);
const emit = defineEmits(['advanced-change', 'reset', 'submit', 'register', 'field-value-change']);
@ -261,7 +257,7 @@ const formActionType: Partial<FormActionType> = {
validateFields,
validate,
submit: handleSubmit,
scrollToField: scrollToField,
scrollToField,
};
onMounted(() => {

View File

@ -1,38 +1,38 @@
import type { Component } from 'vue';
import type { ComponentType } from './types';
/**
* Component list, register here to setting it in the form
*/
import {
Input,
Select,
Radio,
Checkbox,
AutoComplete,
Cascader,
Checkbox,
DatePicker,
Divider,
Input,
InputNumber,
Radio,
Rate,
Select,
Slider,
Switch,
TimePicker,
TreeSelect,
Slider,
Rate,
Divider,
} from 'ant-design-vue';
import type { Component } from 'vue';
import { CountdownInput } from '@/components/CountDown';
import { IconPicker } from '@/components/Icon';
import { StrengthMeter } from '@/components/StrengthMeter';
import { Tinymce } from '@/components/Tinymce';
import { BasicUpload } from '@/components/Upload';
import ApiCascader from './components/ApiCascader.vue';
import ApiRadioGroup from './components/ApiRadioGroup.vue';
import RadioButtonGroup from './components/RadioButtonGroup.vue';
import ApiSelect from './components/ApiSelect.vue';
import ApiTransfer from './components/ApiTransfer.vue';
import ApiTree from './components/ApiTree.vue';
import ApiTreeSelect from './components/ApiTreeSelect.vue';
import ApiCascader from './components/ApiCascader.vue';
import ApiTransfer from './components/ApiTransfer.vue';
import { BasicUpload } from '@/components/Upload';
import { StrengthMeter } from '@/components/StrengthMeter';
import { IconPicker } from '@/components/Icon';
import { CountdownInput } from '@/components/CountDown';
import { Tinymce } from '@/components/Tinymce';
import RadioButtonGroup from './components/RadioButtonGroup.vue';
import type { ComponentType } from './types';
const componentMap = new Map<ComponentType, Component>();

View File

@ -4,13 +4,13 @@
:options="options"
:load-data="loadData"
change-on-select
@change="handleChange"
:displayRender="handleRenderDisplay"
@change="handleChange"
>
<template #suffixIcon v-if="loading">
<template v-if="loading" #suffixIcon>
<LoadingOutlined spin />
</template>
<template #notFoundContent v-if="loading">
<template v-if="loading" #notFoundContent>
<span>
<LoadingOutlined spin class="mr-1" />
{{ t('component.form.apiSelectNotFound') }}
@ -19,14 +19,15 @@
</Cascader>
</template>
<script lang="ts" setup name="ApiCascader">
import { ref, unref, watch, watchEffect } from 'vue';
import { Cascader } from 'ant-design-vue';
import { propTypes } from '@/utils/propTypes';
import { isFunction } from '@/utils/is';
import { get, omit } from 'lodash-es';
import { useRuleFormItem } from '@/hooks/component/useFormItem';
import { LoadingOutlined } from '@ant-design/icons-vue';
import { Cascader } from 'ant-design-vue';
import { get, omit } from 'lodash-es';
import { ref, unref, watch, watchEffect } from 'vue';
import { useRuleFormItem } from '@/hooks/component/useFormItem';
import { useI18n } from '@/hooks/web/useI18n';
import { isFunction } from '@/utils/is';
import { propTypes } from '@/utils/propTypes';
interface Option {
value: string;

View File

@ -14,17 +14,23 @@
</RadioGroup>
</template>
<script lang="ts" setup name="ApiRadioGroup">
import { ref, watchEffect, computed, unref, watch } from 'vue';
import { Radio } from 'ant-design-vue';
import { isFunction } from '@/utils/is';
import { get, omit } from 'lodash-es';
import { computed, ref, unref, watch, watchEffect } from 'vue';
import { useRuleFormItem } from '@/hooks/component/useFormItem';
import { useAttrs } from '@/hooks/core/useAttrs';
import { isFunction } from '@/utils/is';
import { propTypes } from '@/utils/propTypes';
import { get, omit } from 'lodash-es';
const RadioButton = Radio.Button;
const RadioGroup = Radio.Group;
type OptionsItem = { label: string; value: string | number | boolean; disabled?: boolean };
interface OptionsItem {
label: string;
value: string | number | boolean;
disabled?: boolean;
}
const props = defineProps({
api: {

View File

@ -1,12 +1,12 @@
<template>
<Select @dropdown-visible-change="handleFetch" v-bind="attrs" @change="handleChange" :options="getOptions" v-model:value="state">
<template #[item]="data" v-for="item in Object.keys($slots)">
<Select v-bind="attrs" v-model:value="state" :options="getOptions" @dropdown-visible-change="handleFetch" @change="handleChange">
<template v-for="item in Object.keys($slots)" #[item]="data">
<slot :name="item" v-bind="data || {}"></slot>
</template>
<template #suffixIcon v-if="loading">
<template v-if="loading" #suffixIcon>
<LoadingOutlined spin />
</template>
<template #notFoundContent v-if="loading">
<template v-if="loading" #notFoundContent>
<span>
<LoadingOutlined spin class="mr-1" />
{{ t('component.form.apiSelectNotFound') }}
@ -15,18 +15,23 @@
</Select>
</template>
<script lang="ts" setup name="ApiSelect" inheritAttrs="false">
import { ref, watchEffect, computed, unref, watch } from 'vue';
import { LoadingOutlined } from '@ant-design/icons-vue';
import { Select } from 'ant-design-vue';
import { isFunction } from '@/utils/is';
import { SelectValue } from 'ant-design-vue/lib/select';
import { get, omit } from 'lodash-es';
import { computed, ref, unref, watch, watchEffect } from 'vue';
import { useRuleFormItem } from '@/hooks/component/useFormItem';
import { useAttrs } from '@/hooks/core/useAttrs';
import { get, omit } from 'lodash-es';
import { LoadingOutlined } from '@ant-design/icons-vue';
import { useI18n } from '@/hooks/web/useI18n';
import { isFunction } from '@/utils/is';
import { propTypes } from '@/utils/propTypes';
import { SelectValue } from 'ant-design-vue/lib/select';
type OptionsItem = { label: string; value: string; disabled?: boolean };
interface OptionsItem {
label: string;
value: string;
disabled?: boolean;
}
const props = defineProps({
value: {

View File

@ -12,12 +12,13 @@
/>
</template>
<script lang="ts" setup name="ApiTransfer">
import { computed, watch, ref, unref, useAttrs, watchEffect } from 'vue';
import { Transfer } from 'ant-design-vue';
import { isFunction } from '@/utils/is';
import { get, omit } from 'lodash-es';
import { propTypes } from '@/utils/propTypes';
import { TransferDirection, TransferItem } from 'ant-design-vue/lib/transfer';
import { get, omit } from 'lodash-es';
import { computed, ref, unref, useAttrs, watch, watchEffect } from 'vue';
import { isFunction } from '@/utils/is';
import { propTypes } from '@/utils/propTypes';
const props = defineProps({
value: { type: Array as PropType<Array<string>> },

View File

@ -1,20 +1,21 @@
<template>
<Tree v-bind="getAttrs" @change="handleChange">
<template #[item]="data" v-for="item in Object.keys(slots)">
<template v-for="item in Object.keys(slots)" #[item]="data">
<slot :name="item" v-bind="data || {}"></slot>
</template>
<template #suffixIcon v-if="loading">
<template v-if="loading" #suffixIcon>
<LoadingOutlined spin />
</template>
</Tree>
</template>
<script lang="ts" setup name="ApiTree">
import { computed, watch, ref, onMounted, unref, useSlots, useAttrs } from 'vue';
import { Tree } from 'ant-design-vue';
import { isArray, isFunction } from '@/utils/is';
import { get } from 'lodash-es';
import { propTypes } from '@/utils/propTypes';
import { LoadingOutlined } from '@ant-design/icons-vue';
import { Tree } from 'ant-design-vue';
import { get } from 'lodash-es';
import { computed, onMounted, ref, unref, useAttrs, useSlots, watch } from 'vue';
import { isArray, isFunction } from '@/utils/is';
import { propTypes } from '@/utils/propTypes';
import { handleTree } from '@/utils/tree';
const props = defineProps({
@ -30,7 +31,7 @@ const attrs = useAttrs();
const slots = useSlots();
const treeData = ref<Recordable[]>([]);
const isFirstLoaded = ref<Boolean>(false);
const isFirstLoaded = ref<boolean>(false);
const loading = ref(false);
const getAttrs = computed(() => {
return {

View File

@ -1,20 +1,21 @@
<template>
<TreeSelect v-bind="getAttrs" @change="handleChange">
<template #[item]="data" v-for="item in Object.keys($slots)">
<template v-for="item in Object.keys($slots)" #[item]="data">
<slot :name="item" v-bind="data || {}"></slot>
</template>
<template #suffixIcon v-if="loading">
<template v-if="loading" #suffixIcon>
<LoadingOutlined spin />
</template>
</TreeSelect>
</template>
<script lang="ts" setup name="ApiTreeSelect">
import { computed, watch, ref, onMounted, unref, useAttrs } from 'vue';
import { TreeSelect } from 'ant-design-vue';
import { isArray, isFunction } from '@/utils/is';
import { get } from 'lodash-es';
import { propTypes } from '@/utils/propTypes';
import { LoadingOutlined } from '@ant-design/icons-vue';
import { TreeSelect } from 'ant-design-vue';
import { get } from 'lodash-es';
import { computed, onMounted, ref, unref, useAttrs, watch } from 'vue';
import { isArray, isFunction } from '@/utils/is';
import { propTypes } from '@/utils/propTypes';
import { handleTree } from '@/utils/tree';
const props = defineProps({
@ -29,7 +30,7 @@ const emit = defineEmits(['options-change', 'change']);
const attrs = useAttrs();
const treeData = ref<Recordable[]>([]);
const isFirstLoaded = ref<Boolean>(false);
const isFirstLoaded = ref<boolean>(false);
const loading = ref(false);
const getAttrs = computed(() => {
return {

Some files were not shown because too many files have changed in this diff Show More