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> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'; import 'dayjs/locale/zh-cn';
import { ConfigProvider } from 'ant-design-vue'; import { ConfigProvider } from 'ant-design-vue';
import { computed } from 'vue';
import { AppProvider } from '@/components/Application'; import { AppProvider } from '@/components/Application';
import { useTitle } from '@/hooks/web/useTitle'; import { useTitle } from '@/hooks/web/useTitle';
import { useLocale } from '@/locales/useLocale'; import { useLocale } from '@/locales/useLocale';
import { useAppStore } from '@/store/modules/app'; import { useAppStore } from '@/store/modules/app';
import 'dayjs/locale/zh-cn';
// support Multi-language // support Multi-language
const { getAntdLocale } = useLocale(); 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 { getRefreshToken } from '@/utils/auth';
import { defHttp } from '@/utils/http/axios';
import { TentantNameVO } from './model/loginModel';
enum Api { enum Api {
Login = '/system/auth/login', Login = '/system/auth/login',

View File

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

View File

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

View File

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

View File

@ -79,8 +79,8 @@ export function updateUserPwdApi(oldPassword: string, newPassword: string) {
return defHttp.put({ return defHttp.put({
url: Api.updateUserPwdApi, url: Api.updateUserPwdApi,
data: { data: {
oldPassword: oldPassword, oldPassword,
newPassword: newPassword, newPassword,
}, },
}); });
} }
@ -91,7 +91,6 @@ export function uploadAvatarApi(data) {
url: Api.uploadAvatarApi, url: Api.uploadAvatarApi,
headers: { headers: {
'Content-type': ContentTypeEnum.FORM_DATA, 'Content-type': ContentTypeEnum.FORM_DATA,
// @ts-ignore
ignoreCancelToken: true, ignoreCancelToken: true,
}, },
data, 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 { 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(); const { uploadUrl = '' } = useGlobSetting();
/** /**

View File

@ -1,7 +1,7 @@
import { defHttp } from '@/utils/http/axios'; 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 { enum Api {
Login = '/system/auth/login', Login = '/system/auth/login',

View File

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

View File

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

View File

@ -1,13 +1,13 @@
import { defHttp } from '@/utils/http/axios'; import { defHttp } from '@/utils/http/axios';
export type ProcessDefinitionVO = { export interface ProcessDefinitionVO {
id: string; id: string;
version: number; version: number;
deploymentTIme: string; deploymentTIme: string;
suspensionState: number; suspensionState: number;
}; }
export type ModelVO = { export interface ModelVO {
id: number; id: number;
formName: string; formName: string;
key: string; key: string;
@ -22,7 +22,7 @@ export type ModelVO = {
status: number; status: number;
remark: string; remark: string;
createTime: string; createTime: string;
}; }
export function getModelPage(params) { export function getModelPage(params) {
return defHttp.get({ url: '/bpm/model/page', 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) { export function updateModelState(id: number, state: number) {
const data = { const data = {
id: id, id,
state: state, state,
}; };
return defHttp.put({ url: '/bpm/model/update-state', data }); return defHttp.put({ url: '/bpm/model/update-state', data });
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,12 +7,13 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, unref } from 'vue'; import { computed, unref } from 'vue';
import { SvgIcon } from '@/components/Icon'; 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 { 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 { prefixCls } = useDesign('dark-switch');
const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting(); const { getDarkMode, setDarkMode, getShowDarkModeToggle } = useRootSetting();

View File

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

View File

@ -1,18 +1,19 @@
<template> <template>
<div class="anticon" :class="getAppLogoClass" @click="goHome"> <div class="anticon" :class="getAppLogoClass" @click="goHome">
<img src="@/assets/images/logo.png" /> <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 }} {{ title }}
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, unref } from 'vue'; import { computed, unref } from 'vue';
import { PageEnum } from '@/enums/pageEnum';
import { useGlobSetting } from '@/hooks/setting'; import { useGlobSetting } from '@/hooks/setting';
import { useGo } from '@/hooks/web/usePage';
import { useMenuSetting } from '@/hooks/setting/useMenuSetting'; import { useMenuSetting } from '@/hooks/setting/useMenuSetting';
import { useDesign } from '@/hooks/web/useDesign'; import { useDesign } from '@/hooks/web/useDesign';
import { PageEnum } from '@/enums/pageEnum'; import { useGo } from '@/hooks/web/usePage';
const props = defineProps({ const props = defineProps({
// //

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,8 +6,8 @@
<div class="p-2 bg-white"> <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"> <List :grid="{ gutter: 5, xs: 1, sm: 2, md: 4, lg: 4, xl: 6, xxl: grid }" :data-source="data" :pagination="paginationProp">
<template #header> <template #header>
<div class="flex justify-end space-x-2" <div class="flex justify-end space-x-2">
><slot name="header"></slot> <slot name="header"></slot>
<Tooltip> <Tooltip>
<template #title> <template #title>
<div class="w-50">每行显示数量</div> <div class="w-50">每行显示数量</div>
@ -68,15 +68,18 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onMounted, ref } from 'vue';
import { EditOutlined, EllipsisOutlined, RedoOutlined, TableOutlined } from '@ant-design/icons-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 { Dropdown } from '@/components/Dropdown';
import { BasicForm, useForm } from '@/components/Form'; import { BasicForm, useForm } from '@/components/Form';
import { propTypes } from '@/utils/propTypes';
import { Button } from '@/components/Button';
import { isFunction } from '@/utils/is'; 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 ListItem = List.Item;
const CardMeta = Card.Meta; const CardMeta = Card.Meta;
const TypographyText = Typography.Text; const TypographyText = Typography.Text;

View File

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

View File

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

View File

@ -1,14 +1,8 @@
<template> <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> </template>
<script lang="ts" setup> <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 // css
import './codemirror.css'; import './codemirror.css';
import 'codemirror/theme/idea.css'; import 'codemirror/theme/idea.css';
@ -18,6 +12,15 @@ import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/css/css'; import 'codemirror/mode/css/css';
import 'codemirror/mode/htmlmixed/htmlmixed'; 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({ const props = defineProps({
mode: { mode: {
type: String as PropType<MODE>, type: String as PropType<MODE>,

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,8 @@
</template> </template>
<script lang="ts" setup name="ScrollContainer"> <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 { Scrollbar, ScrollbarType } from '@/components/Scrollbar';
import { useScrollTo } from '@/hooks/event/useScrollTo'; import { useScrollTo } from '@/hooks/event/useScrollTo';

View File

@ -1,12 +1,14 @@
<script lang="tsx"> <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 { 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 { useDesign } from '@/hooks/web/useDesign';
import { triggerWindowResize } from '@/utils/event';
import CollapseHeader from './CollapseHeader.vue';
const collapseContainerProps = { const collapseContainerProps = {
title: { type: String, default: '' }, title: { type: String, default: '' },

View File

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

View File

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

View File

@ -1,9 +1,11 @@
<script lang="tsx"> <script lang="tsx">
import type { ContextMenuItem, ItemContentProps, Axis } from './typing'; import { Divider, Menu } from 'ant-design-vue';
import type { FunctionalComponent, CSSProperties } from 'vue'; import type { CSSProperties, FunctionalComponent } from 'vue';
import { defineComponent, nextTick, onMounted, computed, ref, unref, onUnmounted } from 'vue'; import { computed, defineComponent, nextTick, onMounted, onUnmounted, ref, unref } from 'vue';
import { Icon } from '@/components/Icon'; import { Icon } from '@/components/Icon';
import { Menu, Divider } from 'ant-design-vue';
import type { Axis, ContextMenuItem, ItemContentProps } from './typing';
const prefixCls = 'context-menu'; 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 { createVNode, render } from 'vue';
import { isClient } from '@/utils/is';
import contextMenuVue from './ContextMenu.vue';
import { ContextMenuProps, CreateContextOptions } from './typing';
const menuManager: { const menuManager: {
domList: Element[]; domList: Element[];
resolve: Fn; resolve: Fn;

View File

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

View File

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

View File

@ -3,15 +3,17 @@
<template #addonAfter> <template #addonAfter>
<CountButton :size="size" :count="count" :value="state" :beforeStartFunc="sendCodeApi" /> <CountButton :size="size" :count="count" :value="state" :beforeStartFunc="sendCodeApi" />
</template> </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> <slot :name="item" v-bind="data || {}"></slot>
</template> </template>
</a-input> </a-input>
</template> </template>
<script lang="ts" setup name="CountDownInput" inheritAttrs="false"> <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 { useRuleFormItem } from '@/hooks/component/useFormItem';
import { useDesign } from '@/hooks/web/useDesign';
import CountButton from './CountButton.vue';
const props = defineProps({ const props = defineProps({
value: { type: String }, value: { type: String },
size: { type: String, validator: (v: string) => ['default', 'large', 'small'].includes(v) }, 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 { tryOnUnmounted } from '@vueuse/core';
import { ref, unref } from 'vue';
export function useCountdown(count: number) { export function useCountdown(count: number) {
const currentCount = ref(count); const currentCount = ref(count);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,16 +1,18 @@
<script lang="tsx"> <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 { 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 { 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 { 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 = { const props = {
useCollapse: { type: Boolean, default: true }, 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 { DescriptionsProps } from 'ant-design-vue/es/descriptions';
import type { CSSProperties, VNode } from 'vue';
import type { CollapseContainerOptions } from '@/components/Container';
export interface DescItem { export interface DescItem {
labelMinWidth?: number; labelMinWidth?: number;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,12 @@
<template> <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"> <template v-if="!$slots.footer">
<slot name="insertFooter"></slot> <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 }} {{ cancelText }}
</a-button> </a-button>
<slot name="centerFooter"></slot> <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 }} {{ okText }}
</a-button> </a-button>
<slot name="appendFooter"></slot> <slot name="appendFooter"></slot>
@ -20,7 +20,9 @@
<script lang="ts" setup name="BasicDrawerFooter"> <script lang="ts" setup name="BasicDrawerFooter">
import type { CSSProperties } from 'vue'; import type { CSSProperties } from 'vue';
import { computed } from 'vue'; import { computed } from 'vue';
import { useDesign } from '@/hooks/web/useDesign'; import { useDesign } from '@/hooks/web/useDesign';
import { footerProps } from '../props'; import { footerProps } from '../props';
const props = defineProps({ const props = defineProps({

View File

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

View File

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

View File

@ -1,5 +1,6 @@
import type { ButtonProps } from 'ant-design-vue/lib/button/buttonTypes'; 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'; import type { ScrollContainerOptions } from '@/components/Container';
export interface DrawerInstance { 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 { tryOnUnmounted } from '@vueuse/core';
import { isEqual } from 'lodash-es'; 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 { error } from '@/utils/log';
import type { DrawerInstance, DrawerProps, ReturnMethods, UseDrawerInnerReturnType, UseDrawerReturnType } from './typing';
const dataTransferRef = reactive<any>({}); const dataTransferRef = reactive<any>({});
const visibleData = reactive<{ [key: number]: boolean }>({}); const visibleData = reactive<{ [key: number]: boolean }>({});
@ -60,7 +62,7 @@ export function useDrawer(): UseDrawerReturnType {
openDrawer: <T = any>(visible = true, data?: T, openOnSet = true): void => { openDrawer: <T = any>(visible = true, data?: T, openOnSet = true): void => {
getInstance()?.setDrawerProps({ getInstance()?.setDrawerProps({
visible: visible, visible,
}); });
if (!data) return; if (!data) return;

View File

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

View File

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

View File

@ -1,8 +1,9 @@
import { withInstall } from '@/utils'; import { withInstall } from '@/utils';
import impExcel from './src/ImportExcel.vue';
import expExcelModal from './src/ExportExcelModal.vue'; import expExcelModal from './src/ExportExcelModal.vue';
import impExcel from './src/ImportExcel.vue';
export const ImpExcel = withInstall(impExcel); export const ImpExcel = withInstall(impExcel);
export const ExpExcelModal = withInstall(expExcelModal); export const ExpExcelModal = withInstall(expExcelModal);
export { aoaToSheetXlsx, jsonToSheetXlsx } from './src/Export2Excel';
export * from './src/typing'; 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 { WorkBook } from 'xlsx';
import type { JsonToSheet, AoAToSheet } from './typing'; import * as xlsx from 'xlsx';
import type { AoAToSheet, JsonToSheet } from './typing';
const { utils, writeFile } = xlsx; const { utils, writeFile } = xlsx;

View File

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

View File

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

View File

@ -1,17 +1,15 @@
import BasicForm from './src/BasicForm.vue'; 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/form';
export * from './src/types/formItem'; 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 }; export { BasicForm };

View File

@ -1,5 +1,5 @@
<template> <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"> <Row v-bind="getRow">
<slot name="formHeader"></slot> <slot name="formHeader"></slot>
<template v-for="schema in getSchema" :key="schema.field"> <template v-for="schema in getSchema" :key="schema.field">
@ -13,14 +13,14 @@
:formModel="formModel" :formModel="formModel"
:setFormModel="setFormModel" :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> <slot :name="item" v-bind="data || {}"></slot>
</template> </template>
</FormItem> </FormItem>
</template> </template>
<FormAction v-bind="getFormActionBindProps" @toggle-advanced="handleToggleAdvanced"> <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> <slot :name="item" v-bind="data || {}"></slot>
</template> </template>
</FormAction> </FormAction>
@ -29,32 +29,28 @@
</Form> </Form>
</template> </template>
<script lang="ts" setup name="BasicForm"> <script lang="ts" setup name="BasicForm">
import type { FormActionType, FormProps, FormSchema } from './types/form'; import { useDebounceFn } from '@vueuse/core';
import type { AdvanceState } from './types/hooks';
import { Ref, useAttrs } from 'vue';
import { reactive, ref, computed, unref, onMounted, watch, nextTick } from 'vue';
import { Form, Row } from 'ant-design-vue'; import { Form, Row } from 'ant-design-vue';
import FormItem from './components/FormItem.vue'; import { cloneDeep } from 'lodash-es';
import FormAction from './components/FormAction.vue'; import { computed, nextTick, onMounted, reactive, Ref, ref, unref, useAttrs, watch } from 'vue';
import { dateItemType } from './helper';
import { dateUtil } from '@/utils/dateUtil';
import { useModalContext } from '@/components/Modal';
import { useDesign } from '@/hooks/web/useDesign';
// import { cloneDeep } from 'lodash-es'; // import { cloneDeep } from 'lodash-es';
import { deepMerge } from '@/utils'; 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 useAdvanced from './hooks/useAdvanced';
import { useFormEvents } from './hooks/useFormEvents';
import { createFormContext } from './hooks/useFormContext';
import { useAutoFocus } from './hooks/useAutoFocus'; import { useAutoFocus } from './hooks/useAutoFocus';
import { useModalContext } from '@/components/Modal'; import { createFormContext } from './hooks/useFormContext';
import { useDebounceFn } from '@vueuse/core'; import { useFormEvents } from './hooks/useFormEvents';
import { useFormValues } from './hooks/useFormValues';
import { basicProps } from './props'; import { basicProps } from './props';
import { useDesign } from '@/hooks/web/useDesign'; import type { FormActionType, FormProps, FormSchema } from './types/form';
import { cloneDeep } from 'lodash-es'; import type { AdvanceState } from './types/hooks';
const props = defineProps(basicProps); const props = defineProps(basicProps);
const emit = defineEmits(['advanced-change', 'reset', 'submit', 'register', 'field-value-change']); const emit = defineEmits(['advanced-change', 'reset', 'submit', 'register', 'field-value-change']);
@ -261,7 +257,7 @@ const formActionType: Partial<FormActionType> = {
validateFields, validateFields,
validate, validate,
submit: handleSubmit, submit: handleSubmit,
scrollToField: scrollToField, scrollToField,
}; };
onMounted(() => { 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 * Component list, register here to setting it in the form
*/ */
import { import {
Input,
Select,
Radio,
Checkbox,
AutoComplete, AutoComplete,
Cascader, Cascader,
Checkbox,
DatePicker, DatePicker,
Divider,
Input,
InputNumber, InputNumber,
Radio,
Rate,
Select,
Slider,
Switch, Switch,
TimePicker, TimePicker,
TreeSelect, TreeSelect,
Slider,
Rate,
Divider,
} from 'ant-design-vue'; } 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 ApiRadioGroup from './components/ApiRadioGroup.vue';
import RadioButtonGroup from './components/RadioButtonGroup.vue';
import ApiSelect from './components/ApiSelect.vue'; import ApiSelect from './components/ApiSelect.vue';
import ApiTransfer from './components/ApiTransfer.vue';
import ApiTree from './components/ApiTree.vue'; import ApiTree from './components/ApiTree.vue';
import ApiTreeSelect from './components/ApiTreeSelect.vue'; import ApiTreeSelect from './components/ApiTreeSelect.vue';
import ApiCascader from './components/ApiCascader.vue'; import RadioButtonGroup from './components/RadioButtonGroup.vue';
import ApiTransfer from './components/ApiTransfer.vue'; import type { ComponentType } from './types';
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';
const componentMap = new Map<ComponentType, Component>(); const componentMap = new Map<ComponentType, Component>();

View File

@ -4,13 +4,13 @@
:options="options" :options="options"
:load-data="loadData" :load-data="loadData"
change-on-select change-on-select
@change="handleChange"
:displayRender="handleRenderDisplay" :displayRender="handleRenderDisplay"
@change="handleChange"
> >
<template #suffixIcon v-if="loading"> <template v-if="loading" #suffixIcon>
<LoadingOutlined spin /> <LoadingOutlined spin />
</template> </template>
<template #notFoundContent v-if="loading"> <template v-if="loading" #notFoundContent>
<span> <span>
<LoadingOutlined spin class="mr-1" /> <LoadingOutlined spin class="mr-1" />
{{ t('component.form.apiSelectNotFound') }} {{ t('component.form.apiSelectNotFound') }}
@ -19,14 +19,15 @@
</Cascader> </Cascader>
</template> </template>
<script lang="ts" setup name="ApiCascader"> <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 { 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 { useI18n } from '@/hooks/web/useI18n';
import { isFunction } from '@/utils/is';
import { propTypes } from '@/utils/propTypes';
interface Option { interface Option {
value: string; value: string;

View File

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

View File

@ -1,12 +1,12 @@
<template> <template>
<Select @dropdown-visible-change="handleFetch" v-bind="attrs" @change="handleChange" :options="getOptions" v-model:value="state"> <Select v-bind="attrs" v-model:value="state" :options="getOptions" @dropdown-visible-change="handleFetch" @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> <slot :name="item" v-bind="data || {}"></slot>
</template> </template>
<template #suffixIcon v-if="loading"> <template v-if="loading" #suffixIcon>
<LoadingOutlined spin /> <LoadingOutlined spin />
</template> </template>
<template #notFoundContent v-if="loading"> <template v-if="loading" #notFoundContent>
<span> <span>
<LoadingOutlined spin class="mr-1" /> <LoadingOutlined spin class="mr-1" />
{{ t('component.form.apiSelectNotFound') }} {{ t('component.form.apiSelectNotFound') }}
@ -15,18 +15,23 @@
</Select> </Select>
</template> </template>
<script lang="ts" setup name="ApiSelect" inheritAttrs="false"> <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 { 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 { useRuleFormItem } from '@/hooks/component/useFormItem';
import { useAttrs } from '@/hooks/core/useAttrs'; 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 { useI18n } from '@/hooks/web/useI18n';
import { isFunction } from '@/utils/is';
import { propTypes } from '@/utils/propTypes'; 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({ const props = defineProps({
value: { value: {

View File

@ -12,12 +12,13 @@
/> />
</template> </template>
<script lang="ts" setup name="ApiTransfer"> <script lang="ts" setup name="ApiTransfer">
import { computed, watch, ref, unref, useAttrs, watchEffect } from 'vue';
import { Transfer } from 'ant-design-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 { 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({ const props = defineProps({
value: { type: Array as PropType<Array<string>> }, value: { type: Array as PropType<Array<string>> },

View File

@ -1,20 +1,21 @@
<template> <template>
<Tree v-bind="getAttrs" @change="handleChange"> <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> <slot :name="item" v-bind="data || {}"></slot>
</template> </template>
<template #suffixIcon v-if="loading"> <template v-if="loading" #suffixIcon>
<LoadingOutlined spin /> <LoadingOutlined spin />
</template> </template>
</Tree> </Tree>
</template> </template>
<script lang="ts" setup name="ApiTree"> <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 { 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'; import { handleTree } from '@/utils/tree';
const props = defineProps({ const props = defineProps({
@ -30,7 +31,7 @@ const attrs = useAttrs();
const slots = useSlots(); const slots = useSlots();
const treeData = ref<Recordable[]>([]); const treeData = ref<Recordable[]>([]);
const isFirstLoaded = ref<Boolean>(false); const isFirstLoaded = ref<boolean>(false);
const loading = ref(false); const loading = ref(false);
const getAttrs = computed(() => { const getAttrs = computed(() => {
return { return {

View File

@ -1,20 +1,21 @@
<template> <template>
<TreeSelect v-bind="getAttrs" @change="handleChange"> <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> <slot :name="item" v-bind="data || {}"></slot>
</template> </template>
<template #suffixIcon v-if="loading"> <template v-if="loading" #suffixIcon>
<LoadingOutlined spin /> <LoadingOutlined spin />
</template> </template>
</TreeSelect> </TreeSelect>
</template> </template>
<script lang="ts" setup name="ApiTreeSelect"> <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 { 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'; import { handleTree } from '@/utils/tree';
const props = defineProps({ const props = defineProps({
@ -29,7 +30,7 @@ const emit = defineEmits(['options-change', 'change']);
const attrs = useAttrs(); const attrs = useAttrs();
const treeData = ref<Recordable[]>([]); const treeData = ref<Recordable[]>([]);
const isFirstLoaded = ref<Boolean>(false); const isFirstLoaded = ref<boolean>(false);
const loading = ref(false); const loading = ref(false);
const getAttrs = computed(() => { const getAttrs = computed(() => {
return { return {

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