mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-23 23:39:47 +08:00
Merge branch 'dev' of https://gitee.com/xlsea/ruoyi-plus-soybean into flow
This commit is contained in:
@ -20,44 +20,45 @@ const fileList = ref<UploadFileInfo[]>([]);
|
||||
|
||||
async function handleFetchOssList(ossIds: string[]) {
|
||||
startLoading();
|
||||
const { error, data } = await fetchGetOssListByIds(ossIds);
|
||||
if (error) return;
|
||||
fileList.value = data.map(item => ({
|
||||
id: String(item.ossId),
|
||||
url: item.url,
|
||||
name: item.originalName,
|
||||
status: 'finished'
|
||||
}));
|
||||
endLoading();
|
||||
try {
|
||||
const { error, data } = await fetchGetOssListByIds(ossIds);
|
||||
if (error) return;
|
||||
fileList.value = data.map(item => ({
|
||||
id: String(item.ossId),
|
||||
url: item.url,
|
||||
name: item.originalName,
|
||||
status: 'finished'
|
||||
}));
|
||||
} catch (error) {
|
||||
window.$message?.error(`获取文件列表失败: ${error}`);
|
||||
} finally {
|
||||
endLoading();
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
value,
|
||||
async val => {
|
||||
const ossIds = val?.split(',')?.filter(item => isNotNull(item)) || [];
|
||||
const fileIds = new Set(fileList.value.filter(item => item.status === 'finished').map(item => item.id));
|
||||
if (ossIds.every(item => fileIds.has(item))) {
|
||||
return;
|
||||
}
|
||||
if (ossIds.length === 0) {
|
||||
fileList.value = [];
|
||||
return;
|
||||
}
|
||||
const fileIds = new Set(fileList.value.filter(item => item.status === 'finished').map(item => item.id));
|
||||
if (ossIds.every(item => fileIds.has(item))) {
|
||||
return;
|
||||
}
|
||||
await handleFetchOssList(ossIds);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
fileList,
|
||||
val => {
|
||||
value.value = val
|
||||
.filter(item => item.status === 'finished')
|
||||
.map(item => item.id)
|
||||
.join(',');
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
watch(fileList, val => {
|
||||
value.value = val
|
||||
.filter(item => item.status === 'finished')
|
||||
.map(item => item.id)
|
||||
.join(',');
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -2,6 +2,7 @@ import { ref, toValue } from 'vue';
|
||||
import type { ComputedRef, Ref } from 'vue';
|
||||
import type { FormInst } from 'naive-ui';
|
||||
import { REG_CODE_SIX, REG_EMAIL, REG_PHONE, REG_PWD, REG_USER_NAME } from '@/constants/reg';
|
||||
import { isNull } from '@/utils/common';
|
||||
import { $t } from '@/locales';
|
||||
|
||||
export function useFormRules() {
|
||||
@ -52,7 +53,7 @@ export function useFormRules() {
|
||||
required: true,
|
||||
trigger: ['input', 'blur'],
|
||||
validator: (_rule: any, value: any) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
if (isNull(value) || (Array.isArray(value) && value.length === 0)) {
|
||||
return new Error(message);
|
||||
}
|
||||
return true;
|
||||
|
@ -107,12 +107,12 @@ export async function loadDynamicComponent<T extends object = any>(
|
||||
|
||||
/** 判断是否为空 */
|
||||
export function isNotNull(value: any) {
|
||||
return value !== undefined && value !== null && value !== '' && value !== 'undefined' && value !== 'null';
|
||||
return value !== undefined && value !== null && value !== '';
|
||||
}
|
||||
|
||||
/** 判断是否为空 */
|
||||
export function isNull(value: any) {
|
||||
return value === undefined || value === null || value === '' || value === 'undefined' || value === 'null';
|
||||
return value === undefined || value === null || value === '';
|
||||
}
|
||||
|
||||
/** 判断是否为图片类型 */
|
||||
|
@ -28,7 +28,9 @@ const accept = computed(() => (props.uploadType === 'file' ? AcceptType.File : A
|
||||
|
||||
const fileList = ref<UploadFileInfo[]>([]);
|
||||
|
||||
function handleUpdateModelWhenUpload() {}
|
||||
function handleUpdateModelWhenUpload() {
|
||||
fileList.value = [];
|
||||
}
|
||||
|
||||
function closeDrawer() {
|
||||
visible.value = false;
|
||||
|
@ -273,7 +273,7 @@ function handleAuthUser(row: Api.System.Role) {
|
||||
:data="data"
|
||||
size="small"
|
||||
:flex-height="!appStore.isMobile"
|
||||
:scroll-x="962"
|
||||
:scroll-x="1200"
|
||||
:loading="loading"
|
||||
remote
|
||||
:row-key="row => row.roleId"
|
||||
|
@ -1,5 +1,6 @@
|
||||
<script setup lang="tsx">
|
||||
import { computed, watch } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { NDatePicker } from 'naive-ui';
|
||||
import { fetchGetRoleUserList, fetchGetUserList } from '@/service/api/system';
|
||||
import { useAppStore } from '@/store/modules/app';
|
||||
import { useDict } from '@/hooks/business/dict';
|
||||
@ -133,6 +134,22 @@ watch(visible, () => {
|
||||
handleUpdateModelWhenEdit();
|
||||
}
|
||||
});
|
||||
|
||||
const dateRangeCreateTime = ref<[string, string] | null>(null);
|
||||
|
||||
const datePickerRef = ref<InstanceType<typeof NDatePicker>>();
|
||||
|
||||
function onDateRangeCreateTimeUpdate(value: [string, string] | null) {
|
||||
if (value?.length) {
|
||||
searchParams.params!.beginTime = value[0];
|
||||
searchParams.params!.endTime = value[1];
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
dateRangeCreateTime.value = null;
|
||||
resetSearchParams();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -158,9 +175,22 @@ watch(visible, () => {
|
||||
<NFormItemGi span="24 s:12 m:8" label="手机号码" path="phonenumber" class="pr-24px">
|
||||
<NInput v-model:value="searchParams.phonenumber" placeholder="请输入手机号码" />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span="24 s:12 m:24" class="pr-24px" :show-feedback="false">
|
||||
<NFormItemGi span="24 s:12 m:8" label="所属部门" path="deptId" class="pr-24px">
|
||||
<DeptTreeSelect v-model:value="searchParams.deptId" placeholder="请选择部门" />
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span="24 s:12 m:10" label="创建时间" path="createTime" class="pr-24px">
|
||||
<NDatePicker
|
||||
ref="datePickerRef"
|
||||
v-model:formatted-value="dateRangeCreateTime"
|
||||
type="datetimerange"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
clearable
|
||||
@update:formatted-value="onDateRangeCreateTimeUpdate"
|
||||
/>
|
||||
</NFormItemGi>
|
||||
<NFormItemGi span="24 s:12 m:6" class="pr-24px" :show-feedback="false">
|
||||
<NSpace class="w-full" justify="end">
|
||||
<NButton @click="resetSearchParams">
|
||||
<NButton @click="reset">
|
||||
<template #icon>
|
||||
<icon-ic-round-refresh class="text-icon" />
|
||||
</template>
|
||||
|
@ -142,8 +142,12 @@ watch(visible, () => {
|
||||
<div class="flex-center">
|
||||
<NCheckbox v-model="data.updateSupport">{{ $t('common.updateExisting') }}</NCheckbox>
|
||||
</div>
|
||||
|
||||
<NAlert v-if="message" :title="$t('common.importResult')" :type="success ? 'success' : 'error'" :bordered="false">
|
||||
{{ message }}
|
||||
<NScrollbar class="max-h-200px">
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<span v-html="message" />
|
||||
</NScrollbar>
|
||||
</NAlert>
|
||||
<template #footer>
|
||||
<NSpace justify="end" :size="16">
|
||||
|
@ -65,14 +65,15 @@ function createDefaultModel(): Model {
|
||||
};
|
||||
}
|
||||
|
||||
type RuleKey = Extract<keyof Model, 'userName' | 'nickName' | 'password' | 'status' | 'phonenumber'>;
|
||||
type RuleKey = Extract<keyof Model, 'userName' | 'nickName' | 'password' | 'status' | 'phonenumber' | 'roleIds'>;
|
||||
|
||||
const rules: Record<RuleKey, App.Global.FormRule[]> = {
|
||||
userName: [createRequiredRule($t('page.system.user.form.userName.required'))],
|
||||
nickName: [createRequiredRule($t('page.system.user.form.nickName.required'))],
|
||||
password: [{ ...patternRules.pwd, required: props.operateType === 'add' }],
|
||||
phonenumber: [patternRules.phone],
|
||||
status: [createRequiredRule($t('page.system.user.form.status.required'))]
|
||||
status: [createRequiredRule($t('page.system.user.form.status.required'))],
|
||||
roleIds: [{ ...createRequiredRule('请选择角色'), type: 'array' }]
|
||||
};
|
||||
|
||||
async function getUserInfo() {
|
||||
|
Reference in New Issue
Block a user