3106d96ac7
iotlcm-admin-ui:管理前端(基于 Vben Admin 5.5.9 二次开发)。 - 天地图 API Key → YOUR_TIANDITU_KEY - OAuth 客户端 ID → your-client-id,store 加密密钥 → 提示自行替换 - Makefile 移除明文 registry 登录口令,镜像地址改 - appIcon 指向内网图床的链接 → /favicon.ico - 真实手机号 → 合法 11 位编造号(保留号段前 3 位 + 后 4 位) - 真实邮箱 → example.com(署名头内的上游作者邮箱保留) - 移除 CI 触发器 - 补 MIT LICENSE(含 Vben Admin 上游声明)+ README - 统一 LF 行尾并加 .gitattributes 上游 Vben Admin 的版权与许可声明完整保留(各源文件 @Author/@Copyright 头 + LICENSE)。
115 lines
2.9 KiB
TypeScript
115 lines
2.9 KiB
TypeScript
import type {
|
||
UploadChangeParam,
|
||
UploadFile,
|
||
UploadProps,
|
||
} from 'ant-design-vue';
|
||
|
||
import { defineComponent, h, ref, watch } from 'vue';
|
||
|
||
import { IconifyIcon } from '@vben/icons';
|
||
import { $t } from '@vben/locales';
|
||
import { isEmpty } from '@vben/utils';
|
||
|
||
import { Button, Upload } from '../antd';
|
||
import { previewImage } from './upload-preview';
|
||
|
||
/**
|
||
* Upload 未提供自定义插槽时,补齐项目统一的默认上传按钮。
|
||
*/
|
||
function createDefaultSlotsWithUpload(listType: string, placeholder: string) {
|
||
switch (listType) {
|
||
case 'picture-card': {
|
||
return {
|
||
default: () => placeholder,
|
||
};
|
||
}
|
||
default: {
|
||
return {
|
||
default: () =>
|
||
h(
|
||
Button,
|
||
{
|
||
icon: h(IconifyIcon, {
|
||
icon: 'ant-design:upload-outlined',
|
||
class: 'mb-1 size-4',
|
||
}),
|
||
},
|
||
() => placeholder,
|
||
),
|
||
};
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 适配 Ant Design Vue Upload 到 Vben Form:
|
||
* - 使用 modelValue 与表单值同步
|
||
* - 上传列表为空时回写 undefined
|
||
* - 内置图片预览,非图片文件直接打开地址
|
||
*/
|
||
export const withPreviewUpload = () => {
|
||
return defineComponent({
|
||
name: Upload.name,
|
||
emits: ['change', 'update:modelValue'],
|
||
setup: (
|
||
props: any,
|
||
{ attrs, slots, emit }: { attrs: any; emit: any; slots: any },
|
||
) => {
|
||
const previewVisible = ref<boolean>(false);
|
||
const placeholder = attrs?.placeholder || $t(`ui.placeholder.upload`);
|
||
const listType = attrs?.listType || attrs?.['list-type'] || 'text';
|
||
const fileList = ref<UploadProps['fileList']>(
|
||
attrs?.fileList || attrs?.['file-list'] || [],
|
||
);
|
||
|
||
const handleChange = async (event: UploadChangeParam) => {
|
||
fileList.value = event.fileList;
|
||
emit('change', event);
|
||
emit(
|
||
'update:modelValue',
|
||
event.fileList?.length ? fileList.value : undefined,
|
||
);
|
||
};
|
||
|
||
const handlePreview = async (file: UploadFile) => {
|
||
previewVisible.value = true;
|
||
await previewImage(file, previewVisible, fileList);
|
||
};
|
||
|
||
const renderUploadButton = (): any => {
|
||
const isDisabled = attrs.disabled;
|
||
|
||
// 禁用状态下只展示文件列表,不再渲染上传入口
|
||
if (isDisabled) {
|
||
return null;
|
||
}
|
||
|
||
return isEmpty(slots)
|
||
? createDefaultSlotsWithUpload(listType, placeholder)
|
||
: slots;
|
||
};
|
||
|
||
// 监听 formApi.setValues 等外部回填,保持 Upload 内部 fileList 同步
|
||
watch(
|
||
() => attrs.modelValue,
|
||
(res) => {
|
||
fileList.value = res;
|
||
},
|
||
);
|
||
|
||
return () =>
|
||
h(
|
||
Upload,
|
||
{
|
||
...props,
|
||
...attrs,
|
||
fileList: fileList.value,
|
||
onChange: handleChange,
|
||
onPreview: handlePreview,
|
||
},
|
||
renderUploadButton(),
|
||
);
|
||
},
|
||
});
|
||
};
|