feat: eslint

pull/28/head
xingyu 2023-07-29 20:20:40 +08:00
parent 4fb4cb9e82
commit 9e03433b85
79 changed files with 339 additions and 382 deletions

View File

@ -8,6 +8,11 @@ module.exports = {
'max-len': ['error', { code: 140, tabWidth: 2, ignoreComments: true }],
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'prefer-promise-reject-errors': 'off',
'no-case-declarations': 'off',
'no-console': 'off',
'n/prefer-global/process': 'off',

26
.vscode/settings.json vendored
View File

@ -76,6 +76,30 @@
"jsonc",
"yaml"
],
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
},
"[typescriptreact]": {
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
@ -92,7 +116,9 @@
"i18n-ally.displayLanguage": "zh-CN",
"i18n-ally.enabledFrameworks": ["vue", "react"],
"cSpell.words": [
"antfu",
"vben",
"unref",
"unocss",
"tailwind",
"browserslist",

View File

@ -53,7 +53,7 @@ async function generateIcon() {
const isLocal = useType === 'local'
const icons = Object.keys(data.icons).map(item => `${isLocal ? `${prefix}:` : ''}${item}`)
await fs.writeFileSync(
fs.writeFileSync(
path.join(output, 'icons.data.ts'),
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`,
)

View File

@ -36,7 +36,7 @@ function createConfig(params: CreateConfigParams) {
console.log(`${colors.cyan(`✨ [${pkg.name}]`)} - configuration file is build successfully:`)
console.log(`${colors.gray(`${OUTPUT_DIR}/${colors.green(configFileName)}`)}\n`)
}
catch (error) {
catch (error: any) {
console.log(colors.red(`configuration file configuration file failed to package:\n${error}`))
}
}

View File

@ -5,7 +5,7 @@ import colors from 'picocolors'
import pkg from '../../package.json'
import { runBuildConfig } from './buildConf'
export async function runBuild() {
export function runBuild() {
try {
const argvList = process.argv.splice(2)
@ -15,7 +15,7 @@ export async function runBuild() {
console.log(`${colors.cyan(`[${pkg.name}]`)}` + ' - build successfully!')
}
catch (error) {
catch (error: any) {
console.log(colors.red(`vite build error:\n${error}`))
process.exit(1)
}

View File

@ -51,7 +51,7 @@ export function wrapperEnv(envConf: Recordable): ViteEnv {
*/
function getConfFiles() {
const script = process.env.npm_lifecycle_script
const reg = new RegExp('--mode ([a-z_\\d]+)')
const reg = /--mode ([a-z_\d]+)/
const result = reg.exec(script as string) as any
if (result) {
const mode = result[1] as string

View File

@ -14,7 +14,7 @@ import { configVisualizerConfig } from './visualizer'
import { configThemePlugin } from './theme'
import { configSvgIconsPlugin } from './svgSprite'
export async function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
const { VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv
const vitePlugins: PluginOption[] = [

View File

@ -134,7 +134,7 @@ devDependencies:
specifier: ^4.17.8
version: 4.17.8
'@types/node':
specifier: ^20.4.5
specifier: ^20.4.0
version: 20.4.5
'@types/nprogress':
specifier: ^0.2.0
@ -229,18 +229,12 @@ devDependencies:
stylelint-config-recommended:
specifier: ^13.0.0
version: 13.0.0(stylelint@15.10.2)
stylelint-config-recommended-scss:
specifier: ^12.0.0
version: 12.0.0(postcss@8.4.27)(stylelint@15.10.2)
stylelint-config-recommended-vue:
specifier: ^1.5.0
version: 1.5.0(postcss-html@1.5.0)(stylelint@15.10.2)
stylelint-config-standard:
specifier: ^34.0.0
version: 34.0.0(stylelint@15.10.2)
stylelint-config-standard-scss:
specifier: ^10.0.0
version: 10.0.0(postcss@8.4.27)(stylelint@15.10.2)
stylelint-order:
specifier: ^6.0.3
version: 6.0.3(stylelint@15.10.2)
@ -7614,10 +7608,6 @@ packages:
postcss: 8.4.27
dev: true
/postcss-media-query-parser@0.2.3:
resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==}
dev: true
/postcss-prefix-selector@1.16.0(postcss@5.2.18):
resolution: {integrity: sha512-rdVMIi7Q4B0XbXqNUEI+Z4E+pueiu/CS5E6vRCQommzdQ/sgsS4dK42U7GX8oJR+TJOtT+Qv3GkNo6iijUMp3Q==}
peerDependencies:
@ -7639,15 +7629,6 @@ packages:
postcss: 8.4.27
dev: true
/postcss-scss@4.0.6(postcss@8.4.27):
resolution: {integrity: sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.4.19
dependencies:
postcss: 8.4.27
dev: true
/postcss-selector-parser@6.0.13:
resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==}
engines: {node: '>=4'}
@ -8641,22 +8622,6 @@ packages:
stylelint-order: 6.0.3(stylelint@15.10.2)
dev: true
/stylelint-config-recommended-scss@12.0.0(postcss@8.4.27)(stylelint@15.10.2):
resolution: {integrity: sha512-5Bb2mlGy6WLa30oNeKpZvavv2lowJUsUJO25+OA68GFTemlwd1zbFsL7q0bReKipOSU3sG47hKneZ6Nd+ctrFA==}
peerDependencies:
postcss: ^8.3.3
stylelint: ^15.5.0
peerDependenciesMeta:
postcss:
optional: true
dependencies:
postcss: 8.4.27
postcss-scss: 4.0.6(postcss@8.4.27)
stylelint: 15.10.2
stylelint-config-recommended: 12.0.0(stylelint@15.10.2)
stylelint-scss: 5.0.1(stylelint@15.10.2)
dev: true
/stylelint-config-recommended-vue@1.5.0(postcss-html@1.5.0)(stylelint@15.10.2):
resolution: {integrity: sha512-65TAK/clUqkNtkZLcuytoxU0URQYlml+30Nhop7sRkCZ/mtWdXt7T+spPSB3KMKlb+82aEVJ4OrcstyDBdbosg==}
engines: {node: ^12 || >=14}
@ -8671,14 +8636,6 @@ packages:
stylelint-config-recommended: 13.0.0(stylelint@15.10.2)
dev: true
/stylelint-config-recommended@12.0.0(stylelint@15.10.2):
resolution: {integrity: sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==}
peerDependencies:
stylelint: ^15.5.0
dependencies:
stylelint: 15.10.2
dev: true
/stylelint-config-recommended@13.0.0(stylelint@15.10.2):
resolution: {integrity: sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==}
engines: {node: ^14.13.1 || >=16.0.0}
@ -8688,30 +8645,6 @@ packages:
stylelint: 15.10.2
dev: true
/stylelint-config-standard-scss@10.0.0(postcss@8.4.27)(stylelint@15.10.2):
resolution: {integrity: sha512-bChBEo1p3xUVWh/wenJI+josoMk21f2yuLDGzGjmKYcALfl2u3DFltY+n4UHswYiXghqXaA8mRh+bFy/q1hQlg==}
peerDependencies:
postcss: ^8.3.3
stylelint: ^15.5.0
peerDependenciesMeta:
postcss:
optional: true
dependencies:
postcss: 8.4.27
stylelint: 15.10.2
stylelint-config-recommended-scss: 12.0.0(postcss@8.4.27)(stylelint@15.10.2)
stylelint-config-standard: 33.0.0(stylelint@15.10.2)
dev: true
/stylelint-config-standard@33.0.0(stylelint@15.10.2):
resolution: {integrity: sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg==}
peerDependencies:
stylelint: ^15.5.0
dependencies:
stylelint: 15.10.2
stylelint-config-recommended: 12.0.0(stylelint@15.10.2)
dev: true
/stylelint-config-standard@34.0.0(stylelint@15.10.2):
resolution: {integrity: sha512-u0VSZnVyW9VSryBG2LSO+OQTjN7zF9XJaAJRX/4EwkmU0R2jYwmBSN10acqZisDitS0CLiEiGjX7+Hrq8TAhfQ==}
engines: {node: ^14.13.1 || >=16.0.0}
@ -8744,18 +8677,6 @@ packages:
stylelint: 15.10.2
dev: true
/stylelint-scss@5.0.1(stylelint@15.10.2):
resolution: {integrity: sha512-n87iCRZrr2J7//I/QFsDXxFLnHKw633U4qvWZ+mOW6KDAp/HLj06H+6+f9zOuTYy+MdGdTuCSDROCpQIhw5fvQ==}
peerDependencies:
stylelint: ^14.5.1 || ^15.0.0
dependencies:
postcss-media-query-parser: 0.2.3
postcss-resolve-nested-selector: 0.1.1
postcss-selector-parser: 6.0.13
postcss-value-parser: 4.2.0
stylelint: 15.10.2
dev: true
/stylelint@15.10.2:
resolution: {integrity: sha512-UxqSb3hB74g4DTO45QhUHkJMjKKU//lNUAOWyvPBVPZbCknJ5HjOWWZo+UDuhHa9FLeVdHBZXxu43eXkjyIPWg==}
engines: {node: ^14.13.1 || >=16.0.0}

View File

@ -14,7 +14,8 @@ enum Api {
// 刷新访问令牌
export function refreshToken() {
return defHttp.post({ url: Api.RefreshToken + getRefreshToken() })
const refreshToken = getRefreshToken()
return defHttp.post({ url: Api.RefreshToken + refreshToken })
}
// 使用租户名,获得租户编号

View File

@ -91,7 +91,6 @@ export function uploadAvatarApi(data) {
url: Api.uploadAvatarApi,
headers: {
'Content-type': ContentTypeEnum.FORM_DATA,
// @ts-expect-error
'ignoreCancelToken': true,
},
data,

View File

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

View File

@ -137,13 +137,13 @@ export function useTabSetup(props, context, options) {
else if (value.includes('W')) {
type.value = TypeEnum.work
const values = value.split('W')
if (!values[0] && !isNaN(values[0]))
if (!values[0] && !Number.isNaN(values[0]))
valueWork.value = Number.parseInt(values[0])
}
else if (value.includes('L')) {
type.value = TypeEnum.last
}
else if (value.includes(',') || !isNaN(value)) {
else if (value.includes(',') || !Number.isNaN(value)) {
type.value = TypeEnum.specify
valueList.value = value.split(',').map(item => Number.parseInt(item))
}

View File

@ -25,7 +25,7 @@ const cronRule: ValidatorRule = {
yearValues = [year]
// 判断是否都是数字
const checkYear = yearValues.some(item => isNaN(Number(item)))
const checkYear = yearValues.some(item => Number.isNaN(Number(item)))
if (checkYear)
return Promise.reject(`Cron表达式参数[年]错误:${year}`)
}
@ -39,7 +39,7 @@ const cronRule: ValidatorRule = {
iter.next()
return Promise.resolve()
}
catch (e) {
catch (e: any) {
return Promise.reject(`Cron表达式错误${e}`)
}
},

View File

@ -52,13 +52,13 @@ export interface DrawerFooterProps {
* The ok button props, follow jsx rules
* @type object
*/
okButtonProps: { props: ButtonProps; on: {} }
okButtonProps: { props: ButtonProps; on: object }
/**
* The cancel button props, follow jsx rules
* @type object
*/
cancelButtonProps: { props: ButtonProps; on: {} }
cancelButtonProps: { props: ButtonProps; on: object }
/**
* Whether to apply loading visual effect for OK button or not
* @default false

View File

@ -51,7 +51,6 @@ const { prefixCls } = useDesign('basic-form')
// Get the basic configuration of the form
const getProps = computed((): FormProps => {
// @ts-expect-error
return { ...props, ...unref(propsRef) } as FormProps
})
@ -214,7 +213,7 @@ function handleEnterPress(e: KeyboardEvent) {
return
if (e.key === 'Enter' && e.target && e.target instanceof HTMLElement) {
const target: HTMLElement = e.target as HTMLElement
if (target && target.tagName && target.tagName.toUpperCase() == 'INPUT')
if (target && target.tagName && target.tagName.toUpperCase() === 'INPUT')
handleSubmit()
}
}

View File

@ -107,8 +107,6 @@ async function fetch() {
catch (error) {
console.warn(error)
}
finally {
}
}
function emitChange() {
emit('options-change', unref(getdataSource))

View File

@ -95,7 +95,7 @@ watch(
//
function parsePathsValue(paths) {
if (!paths || paths.length == 0) {
if (!paths || paths.length === 0) {
fileList.value = []
return
}
@ -114,7 +114,7 @@ function parsePathsValue(paths) {
//
function parseArrayValue(array) {
if (!array || array.length == 0) {
if (!array || array.length === 0) {
fileList.value = []
return
}
@ -225,7 +225,7 @@ function onFileChange(info) {
function handlePathChange() {
const uploadFiles = fileList.value
let path = ''
if (!uploadFiles || uploadFiles.length == 0)
if (!uploadFiles || uploadFiles.length === 0)
path = ''
const pathList: string[] = []
@ -255,12 +255,12 @@ function emitValue(value) {
}
function uidGenerator() {
return `-${Number.parseInt(Math.random() * 10000 + 1, 10)}`
return `-${Number.parseInt((Math.random() * 10000 + 1, 10).toString())}`
}
function getFileName(path) {
if (path.lastIndexOf('\\') >= 0) {
const reg = new RegExp('\\\\', 'g')
const reg = /\\/g
path = path.replace(reg, '/')
}
return path.substring(path.lastIndexOf('/') + 1)

View File

@ -227,6 +227,16 @@ export default defineComponent({
const eventKey = `on${upperFirst(changeEvent)}`
const { autoSetPlaceHolder, size } = props.formProps
const propsData: Recordable = {
allowClear: true,
getPopupContainer: (trigger: Element) => trigger.parentNode,
size,
...unref(getComponentsProps),
disabled: unref(getDisable),
}
const on = {
[eventKey]: (...args: Nullable<Recordable>[]) => {
const [e] = args
@ -240,15 +250,6 @@ export default defineComponent({
}
const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>
const { autoSetPlaceHolder, size } = props.formProps
const propsData: Recordable = {
allowClear: true,
getPopupContainer: (trigger: Element) => trigger.parentNode,
size,
...unref(getComponentsProps),
disabled: unref(getDisable),
}
const isCreatePlaceholder = !propsData.disabled && autoSetPlaceHolder
// RangePicker place is an array
if (isCreatePlaceholder && component !== 'RangePicker' && component)

View File

@ -36,7 +36,7 @@ function onMoveBack() {
createMessage.warn(`移动失败:${index}`)
return
}
if (index == unref(list).length - 1) {
if (index === unref(list).length - 1) {
doSwap(index, 0)
return
}

View File

@ -73,9 +73,8 @@ export function useForm(props?: Props): UseFormReturnType {
},
resetFields: async () => {
getForm().then(async (form) => {
const form = await getForm()
await form.resetFields()
})
},
removeSchemaByField: async (field: string | string[]) => {

View File

@ -171,7 +171,7 @@ export function useFormEvents({
fieldList = [fields]
for (const field of fieldList)
_removeSchemaByFeild(field, schemaList)
_removeSchemaByField(field, schemaList)
schemaRef.value = schemaList
}
@ -179,7 +179,7 @@ export function useFormEvents({
/**
* @description: Delete based on field name
*/
function _removeSchemaByFeild(field: string, schemaList: FormSchema[]): void {
function _removeSchemaByField(field: string, schemaList: FormSchema[]): void {
if (isString(field)) {
const index = schemaList.findIndex(schema => schema.field === field)
if (index !== -1) {

View File

@ -35,7 +35,7 @@ export default defineComponent({
},
emits: ['submit', 'change', 'update:fApi', 'update:formModel'],
setup(props, context) {
const wrapperComp = props.formConfig.layout == 'vertical' ? Col : Row
const wrapperComp = props.formConfig.layout === 'vertical' ? Col : Row
const { emit } = context
const eFormModel = ref<AForm | null>(null)

View File

@ -114,14 +114,14 @@ export default defineComponent({
//
const controlOptions = computed(() => {
return allOptions.value.filter((item) => {
return item.category == 'control'
return item.category === 'control'
})
})
//
const inputOptions = computed(() => {
return allOptions.value.filter((item) => {
return item.category == 'input'
return item.category === 'input'
})
})

View File

@ -109,7 +109,7 @@ export default defineComponent({
</div>
<FormItem label="表单属性">
<Col>
<Checkbox v-if="formConfig.layout == 'horizontal'" v-model:checked="formConfig.colon">
<Checkbox v-if="formConfig.layout === 'horizontal'" v-model:checked="formConfig.colon">
label后面显示冒号
</Checkbox>
</Col>

View File

@ -2,7 +2,7 @@
* @Description: 导入JSON模板
-->
<script lang="ts">
import { defineComponent, reactive, toRefs } from 'vue'
import { defineComponent, reactive, ref, toRefs } from 'vue'
// import message from '../../../utils/message';
import { Modal, Upload } from 'ant-design-vue'
@ -24,6 +24,8 @@ export default defineComponent({
setup() {
const { createMessage } = useMessage()
const myEditor = ref(null)
const state = reactive({
visible: false,
json: `{
@ -43,7 +45,7 @@ export default defineComponent({
"labelWidth": 100,
"labelCol": {},
"wrapperCol": {}
}`,
}`,
jsonData: {
schemas: {},
config: {},
@ -89,6 +91,7 @@ export default defineComponent({
}
return {
myEditor,
handleImportJson,
beforeUpload,
handleCancel,

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { defineComponent, reactive, toRefs, unref } from 'vue'
import { defineComponent, reactive, ref, toRefs, unref } from 'vue'
import { CodeEditor, MODE } from '@/components/CodeEditor'
import { useCopyToClipboard } from '@/hooks/web/useCopyToClipboard'
@ -25,6 +25,8 @@ export default defineComponent({
visible: false,
})
const myEditor = ref(null)
const exportData = (data: string, fileName = `file.${props.fileFormat}`) => {
let content = 'data:text/csv;charset=utf-8,'
content += data
@ -55,6 +57,7 @@ export default defineComponent({
return {
...toRefs(state),
myEditor,
exportData,
handleCopyJson,
handleExportJson,

View File

@ -1099,7 +1099,7 @@ const componentAttrs: IBaseComponentProps = {
function deleteProps(list: Omit<IBaseFormAttrs, 'tag'>[], key: string) {
list.forEach((element, index) => {
if (element.name == key)
if (element.name === key)
list.splice(index, 1)
})
}
@ -1122,7 +1122,7 @@ export const baseComponentAttrs: IBaseComponentProps = componentAttrs
// 在所有的选项中查找需要配置项
function findCompoentProps(props, name) {
const idx = props.findIndex((value: BaseFormAttrs, _index) => {
return value.name == name
return value.name === name
})
if (idx) {
if (props[idx].componentProps)
@ -1135,7 +1135,7 @@ export const componentPropsFuncs = {
RadioGroup: (compProp, options: BaseFormAttrs[]) => {
const props = findCompoentProps(options, 'size')
if (props) {
if (compProp.optionType && compProp.optionType != 'button') {
if (compProp.optionType && compProp.optionType !== 'button') {
props.disabled = true
compProp.size = null
}

View File

@ -1,4 +1,9 @@
<script lang="ts" setup>
import { type Ref, provide, ref } from 'vue'
import { Layout, LayoutContent, LayoutSider } from 'ant-design-vue'
import { cloneDeep } from 'lodash-es'
import { type UseRefHistoryReturn, useRefHistory } from '@vueuse/core'
import VFormPreview from '../VFormPreview/index.vue'
import VFormPreview2 from '../VFormPreview/useForm.vue'
import type { IFormConfig, IVFormComponent, PropsTabKey } from '../../typings/v-form-component'
@ -16,13 +21,6 @@ import CodeModal from './components/CodeModal.vue'
import 'codemirror/mode/javascript/javascript'
import type { Ref } from 'vue'
import { provide, ref } from 'vue'
import { Layout, LayoutContent, LayoutSider } from 'ant-design-vue'
import { cloneDeep } from 'lodash-es'
import type { UseRefHistoryReturn } from '@vueuse/core'
import { useRefHistory } from '@vueuse/core'
import { globalConfigState } from './config/formItemPropsConfig'
import { useDesign } from '@/hooks/web/useDesign'

View File

@ -177,7 +177,7 @@ export default defineComponent({
</template>
<slot v-if="schema.componentProps && schema.componentProps?.slotName" :name="schema.componentProps.slotName" v-bind="schema" />
<Divider v-else-if="schema.component == 'Divider' && schema.label && !formItemProps.hiddenLabel">
<Divider v-else-if="schema.component === 'Divider' && schema.label && !formItemProps.hiddenLabel">
{{ schema.label }}
</Divider>
<!-- 部分控件需要一个空div -->

View File

@ -10,6 +10,9 @@ import type { ComponentType } from '@/components/Form/src/types'
const componentMap = new Map<string, Component>()
// 外部设置的自定义控件
export const customComponents: IVFormComponent[] = []
// 如果有其它控件,可以在这里初始化
// 注册Ant控件库
@ -44,9 +47,6 @@ export function setFormDesignComponents(config: IVFormComponent | IVFormComponen
}
}
// 外部设置的自定义控件
export const customComponents: IVFormComponent[] = []
// 左侧控件列表与初始化的控件属性
// props.slotName,会在formitem级别生成一个slot,并绑定当前record值
// 属性props类型为对象不能为undefined或是null。

View File

@ -13,7 +13,7 @@ export function useFormDesignState() {
}
export function useFormModelState() {
const formModel = inject('formModel') as Ref<{}>
const formModel = inject('formModel') as Ref<object>
const setFormModel = inject('setFormModelMethod') as (key: string, value: any) => void
return { formModel, setFormModel }
}

View File

@ -35,7 +35,7 @@ export function useFormInstanceMethods(props: IAnyObject, formdata, context: Par
const { resetFields, validate, clearValidate, validateField } = useForm(formdata, [])
const submit = async () => {
const submit = () => {
// const _result = await validate();
const data = cloneDeep(toRaw(formdata.value))

View File

@ -73,20 +73,6 @@ export function useVFormMethods(
formItem[key] = value
}
/**
* props
* @param {string} field field
* @param {string} key key
* @param value
*/
const setProps: ISetProps = (field, key, value) => {
const formItem = get(field)
if (formItem?.componentProps) {
;['options', 'treeData'].includes(key) && setValue(field, undefined)
formItem.componentProps[key] = value
}
}
/**
*
* @param {string} field
@ -106,6 +92,20 @@ export function useVFormMethods(
})
}
}
/**
* props
* @param {string} field field
* @param {string} key key
* @param value
*/
const setProps: ISetProps = (field, key, value) => {
const formItem = get(field)
if (formItem?.componentProps) {
;['options', 'treeData'].includes(key) && setValue(field, undefined)
formItem.componentProps[key] = value
}
}
/**
*
* @param {string} key

View File

@ -1,5 +1,6 @@
// import { VueConstructor } from 'vue';
import { cloneDeep, isArray, isFunction, isNumber, uniqueId } from 'lodash-es'
import type { Ref } from 'vue'
import type { IFormConfig, IVFormComponent, IValidationRule } from '../typings/v-form-component'
// import { del } from '@vue/composition-api';
@ -208,14 +209,12 @@ export function runCode<T>(code: any): T {
*/
// 编码表单 Conf
export function encodeConf(designerRef: object) {
// @ts-expect-error
export function encodeConf(designerRef: Ref<Recordable>) {
return JSON.stringify(designerRef.value.getOption())
}
// 编码表单 Fields
export function encodeFields(designerRef: object) {
// @ts-expect-error
export function encodeFields(designerRef: Ref<Recordable>) {
const rule = designerRef.value.getRule()
const fields: string[] = []
rule.forEach((item) => {
@ -234,21 +233,15 @@ export function decodeFields(fields: string[]) {
}
// 设置表单的 Conf 和 Fields
export function setConfAndFields(designerRef: object, conf: string, fields: string) {
// @ts-expect-error
export function setConfAndFields(designerRef: Ref<Recordable>, conf: string, fields: string[]) {
designerRef.value.setOption(JSON.parse(conf))
// @ts-expect-error
designerRef.value.setRule(decodeFields(fields))
}
// 设置表单的 Conf 和 Fields
export function setConfAndFields2(detailPreview: object, conf: string, fields: string, value?: object) {
// @ts-expect-error
export function setConfAndFields2(detailPreview: Ref<Recordable>, conf: string, fields: string[], value?: object) {
detailPreview.value.option = JSON.parse(conf)
// @ts-expect-error
detailPreview.value.rule = decodeFields(fields)
if (value) {
// @ts-expect-error
if (value)
detailPreview.value.value = value
}
}

View File

@ -1,4 +1,4 @@
<script lang="ts" setup inheritAttrs="false">
<script lang="ts" setup>
import type { Ref } from 'vue'
import { computed, nextTick, onBeforeUnmount, onDeactivated, ref, unref, useAttrs, watch } from 'vue'
import Vditor from 'vditor'
@ -10,13 +10,17 @@ import { useRootSetting } from '@/hooks/setting/useRootSetting'
import { onMountedOrActivated } from '@/hooks/core/onMountedOrActivated'
import { propTypes } from '@/utils/propTypes'
type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined
defineOptions({ inheritAttrs: false })
const props = defineProps({
height: propTypes.number.def(360),
value: propTypes.string.def(''),
})
const emit = defineEmits(['change', 'get', 'update:value'])
type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined
const attrs = useAttrs()
const wrapRef = ref<ElRef>(null)
const vditorRef = ref(null) as Ref<Nullable<Vditor>>
@ -28,6 +32,10 @@ const { getLocale } = useLocale()
const { getDarkMode } = useRootSetting()
const valueRef = ref(props.value || '')
const instance = {
getVditor: (): Vditor => vditorRef.value!,
}
watch(
[() => getDarkMode.value, () => initedRef.value],
([val, inited]) => {
@ -117,10 +125,6 @@ function init() {
})
}
const instance = {
getVditor: (): Vditor => vditorRef.value!,
}
function destroy() {
const vditorInstance = unref(vditorRef)
if (!vditorInstance)

View File

@ -12,7 +12,7 @@ import { getAllParentPath } from '@/router/helper/menuHelper'
export function useOpenKeys(menuState: MenuState, menus: Ref<MenuType[]>, mode: Ref<MenuModeEnum>, accordion: Ref<boolean>) {
const { getCollapsed, getIsMixSidebar } = useMenuSetting()
async function setOpenKeys(path: string) {
function setOpenKeys(path: string) {
if (mode.value === MenuModeEnum.HORIZONTAL)
return

View File

@ -1,6 +1,6 @@
import basicModal from './src/BasicModal.vue'
import { withInstall } from '@/utils'
import './src/index.less'
import basicModal from './src/BasicModal.vue'
export const BasicModal = withInstall(basicModal)
export { useModalContext } from './src/hooks/useModalContext'

View File

@ -63,14 +63,14 @@ const getClass = computed(() => {
]
})
const getShowHeader = computed(() => props.content || slots?.headerContent || props.title || getHeaderSlots.value.length)
const getShowFooter = computed(() => slots?.leftFooter || slots?.rightFooter)
const getHeaderSlots = computed(() => {
return Object.keys(omit(slots, 'default', 'leftFooter', 'rightFooter', 'headerContent'))
})
const getShowHeader = computed(() => props.content || slots?.headerContent || props.title || getHeaderSlots.value.length)
const getShowFooter = computed(() => slots?.leftFooter || slots?.rightFooter)
const getContentStyle = computed((): CSSProperties => {
const { contentFullHeight, contentStyle, fixedHeight } = props
if (!contentFullHeight)

View File

@ -117,7 +117,7 @@ export default defineComponent({
const getScaleStep = computed(() => {
const scaleStep = props?.scaleStep ?? 0
if (scaleStep ?? (0 > 0 && scaleStep < 100))
if (scaleStep ?? (scaleStep < 100))
return scaleStep / 100
else
return imgState.imgScale / 10

View File

@ -21,6 +21,29 @@ export default defineComponent({
})
const barStore = ref<Recordable>({})
const cursorDown = ref()
const mouseMoveDocumentHandler = (e: any) => {
if (cursorDown.value === false)
return
const prevPage = barStore.value[bar.value.axis]
if (!prevPage)
return
const offset = (instance?.vnode.el?.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) * -1
const thumbClickPosition = thumb.value[bar.value.offset] - prevPage
const thumbPositionPercentage = ((offset - thumbClickPosition) * 100) / instance?.vnode.el?.[bar.value.offset]
wrap.value[bar.value.scroll] = (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100
}
const startDrag = (e: any) => {
e.stopImmediatePropagation()
cursorDown.value = true
on(document, 'mousemove', mouseMoveDocumentHandler)
on(document, 'mouseup', mouseUpDocumentHandler)
document.onselectstart = () => false
}
const clickThumbHandler = (e: any) => {
// prevent click event of right button
if (e.ctrlKey || e.button === 2)
@ -39,27 +62,6 @@ export default defineComponent({
wrap.value[bar.value.scroll] = (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100
}
const startDrag = (e: any) => {
e.stopImmediatePropagation()
cursorDown.value = true
on(document, 'mousemove', mouseMoveDocumentHandler)
on(document, 'mouseup', mouseUpDocumentHandler)
document.onselectstart = () => false
}
const mouseMoveDocumentHandler = (e: any) => {
if (cursorDown.value === false)
return
const prevPage = barStore.value[bar.value.axis]
if (!prevPage)
return
const offset = (instance?.vnode.el?.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) * -1
const thumbClickPosition = thumb.value[bar.value.offset] - prevPage
const thumbPositionPercentage = ((offset - thumbClickPosition) * 100) / instance?.vnode.el?.[bar.value.offset]
wrap.value[bar.value.scroll] = (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100
}
function mouseUpDocumentHandler() {
cursorDown.value = false

View File

@ -16,7 +16,8 @@ export function useOpenKeys(
collapse: Ref<boolean>,
) {
const debounceSetOpenKeys = useDebounceFn(setOpenKeys, 50)
async function setOpenKeys(path: string) {
function setOpenKeys(path: string) {
const native = !mixSider.value
const menuList = toRaw(menus.value)
const handle = () => {

View File

@ -36,7 +36,7 @@ const { prefixCls } = useDesign('basic-table-img')
<template>
<div v-if="imgList && imgList.length" :class="prefixCls" class="flex items-center mx-auto" :style="getWrapStyle">
<Badge v-if="simpleShow" :count="!showBadge || imgList.length == 1 ? 0 : imgList.length">
<Badge v-if="simpleShow" :count="!showBadge || imgList.length === 1 ? 0 : imgList.length">
<div class="img-div">
<ImagePreviewGroup>
<template v-for="(img, index) in imgList" :key="img">

View File

@ -63,6 +63,19 @@ export default defineComponent({
return ['Checkbox', 'Switch'].includes(component)
})
const getDisable = computed(() => {
const { editDynamicDisabled } = props.column
let disabled = false
if (isBoolean(editDynamicDisabled))
disabled = editDynamicDisabled
if (isFunction(editDynamicDisabled)) {
const { record } = props
disabled = editDynamicDisabled({ record })
}
return disabled
})
const getComponentProps = computed(() => {
const isCheckValue = unref(getIsCheckComp)
@ -106,18 +119,7 @@ export default defineComponent({
const dataKey = (dataIndex || key) as string
set(record, dataKey, value)
}
const getDisable = computed(() => {
const { editDynamicDisabled } = props.column
let disabled = false
if (isBoolean(editDynamicDisabled))
disabled = editDynamicDisabled
if (isFunction(editDynamicDisabled)) {
const { record } = props
disabled = editDynamicDisabled({ record })
}
return disabled
})
const getValues = computed(() => {
const { editValueMap } = props.column

View File

@ -13,7 +13,6 @@ import { ScrollContainer } from '@/components/Container'
import { useI18n } from '@/hooks/web/useI18n'
import { useDesign } from '@/hooks/web/useDesign'
// import { useSortable } from '@/hooks/web/useSortable';
import { isFunction, isNullAndUnDef } from '@/utils/is'
import { getPopupContainer as getParentContainer } from '@/utils'

View File

@ -117,7 +117,7 @@ export function useDataSource(
return unref(dataSourceRef)
})
async function updateTableData(index: number, key: string, value: any) {
function updateTableData(index: number, key: string, value: any) {
const record = dataSourceRef.value[index]
if (record)
dataSourceRef.value[index][key] = value
@ -139,7 +139,7 @@ export function useDataSource(
}
function deleteTableDataRecord(rowKey: string | number | string[] | number[]) {
if (!dataSourceRef.value || dataSourceRef.value.length == 0)
if (!dataSourceRef.value || dataSourceRef.value.length === 0)
return
const rowKeyName = unref(getRowKey)
if (!rowKeyName)
@ -194,7 +194,7 @@ export function useDataSource(
}
function findTableDataRecord(rowKey: string | number) {
if (!dataSourceRef.value || dataSourceRef.value.length == 0)
if (!dataSourceRef.value || dataSourceRef.value.length === 0)
return
const rowKeyName = unref(getRowKey)

View File

@ -77,7 +77,7 @@ export function usePagination(refProps: ComputedRef<BasicTableProps>) {
return unref(show)
}
async function setShowPagination(flag: boolean) {
function setShowPagination(flag: boolean) {
show.value = flag
}

View File

@ -146,7 +146,7 @@ export function useTable(tableProps?: Props): [
return unref(formRef) as unknown as FormActionType
},
setShowPagination: async (show: boolean) => {
getTableInstance().setShowPagination(show)
await getTableInstance().setShowPagination(show)
},
getShowPagination: () => {
return toRaw(getTableInstance().getShowPagination())
@ -164,7 +164,7 @@ export function useTable(tableProps?: Props): [
getTableInstance().scrollTo(pos)
},
setShowForm: async (show: boolean) => {
getTableInstance().setShowForm(show)
await getTableInstance().setShowForm(show)
},
getShowForm: () => {
return toRaw(getTableInstance().getShowForm())

View File

@ -46,7 +46,7 @@ export function useTableForm(
return unref(show)
}
async function setShowForm(flag: boolean) {
function setShowForm(flag: boolean) {
show.value = flag
}

View File

@ -25,7 +25,7 @@ export interface TableRowSelection<T = any> extends ITableRowSelection {
* Callback executed when select/deselect one row
* @type Function
*/
onSelect?: (record: T, selected: boolean, selectedRows: Object[], nativeEvent: Event) => any
onSelect?: (record: T, selected: boolean, selectedRows: object[], nativeEvent: Event) => any
/**
* Callback executed when select/deselect all rows
@ -55,11 +55,6 @@ export interface ColumnFilterItem {
children?: any
}
export interface TableCustomRecord<T = Recordable> {
record?: T
index?: number
}
export interface SorterResult {
column: ColumnProps
order: SortOrder

View File

@ -2,5 +2,5 @@ import BasicTree from './src/BasicTree.vue'
import './style'
export { BasicTree }
export type { ContextMenuItem } from '@/hooks/web/useContextMenu'
export * from './src/types/tree'

View File

@ -61,7 +61,7 @@ export default {
const instance = ref({})
const showBox = computed(() => {
if (mode.value == 'pop')
if (mode.value === 'pop')
return clickShow.value
else
return true
@ -79,7 +79,7 @@ export default {
refresh()
}
const show = () => {
if (mode.value == 'pop')
if (mode.value === 'pop')
clickShow.value = true
}
watchEffect(() => {
@ -111,21 +111,21 @@ export default {
<template>
<div v-show="showBox" :class="mode == 'pop' ? 'mask' : ''">
<div :class="mode == 'pop' ? 'verifybox' : ''" :style="{ 'max-width': `${parseInt(imgSize.width) + 20}px` }">
<div v-if="mode == 'pop'" class="verifybox-top">
<div :class="mode === 'pop' ? 'verifybox' : ''" :style="{ 'max-width': `${parseInt(imgSize.width) + 20}px` }">
<div v-if="mode === 'pop'" class="verifybox-top">
{{ t('component.captcha.verification') }}
<span class="verifybox-close" @click="closeBox">
<i class="iconfont icon-close" />
</span>
</div>
<div class="verifybox-bottom" :style="{ padding: mode == 'pop' ? '10px' : '0' }">
<div class="verifybox-bottom" :style="{ padding: mode === 'pop' ? '10px' : '0' }">
<!-- 验证码容器 -->
<component
:is="componentType"
v-if="componentType"
ref="instance"
:captcha-type="captchaType"
:type="verifyType"
ref="instance"
:figure="figure"
:arith="arith"
:mode="mode"

View File

@ -90,9 +90,44 @@ onMounted(() => {
}
})
const canvas = ref(null)
//
const getMousePos = function (obj, e) {
const x = e.offsetX
const y = e.offsetY
return { x, y }
}
//
const createPoint = function (pos) {
tempPoints.push(Object.assign({}, pos))
return num.value + 1
}
//
const pointTransfrom = function (pointArr, imgSize) {
const newPointArr = pointArr.map((p) => {
const x = Math.round((310 * p.x) / Number.parseInt(imgSize.imgWidth))
const y = Math.round((155 * p.y) / Number.parseInt(imgSize.imgHeight))
return { x, y }
})
return newPointArr
}
const refresh = async function () {
tempPoints.splice(0, tempPoints.length)
barAreaColor.value = '#000'
barAreaBorderColor.value = '#ddd'
bindingClick.value = true
fontPos.splice(0, fontPos.length)
checkPosArr.splice(0, checkPosArr.length)
num.value = 1
await getPictrue()
showRefresh.value = true
}
function canvasClick(e) {
checkPosArr.push(getMousePos(canvas, e))
if (num.value == checkNum.value) {
if (num.value === checkNum.value) {
num.value = createPoint(getMousePos(canvas, e))
//
const arr = pointTransfrom(checkPosArr, setSize)
@ -112,12 +147,12 @@ function canvasClick(e) {
}
checkCaptcha(data).then((response) => {
const res = response.data
if (res.repCode == '0000') {
if (res.repCode === '0000') {
barAreaColor.value = '#4cae4c'
barAreaBorderColor.value = '#5cb85c'
text.value = t('component.captcha.success')
bindingClick.value = false
if (mode.value == 'pop') {
if (mode.value === 'pop') {
setTimeout(() => {
proxy.$parent.clickShow = false
refresh()
@ -140,28 +175,6 @@ function canvasClick(e) {
if (num.value < checkNum.value)
num.value = createPoint(getMousePos(canvas, e))
}
//
const getMousePos = function (obj, e) {
const x = e.offsetX
const y = e.offsetY
return { x, y }
}
//
const createPoint = function (pos) {
tempPoints.push(Object.assign({}, pos))
return num.value + 1
}
const refresh = async function () {
tempPoints.splice(0, tempPoints.length)
barAreaColor.value = '#000'
barAreaBorderColor.value = '#ddd'
bindingClick.value = true
fontPos.splice(0, fontPos.length)
checkPosArr.splice(0, checkPosArr.length)
num.value = 1
await getPictrue()
showRefresh.value = true
}
//
async function getPictrue() {
@ -169,7 +182,7 @@ async function getPictrue() {
captchaType: captchaType.value,
}
const res = await getCaptcha(data)
if (res.data.repCode == '0000') {
if (res.data.repCode === '0000') {
pointBackImgBase.value = res.data.repData.originalImageBase64
backToken.value = res.data.repData.token
secretKey.value = res.data.repData.secretKey
@ -180,15 +193,6 @@ async function getPictrue() {
text.value = res.data.repMsg
}
}
//
const pointTransfrom = function (pointArr, imgSize) {
const newPointArr = pointArr.map((p) => {
const x = Math.round((310 * p.x) / Number.parseInt(imgSize.imgWidth))
const y = Math.round((155 * p.y) / Number.parseInt(imgSize.imgHeight))
return { x, y }
})
return newPointArr
}
</script>
<template>

View File

@ -154,17 +154,18 @@ onMounted(() => {
//
function start(e) {
e = e || window.event
let x
if (!e.touches) {
// PC
var x = e.clientX
x = e.clientX
}
else {
//
var x = e.touches[0].pageX
x = e.touches[0].pageX
}
startLeft.value = Math.floor(x - barArea.value.getBoundingClientRect().left)
startMoveTime.value = +new Date() //
if (isEnd.value == false) {
if (isEnd.value === false) {
text.value = ''
moveBlockBackgroundColor.value = '#337ab7'
leftBarBorderColor.value = '#337AB7'
@ -176,14 +177,15 @@ function start(e) {
//
function move(e) {
e = e || window.event
if (status.value && isEnd.value == false) {
let x
if (status.value && isEnd.value === false) {
if (!e.touches) {
// PC
var x = e.clientX
x = e.clientX
}
else {
//
var x = e.touches[0].pageX
x = e.touches[0].pageX
}
const bar_area_left = barArea.value.getBoundingClientRect().left
let move_block_left = x - bar_area_left // left
@ -203,7 +205,7 @@ function move(e) {
function end() {
endMovetime.value = +new Date()
//
if (status.value && isEnd.value == false) {
if (status.value && isEnd.value === false) {
let moveLeftDistance = Number.parseInt((moveBlockLeft.value || '').replace('px', ''))
moveLeftDistance = (moveLeftDistance * 310) / Number.parseInt(setSize.imgWidth)
const data = {
@ -215,14 +217,14 @@ function end() {
}
checkCaptcha(data).then((response) => {
const res = response.data
if (res.repCode == '0000') {
if (res.repCode === '0000') {
moveBlockBackgroundColor.value = '#5cb85c'
leftBarBorderColor.value = '#5cb85c'
iconColor.value = '#fff'
iconClass.value = 'icon-check'
showRefresh.value = false
isEnd.value = true
if (mode.value == 'pop') {
if (mode.value === 'pop') {
setTimeout(() => {
proxy.$parent.clickShow = false
refresh()
@ -290,7 +292,7 @@ async function getPictrue() {
captchaType: captchaType.value,
}
const res = await getCaptcha(data)
if (res.data.repCode == '0000') {
if (res.data.repCode === '0000') {
backImgBase.value = res.data.repData.originalImageBase64
blockBackImgBase.value = `data:image/png;base64,${res.data.repData.jigsawImageBase64}`
backToken.value = res.data.repData.token

View File

@ -32,7 +32,7 @@ const prefixCls = 'virtual-scroll'
function convertToUnit(str: string | number | null | undefined, unit = 'px'): string | undefined {
if (str == null || str === '')
return undefined
else if (isNaN(+str!))
else if (Number.isNaN(+str!))
return String(str)
else
return `${Number(str)}${unit}`

View File

@ -172,7 +172,7 @@ function rippler({ event, el, zIndex, background }: { event: EventType; el: HTML
function setProps(modifiers: Recordable, props: Recordable) {
modifiers.forEach((item: Recordable) => {
if (isNaN(Number(item)))
if (Number.isNaN(Number(item)))
props.event = item
else props.transition = item
})

View File

@ -14,7 +14,7 @@ export function entries<T>(obj: Recordable<T>): [string, T][] {
return Object.keys(obj).map((key: string) => [key, obj[key]])
}
export function useAttrs(params: Params = {}): Ref<Recordable> | {} {
export function useAttrs(params: Params = {}): Ref<Recordable> | object {
const instance = getCurrentInstance()
if (!instance)
return {}

View File

@ -12,22 +12,9 @@ export function useHeaderSetting() {
const { getFullContent } = useFullContent()
const appStore = useAppStore()
const getShowFullHeaderRef = computed(() => {
return !unref(getFullContent) && unref(getShowMixHeaderRef) && unref(getShowHeader) && !unref(getIsTopMenu) && !unref(getIsMixSidebar)
})
const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef))
const getShowInsetHeaderRef = computed(() => {
const need = !unref(getFullContent) && unref(getShowHeader)
return (need && !unref(getShowMixHeaderRef)) || (need && unref(getIsTopMenu)) || (need && unref(getIsMixSidebar))
})
const { getMenuMode, getSplit, getShowHeaderTrigger, getIsSidebarType, getIsMixSidebar, getIsTopMenu } = useMenuSetting()
const { getShowBreadCrumb, getShowLogo } = useRootSetting()
const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader))
const getShowDoc = computed(() => appStore.getHeaderSetting.showDoc)
const getHeaderTheme = computed(() => appStore.getHeaderSetting.theme)
@ -46,6 +33,19 @@ export function useHeaderSetting() {
const getShowNotice = computed(() => appStore.getHeaderSetting.showNotice)
const getShowMixHeaderRef = computed(() => !unref(getIsSidebarType) && unref(getShowHeader))
const getShowFullHeaderRef = computed(() => {
return !unref(getFullContent) && unref(getShowMixHeaderRef) && unref(getShowHeader) && !unref(getIsTopMenu) && !unref(getIsMixSidebar)
})
const getUnFixedAndFull = computed(() => !unref(getFixed) && !unref(getShowFullHeaderRef))
const getShowInsetHeaderRef = computed(() => {
const need = !unref(getFullContent) && unref(getShowHeader)
return (need && !unref(getShowMixHeaderRef)) || (need && unref(getIsTopMenu)) || (need && unref(getIsMixSidebar))
})
const getShowBread = computed(() => {
return unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && unref(getShowBreadCrumb) && !unref(getSplit)
})
@ -64,7 +64,6 @@ export function useHeaderSetting() {
}
return {
setHeaderSetting,
getShowDoc,
getShowSearch,
getHeaderTheme,

View File

@ -13,10 +13,6 @@ export function useMenuSetting() {
const { getFullContent: fullContent } = useFullContent()
const appStore = useAppStore()
const getShowSidebar = computed(() => {
return unref(getSplit) || (unref(getShowMenu) && unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && !unref(fullContent))
})
const getCollapsed = computed(() => appStore.getMenuSetting.collapsed)
const getMenuType = computed(() => appStore.getMenuSetting.type)
@ -57,6 +53,10 @@ export function useMenuSetting() {
const getCollapsedShowTitle = computed(() => appStore.getMenuSetting.collapsedShowTitle)
const getShowSidebar = computed(() => {
return unref(getSplit) || (unref(getShowMenu) && unref(getMenuMode) !== MenuModeEnum.HORIZONTAL && !unref(fullContent))
})
const getShowTopMenu = computed(() => {
return unref(getMenuMode) === MenuModeEnum.HORIZONTAL || unref(getSplit)
})
@ -80,6 +80,11 @@ export function useMenuSetting() {
return unref(getMenuMode) === MenuModeEnum.INLINE && unref(getMenuType) === MenuTypeEnum.MIX
})
const getMiniWidthNumber = computed(() => {
const { collapsedShowTitle, siderHidden } = appStore.getMenuSetting
return siderHidden ? 0 : collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH
})
const getRealWidth = computed(() => {
if (unref(getIsMixSidebar))
return unref(getCollapsed) && !unref(getMixSideFixed) ? unref(getMiniWidthNumber) : unref(getMenuWidth)
@ -87,11 +92,6 @@ export function useMenuSetting() {
return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth)
})
const getMiniWidthNumber = computed(() => {
const { collapsedShowTitle, siderHidden } = appStore.getMenuSetting
return siderHidden ? 0 : collapsedShowTitle ? SIDE_BAR_SHOW_TIT_MINI_WIDTH : SIDE_BAR_MINI_WIDTH
})
const getCalcContentWidth = computed(() => {
const width
= unref(getIsTopMenu) || !unref(getShowMenu) || (unref(getSplit) && unref(getMenuHidden))

View File

@ -1,8 +1,6 @@
import { getCurrentInstance, onUnmounted } from 'vue'
import { createContextMenu, destroyContextMenu } from '@/components/ContextMenu'
import type { ContextMenuItem } from '@/components/ContextMenu'
export type { ContextMenuItem }
export function useContextMenu(authRemove = true) {
if (getCurrentInstance() && authRemove) {
onUnmounted(() => {

View File

@ -27,9 +27,12 @@ export function usePermission() {
/**
* Change permission mode
*/
async function togglePermissionMode() {
function togglePermissionMode() {
appStore.setProjectConfig({
permissionMode: projectSetting.permissionMode === PermissionModeEnum.BACK ? PermissionModeEnum.ROUTE_MAPPING : PermissionModeEnum.BACK,
permissionMode: projectSetting.permissionMode
=== PermissionModeEnum.BACK
? PermissionModeEnum.ROUTE_MAPPING
: PermissionModeEnum.BACK,
})
location.reload()
}
@ -99,7 +102,7 @@ export function usePermission() {
/**
* refresh menu data
*/
async function refreshMenu() {
function refreshMenu() {
resume()
}

View File

@ -5,7 +5,7 @@ import { addResizeListener, removeResizeListener } from '@/utils/event'
import { isDef } from '@/utils/is'
const domSymbol = Symbol('watermark-dom')
const sourceMap = new WeakMap<HTMLElement, {}>()
const sourceMap = new WeakMap<HTMLElement, object>()
export function useWatermark(appendEl: Ref<HTMLElement | null> = ref(document.body)) {
const appendElRaw = unref(appendEl)

View File

@ -30,7 +30,7 @@ export function useContentViewHeight() {
{ immediate: true },
)
async function setPageHeight(height: number) {
function setPageHeight(height: number) {
pageHeight.value = height
}

View File

@ -1,7 +1,7 @@
<script lang="ts" setup>
import { computed, ref, unref, watch } from 'vue'
import { Avatar, List, Tag, Typography } from 'ant-design-vue'
import { ListItem } from './data'
import type { ListItem } from './data'
import { useDesign } from '@/hooks/web/useDesign'
import { isNumber } from '@/utils/is'
@ -31,9 +31,6 @@ const props = defineProps({
},
})
const emit = defineEmits(['update:currentPage'])
const ListItem = List.Item
const ListItemMeta = List.Item.Meta
const TypographyParagraph = Typography.Paragraph
const { prefixCls } = useDesign('header-notify-list')
const current = ref(props.currentPage || 1)
const getData = computed(() => {
@ -77,11 +74,11 @@ function handleTitleClick(item: ListItem) {
<template>
<List :class="prefixCls" bordered :pagination="getPagination">
<template v-for="item in getData" :key="item.id">
<ListItem class="list-item">
<ListItemMeta>
<List.Item class="list-item">
<List.Item.Meta>
<template #title>
<div class="title">
<TypographyParagraph
<Typography.Paragraph
style="width: 100%; margin-bottom: 0 !important"
:style="{ cursor: isTitleClickable ? 'pointer' : '' }"
:delete="!!item.titleDelete"
@ -105,7 +102,7 @@ function handleTitleClick(item: ListItem) {
<template #description>
<div>
<div v-if="item.description" class="description">
<TypographyParagraph
<Typography.Paragraph
style="width: 100%; margin-bottom: 0 !important"
:ellipsis="$props.descRows && $props.descRows > 0 ? { rows: $props.descRows, tooltip: !!item.description } : false"
:content="item.description"
@ -116,8 +113,8 @@ function handleTitleClick(item: ListItem) {
</div>
</div>
</template>
</ListItemMeta>
</ListItem>
</List.Item.Meta>
</List.Item>
</template>
</List>
</template>

View File

@ -50,7 +50,7 @@ const staticMenus: Menu[] = []
staticMenus.push(transformMenuModule(menu))
})()
async function getAsyncMenus() {
function getAsyncMenus() {
const permissionStore = usePermissionStore()
// 递归过滤所有隐藏的菜单
const menuFilter = (items) => {
@ -82,7 +82,7 @@ export async function getMenus(): Promise<Menu[]> {
export async function getCurrentParentPath(currentPath: string) {
const menus = await getAsyncMenus()
const allParentPath = await getAllParentPath(menus, currentPath)
const allParentPath = getAllParentPath(menus, currentPath)
return allParentPath?.[0]
}

View File

@ -90,11 +90,11 @@ export const useAppStore = defineStore('app', {
Persistent.setLocal(PROJ_CFG_KEY, this.projectConfig)
},
async resetAllState() {
resetAllState() {
resetRouter()
Persistent.clearAll()
},
async setPageLoadingAction(loading: boolean): Promise<void> {
setPageLoadingAction(loading: boolean) {
if (loading) {
clearTimeout(timeId)
// Prevent flicker

View File

@ -60,7 +60,7 @@ export const useMultipleTabStore = defineStore('app-multiple-tab', {
/**
* Update the cache according to the currently opened tabs
*/
async updateCacheTab() {
updateCacheTab() {
const cacheMap: Set<string> = new Set()
for (const tab of this.tabList) {
@ -115,7 +115,7 @@ export const useMultipleTabStore = defineStore('app-multiple-tab', {
path !== toPath && go(toPath as PageEnum, true)
},
async addTab(route: RouteLocationNormalized) {
addTab(route: RouteLocationNormalized) {
const { path, name, fullPath, params, query, meta } = getRawRoute(route)
// 404 The page does not need to add a tab
if (
@ -242,7 +242,7 @@ export const useMultipleTabStore = defineStore('app-multiple-tab', {
},
// Sort the tabs
async sortTabs(oldIndex: number, newIndex: number) {
sortTabs(oldIndex: number, newIndex: number) {
const currentTab = this.tabList[oldIndex]
this.tabList.splice(oldIndex, 1)
this.tabList.splice(newIndex, 0, currentTab)
@ -250,7 +250,7 @@ export const useMultipleTabStore = defineStore('app-multiple-tab', {
},
// Close the tab on the right and jump
async closeLeftTabs(route: RouteLocationNormalized, router: Router) {
closeLeftTabs(route: RouteLocationNormalized, router: Router) {
const index = this.tabList.findIndex(item => item.path === route.path)
if (index > 0) {
@ -268,7 +268,7 @@ export const useMultipleTabStore = defineStore('app-multiple-tab', {
},
// Close the tab on the left and jump
async closeRightTabs(route: RouteLocationNormalized, router: Router) {
closeRightTabs(route: RouteLocationNormalized, router: Router) {
const index = this.tabList.findIndex(item => item.fullPath === route.fullPath)
if (index >= 0 && index < this.tabList.length - 1) {
@ -286,7 +286,7 @@ export const useMultipleTabStore = defineStore('app-multiple-tab', {
handleGotoPage(router)
},
async closeAllTab(router: Router) {
closeAllTab(router: Router) {
this.tabList = this.tabList.filter(item => item?.meta?.affix ?? false)
this.clearCacheTabs()
this.goToPage(router)
@ -295,7 +295,7 @@ export const useMultipleTabStore = defineStore('app-multiple-tab', {
/**
* Close other tabs
*/
async closeOtherTabs(route: RouteLocationNormalized, router: Router) {
closeOtherTabs(route: RouteLocationNormalized, router: Router) {
const closePathList = this.tabList.map(item => item.fullPath)
const pathList: string[] = []
@ -320,29 +320,29 @@ export const useMultipleTabStore = defineStore('app-multiple-tab', {
/**
* Close tabs in bulk
*/
async bulkCloseTabs(pathList: string[]) {
bulkCloseTabs(pathList: string[]) {
this.tabList = this.tabList.filter(item => !pathList.includes(item.fullPath))
},
/**
* Set tab's title
*/
async setTabTitle(title: string, route: RouteLocationNormalized) {
setTabTitle(title: string, route: RouteLocationNormalized) {
const findTab = this.getTabList.find(item => item === route)
if (findTab) {
findTab.meta.title = title
await this.updateCacheTab()
this.updateCacheTab()
}
},
/**
* replace tab's path
* **/
async updateTabPath(fullPath: string, route: RouteLocationNormalized) {
updateTabPath(fullPath: string, route: RouteLocationNormalized) {
const findTab = this.getTabList.find(item => item === route)
if (findTab) {
findTab.fullPath = fullPath
findTab.path = fullPath
await this.updateCacheTab()
this.updateCacheTab()
}
},
},

View File

@ -17,9 +17,9 @@ export function getStorageShortName() {
export function getAppEnvConfig() {
const ENV_NAME = getConfigFileName(import.meta.env)
// Get the global configuration (the configuration will be extracted independently when packaging)
const ENV = (import.meta.env.DEV
? // Get the global configuration (the configuration will be extracted independently when packaging)
(import.meta.env as unknown as GlobEnvConfig)
? (import.meta.env as unknown as GlobEnvConfig)
: window[ENV_NAME as any]) as unknown as GlobEnvConfig
const {

View File

@ -9,7 +9,7 @@ import type { RequestOptions, Result, UploadFileParams } from '@/types/axios'
import { ContentTypeEnum, RequestEnum } from '@/enums/httpEnum'
import { downloadByData } from '@/utils/file/download'
import { useGlobSetting } from '@/hooks/setting'
import { getAccessToken, getRefreshToken, getTenantId, setAccessToken } from '@/utils/auth'
import { getRefreshToken, getTenantId, setAccessToken } from '@/utils/auth'
export * from './axiosTransform'
const globSetting = useGlobSetting()
@ -49,7 +49,8 @@ export class VAxios {
refreshToken() {
axios.defaults.headers.common['tenant-id'] = getTenantId() as number
return axios.post(`${globSetting.apiUrl}/system/auth/refresh-token?refreshToken=${getRefreshToken()}`)
const refreshToken = getRefreshToken() as string
return axios.post(`${globSetting.apiUrl}/system/auth/refresh-token?refreshToken=${refreshToken}`)
}
/**
@ -118,8 +119,9 @@ export class VAxios {
try {
const refreshTokenRes = await this.refreshToken()
// 2.1 刷新成功,则回放队列的请求 + 当前请求
const refreshToken = getRefreshToken() as string
setAccessToken(refreshTokenRes.data.data.accessToken)
;(config as Recordable).headers.Authorization = `Bearer ${getAccessToken()}`
;(config as Recordable).headers.Authorization = `Bearer ${refreshToken}`
requestList.forEach((cb: any) => {
cb()
})
@ -143,8 +145,9 @@ export class VAxios {
else {
// 添加到队列,等待刷新获取到新的令牌
return new Promise((resolve) => {
const refreshToken = getRefreshToken() as string
requestList.push(() => {
;(config as Recordable).headers.Authorization = `Bearer ${getAccessToken()}` // 让每个请求携带自定义token 请根据实际情况自行修改
;(config as Recordable).headers.Authorization = `Bearer ${refreshToken}` // 让每个请求携带自定义token 请根据实际情况自行修改
resolve(this.axiosInstance(config))
})
})
@ -197,7 +200,6 @@ export class VAxios {
data: formData,
headers: {
'Content-type': ContentTypeEnum.FORM_DATA,
// @ts-expect-error
'ignoreCancelToken': true,
},
})

View File

@ -9,7 +9,6 @@ export class AxiosRetry {
*
*/
retry(axiosInstance: AxiosInstance, error: AxiosError) {
// @ts-expect-error
const { config } = error.response
const { waitTime, count } = config?.requestOptions?.retryRequest
config.__retryCount = config.__retryCount || 0

View File

@ -9,7 +9,6 @@ import projectSetting from '@/settings/projectSetting'
import { SessionTimeoutProcessingEnum } from '@/enums/appEnum'
const { createMessage, createErrorModal } = useMessage()
const error = createMessage.error
const stp = projectSetting.sessionTimeoutProcessing
export function checkStatus(status: number, msg: string, errorMessageMode: ErrorMessageMode = 'message'): void {
@ -71,6 +70,6 @@ export function checkStatus(status: number, msg: string, errorMessageMode: Error
if (errorMessageMode === 'modal')
createErrorModal({ title: t('sys.api.errorTip'), content: errMessage })
else if (errorMessageMode === 'message')
error({ content: errMessage, key: `global_error_message_status_${status}` })
createMessage.error({ content: errMessage, key: `global_error_message_status_${status}` })
}
}

View File

@ -246,8 +246,8 @@ const transform: AxiosTransform = {
const { isOpenRetry } = config.requestOptions.retryRequest
config.method?.toUpperCase() === RequestEnum.GET
&& isOpenRetry
// @ts-expect-error
&& retryRequest.retry(axiosInstance, error)
return Promise.reject(error)
},
}

View File

@ -157,14 +157,13 @@ export function withInstall<T extends CustomComponent>(component: T, alias?: str
*/
export function simpleDebounce(fn, delay = 100) {
let timer: any | null = null
return function () {
return () => {
// eslint-disable-next-line prefer-rest-params
const args = arguments
if (timer)
clearTimeout(timer)
timer = setTimeout(() => {
// @ts-expect-error
fn.apply(this, args)
}, delay)
}

View File

@ -32,7 +32,7 @@ export interface Indexable<T> {
export type Hash<T> = Indexable<T>
export type TimeoutHandle = ReturnType<typeof global.setTimeout>
export type TimeoutHandle = ReturnType<typeof globalThis.setTimeout>
export type ComponentSize = 'large' | 'medium' | 'small' | 'mini'

View File

@ -31,7 +31,7 @@ export function useLoginState() {
return { setLoginState, getLoginState, handleBackLogin }
}
export function useFormValid<T extends Object = any>(formRef: Ref<FormInstance>) {
export function useFormValid<T extends object = any>(formRef: Ref<FormInstance>) {
const validate = computed(() => {
const form = unref(formRef)
return form?.validate ?? ((_nameList?: NamePath) => Promise.resolve())

View File

@ -13,7 +13,7 @@ const { createMessage } = useMessage()
const [registerModal, { openModal }] = useModal()
function handleEdit(title: string) {
if (title == '账户密码')
if (title === '账户密码')
openModal(true, {})
}
function handleSuccess() {

View File

@ -1,5 +1,6 @@
<script setup lang="ts">
import { TabPane, Tabs } from 'ant-design-vue'
import { ref } from 'vue'
import { settingList } from './data'
import BaseSetting from './BaseSetting.vue'
import SecureSetting from './SecureSetting.vue'
@ -7,6 +8,8 @@ import AccountBind from './AccountBind.vue'
import MsgNotify from './MsgNotify.vue'
import { ScrollContainer } from '@/components/Container/index'
const wrapperRef = ref(null)
const tabBarStyle = { width: '220px' }
</script>
@ -16,10 +19,10 @@ const tabBarStyle = { width: '220px' }
<Tabs tab-position="left" :tab-bar-style="tabBarStyle">
<template v-for="item in settingList" :key="item.key">
<TabPane :tab="item.name">
<BaseSetting v-if="item.component == 'BaseSetting'" />
<SecureSetting v-if="item.component == 'SecureSetting'" />
<AccountBind v-if="item.component == 'AccountBind'" />
<MsgNotify v-if="item.component == 'MsgNotify'" />
<BaseSetting v-if="item.component === 'BaseSetting'" />
<SecureSetting v-if="item.component === 'SecureSetting'" />
<AccountBind v-if="item.component === 'AccountBind'" />
<MsgNotify v-if="item.component === 'MsgNotify'" />
</TabPane>
</template>
</Tabs>

View File

@ -27,6 +27,11 @@ const ListItem = List.Item
const CardMeta = Card.Meta
const TypographyText = Typography.Text
//
const page = ref(1)
const pageSize = ref(36)
const total = ref(0)
// slider
const sliderProp = computed(() => useSlider())
@ -97,9 +102,6 @@ async function fetch(p = {}) {
}
}
//
const page = ref(1)
const pageSize = ref(36)
const total = ref(0)
const paginationProp = ref({
showSizeChanger: false,
showQuickJumper: true,

View File

@ -7,11 +7,12 @@ import { Description, useDescription } from '@/components/Description/index'
defineOptions({ name: 'MessageInfoModal' })
const data = ref<MessageInfo>()
const [innerRegister] = useModalInner((value: MessageInfo) => {
data.value = value
})
const data = ref<MessageInfo>()
const [descriptionRegister] = useDescription({
column: 1,
schema: infoSchema,