diff --git a/templates/vue/api.ts.j2 b/templates/vue/api.ts.j2
index 54fb1a6..9df1d2a 100644
--- a/templates/vue/api.ts.j2
+++ b/templates/vue/api.ts.j2
@@ -9,46 +9,46 @@ import { useAccessStore } from '@vben/stores';
export namespace {{entity}}Api {
- const applicationConfig = useAppConfig(import.meta.env, import.meta.env.PROD);
- console.log('=== 接口域名 ===', applicationConfig.javaURL)
+ const applicationConfig = useAppConfig(import.meta.env, import.meta.env.PROD);
+ console.log('=== 接口域名 ===', applicationConfig.javaURL)
- /**
- * 分页查询
- */
- export function page(params: any) {
- return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/page', params,
- { headers: {'Content-Type': 'application/json', Token: useAccessStore().accessToken, version: '1.0.1'}});
- }
+ /**
+ * 分页查询
+ */
+ export function page(params: any) {
+ return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/page', params,
+ { headers: {'Content-Type': 'application/json', Token: useAccessStore().accessToken, version: '1.0.1'}});
+ }
- /**
- * 获取详情
- */
- export function get(id: number) {
- return requestClient.get(applicationConfig.javaURL+'/{{old_table}}/' + id);
- }
+ /**
+ * 获取详情
+ */
+ export function get(id: number) {
+ return requestClient.get(applicationConfig.javaURL+'/{{old_table}}/' + id);
+ }
- /**
- * 新增
- */
- export function add(data: any) {
- return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/add', data,
- { headers: {'Content-Type': 'application/json', Token: useAccessStore().accessToken, version: '1.0.1'}});
- }
+ /**
+ * 新增
+ */
+ export function add(data: any) {
+ return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/add', data,
+ { headers: {'Content-Type': 'application/json', Token: useAccessStore().accessToken, version: '1.0.1'}});
+ }
- /**
- * 修改
- */
- export function save(data: any) {
- return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/modify', data,
- { headers: {'Content-Type': 'application/json', Token: useAccessStore().accessToken, version: '1.0.1'}});
- }
+ /**
+ * 修改
+ */
+ export function save(data: any) {
+ return requestClient.post(applicationConfig.javaURL+'/{{old_table}}/modify', data,
+ { headers: {'Content-Type': 'application/json', Token: useAccessStore().accessToken, version: '1.0.1'}});
+ }
- /**
- * 删除
- */
- export function remove(id: number) {
- return requestClient.delete(applicationConfig.javaURL+'/{{old_table}}/' + id);
- }
+ /**
+ * 删除
+ */
+ export function remove(id: number) {
+ return requestClient.delete(applicationConfig.javaURL+'/{{old_table}}/' + id);
+ }
/**
* 枚举列表
@@ -58,12 +58,12 @@ export namespace {{entity}}Api {
{ headers: {'Content-Type': 'application/json', Token: useAccessStore().accessToken, version: '1.0.1'}});
}
- /**
- * 上传图片
- */
- export function upload(params: any) {
- return requestClient.post(applicationConfig.javaURL+'/file/up', params,
- { headers: {'Content-Type': 'multipart/form-data', Token: useAccessStore().accessToken, version: '1.0.1'}});
- }
+ /**
+ * 上传图片
+ */
+ export function upload(params: any) {
+ return requestClient.post(applicationConfig.javaURL+'/file/up', params,
+ { headers: {'Content-Type': 'multipart/form-data', Token: useAccessStore().accessToken, version: '1.0.1'}});
+ }
}
\ No newline at end of file
diff --git a/templates/vue/index.vue.j2 b/templates/vue/index.vue.j2
index 3b20dad..1949336 100644
--- a/templates/vue/index.vue.j2
+++ b/templates/vue/index.vue.j2
@@ -18,7 +18,6 @@ const API_BASE_URL = import.meta.env.VITE_GLOB_API_URL || '';
const currentRow = ref(null);
const isEdit = ref(false);
const modalTitle = ref('新增');
-const uploadVisible = ref(false);
const uploadFieldName = ref('');
const uploadImageUrl = ref('');
const uploadedUrl = ref(''); // 上传成功后返回的
@@ -33,14 +32,12 @@ const enumData = reactive({
});
//todo 枚举数据在查询里面不展示的配置
const hiddenColumns = ref(['fun_code', 'graduallyIntervalTime', 'funMsgTitle', 'funImg', 'createdAt', 'updatedBy', 'updatedAt', 'userPassword', 'userId', 'userSys', 'deletedFlag', "userFace"])
-const editFields = ['userId', 'createdAt', 'createdBy', 'updatedAt', 'updatedBy', 'deletedFlag'];
+const editFields = [{{editFields}}];
// ========== 判断是否是图片字段 ==========
-function isImageField(fieldName: string): boolean {
- const lowerName = fieldName.toLowerCase();
- return lowerName.includes('img') || lowerName.includes('face') || lowerName.includes('picture');
+function isImageField(field: string) {
+ return /img|face|picture/i.test(field);
}
-
// ========== 初始化枚举数据和查询表单 ==========
async function initEnumData() {
try {
@@ -111,7 +108,6 @@ onMounted(() => {
initEnumData();
});
-
// ========== 查询表单配置 (初始为空 schema) ==========
const [QueryForm, queryFormApi] = useVbenForm({
schema: [], // 初始化为空数组
@@ -134,9 +130,13 @@ watch(
{immediate: false}
);
-// 存储当前页码
-const currentPageRef = ref(1);
+
// ========== 表格配置 ==========
+function getFullUrl(url: string) {
+ if (!url) return '';
+ if (url.startsWith('http')) return url;
+ return `${API_BASE_URL}${url}`;
+}
const gridOptions = {
columns: [
...columns.map(col => {
@@ -149,126 +149,27 @@ const gridOptions = {
slots: {
default: ({row}: any) => {
const imgUrl = row[col.field];
-
- // 如果没有图片,显示提示文字
+ const handleClick = (e: Event) => {
+ e.stopPropagation();
+ currentRow.value = row;
+ isEdit.value = true;
+ openUploadDialog(col.field, imgUrl);
+ };
if (!imgUrl) {
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- gap: '8px',
- height: '50px',
- }
- }, [
- h('span', {
- style: {
- color: '#999',
- fontSize: '12px'
- }
- }, '无图片'),
- h('button', {
- onClick: (e: Event) => {
- e.stopPropagation();
- // 设置当前行数据
- currentRow.value = row;
- isEdit.value = true; // 设置为编辑模式
- openUploadDialog(col.field, imgUrl);
- },
- style: {
- padding: '4px 8px',
- fontSize: '12px',
- color: '#1890ff',
- backgroundColor: '#e6f7ff',
- border: '1px solid #1890ff',
- borderRadius: '4px',
- cursor: 'pointer',
- }
- }, '上传')
+ return h('div', { class: 'flex items-center justify-center gap-2 h-[50px]' }, [
+ h('span', { class: 'text-gray-400 text-xs' }, '无图片'),
+ h('button', { onClick: handleClick, class: 'text-blue-500 text-xs' }, '上传'),
]);
}
-
- // 判断是否是完整的 URL
- let fullUrl = imgUrl;
- if (!imgUrl.startsWith('http://') && !imgUrl.startsWith('https://')) {
- // 如果不是完整 URL,拼接基础 API 地址
- const apiURL = import.meta.env.VITE_GLOB_API_URL || '';
- fullUrl = `${apiURL}${imgUrl}`;
- }
-
- console.log('🖼️ 图片 URL:', fullUrl);
-
- // 返回图片组件和上传按钮
- try {
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- gap: '8px',
- }
- }, [
- h(Image, {
- src: fullUrl,
- height: 60,
- width: 80,
- preview: true,
- style: {
- borderRadius: '4px',
- objectFit: 'cover',
- cursor: 'pointer',
- boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
- },
- onError: () => {
- console.error('❌ 图片加载失败:', fullUrl);
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- height: '50px',
- backgroundColor: '#f5f5f5',
- borderRadius: '4px',
- color: '#999',
- fontSize: '12px'
- }
- }, '加载失败');
- }
- }),
- h('button', {
- onClick: (e: Event) => {
- e.stopPropagation();
- // 设置当前行数据
- currentRow.value = row;
- isEdit.value = true; // 设置为编辑模式
- openUploadDialog(col.field, imgUrl);
- },
- style: {
- padding: '4px 8px',
- fontSize: '12px',
- color: '#1890ff',
- backgroundColor: '#e6f7ff',
- border: '1px solid #1890ff',
- borderRadius: '4px',
- cursor: 'pointer',
- }
- }, '更换')
- ]);
- } catch (error) {
- console.error('❌ 图片渲染错误:', error);
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- height: '50px',
- backgroundColor: '#fffbe6',
- borderRadius: '4px',
- color: '#faad14',
- fontSize: '12px'
- }
- }, '渲染失败');
- }
+ return h('div', { class: 'flex items-center gap-2 justify-center' }, [
+ h(Image, {
+ src: getFullUrl(imgUrl),
+ width: 80,
+ height: 60,
+ preview: true,
+ }),
+ h('button', { onClick: handleClick, class: 'text-blue-500 text-xs' }, '更换'),
+ ]);
}
}
};
@@ -289,14 +190,6 @@ const gridOptions = {
try {
// 获取查询表单的值
const queryValues = await queryFormApi.getValues();
-
- console.log('=== 查询参数 ===', {
- pageNum: page?.currentPage || 1,
- pageSize: page?.pageSize || 10,
- currentPageRef: currentPageRef.value,
- ...queryValues,
- })
-
const res = await {{entity}}Api.page({
pageNum: page.currentPage || 1,
pageSize: page?.pageSize || 10,
@@ -343,6 +236,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
},
onConfirm: async () => {
+ let loadingMessage: any = null;
try {
const values = await formApi.validateAndSubmitForm();
if (!values) return;
@@ -357,22 +251,31 @@ const [Modal, modalApi] = useVbenModal({
...submitValues,
userBirthday: submitValues.userBirthday ? dayjs(submitValues.userBirthday).format('YYYY-MM-DD') : null,
};
+ // 显示 loading 提示
+ loadingMessage = message.loading(isEdit.value ? '保存中...' : '新增中...', 0);
if (isEdit.value && currentRow.value?.id) {
await {{entity}}Api.save({...finalSubmitValues, id: currentRow.value.id});
Object.assign(currentRow.value, finalSubmitValues);
modalApi.close();
gridApi.reloadRow(currentRow.value);
+ loadingMessage();
isEdit.value = false;
+ message.success('保存成功!');
} else {
await {{entity}}Api.add(finalSubmitValues);
// 新增才 reload(必须)
modalApi.close();
gridApi.reload();
formUploadUrls.value = {};
+ loadingMessage();
+ message.success('新增成功!');
}
} catch (error) {
console.error('保存失败:', error);
+ if (loadingMessage) {
+ loadingMessage();
+ }
}
},
onOpenChange(isOpen: boolean) {
@@ -399,6 +302,7 @@ const [UploadModal, uploadModalApi] = useVbenModal({
uploadedUrl.value = '';
},
onConfirm: async () => {
+ let loadingMessage: any = null;
console.log('=== 点击确认保存 ===', {
uploadedUrl: uploadedUrl.value,
isEdit: isEdit.value,
@@ -427,14 +331,15 @@ const [UploadModal, uploadModalApi] = useVbenModal({
id: currentRow.value.id
};
console.log('📤 提交保存数据:', submitData);
-
+ // 显示 loading 提示
+ loadingMessage = message.loading('保存图片中...', 0);
await {{entity}}Api.save(submitData);
message.success('保存成功!');
// 关闭弹窗并刷新表格
uploadModalApi.close();
// gridApi.reload();
-
+ loadingMessage()
// 重置状态
uploadFileList.value = [];
uploadedUrl.value = '';
@@ -452,6 +357,9 @@ const [UploadModal, uploadModalApi] = useVbenModal({
} catch (error: any) {
console.error('❌ 保存失败:', error);
+ if (loadingMessage) {
+ loadingMessage();
+ }
message.error(error?.message || '保存失败');
}
} else {
@@ -497,13 +405,7 @@ const getEditFormSchema = () => {
console.log('📦 新增表单内上传文件:', file);
try {
- const formData = new FormData();
- formData.append('file', file);
-
- // 调用上传 API
- const res = await {{entity}}Api.upload(formData);
- const resultUrl = res.result || res.message || res.url || res;
-
+ const resultUrl = await uploadFile(file);
console.log(item.fieldName + ' 新增表单内上传成功,URL:', resultUrl);
message.success('上传成功!');
@@ -545,6 +447,19 @@ const [Form, formApi] = useVbenForm({
},
})
+// ========== 上传文件 ==========
+
+async function uploadFile(file: File) {
+ let loadingMessage: any = null;
+ // 显示 loading 提示
+ loadingMessage = message.loading('图片上传中...', 0);
+ const formData = new FormData();
+ formData.append('file', file);
+ const res = await {{entity}}Api.upload(formData);
+ loadingMessage();
+ return res.result || res.message || res.url || res;
+}
+
// ========== 打开上传对话框 ==========
function openUploadDialog(fieldName: string, currentUrl: string) {
console.log('=== 打开上传对话框 ===', {
@@ -559,7 +474,6 @@ function openUploadDialog(fieldName: string, currentUrl: string) {
uploadImageUrl.value = currentUrl || '';
uploadedUrl.value = ''; // 重置上传后的 URL
uploadFileList.value = []; // 清空文件列表
- uploadVisible.value = true;
uploadModalApi.open();
}
@@ -575,17 +489,9 @@ async function handleCustomRequest(options: any) {
size: file.size,
lastModified: file.lastModified,
});
-
- const formData = new FormData();
- formData.append('file', file);
-
- // 调用上传 API
- const res = await {{entity}}Api.upload(formData);
- const resultUrl = res.result || res.message || res.url || res;
-
+ const resultUrl = await uploadFile(file);
console.log('✅ 上传成功,URL:', resultUrl);
message.success('上传成功!');
-
// 保存上传返回的 URL
uploadedUrl.value = resultUrl;
console.log('=== uploadedUrl 赋值后 ===', uploadedUrl.value);
@@ -608,20 +514,6 @@ async function handleCustomRequest(options: any) {
}
}
-// ========== 上传成功或失败后的处理
-function handleChange(info: any) {
- const {status} = info.file;
- console.log('📋 文件状态变化:', status, info.file);
-
- if (status === 'done') {
- console.log('✅ 上传完成响应:', info);
- } else if (status === 'error') {
- console.error('❌ 上传失败:', info);
- message.error(`${info.file.name} 上传失败`);
- }
-}
-
-
// ========== 打开新增弹窗 ==========
function handleAdd() {
isEdit.value = false;
@@ -679,7 +571,6 @@ function handleReset() {
queryFormApi.resetForm();
gridApi.reload();
}
-
@@ -728,7 +619,6 @@ function handleReset() {
-
当前图片:
diff --git a/vue-vben-admin/apps/web-antd/src/views/device/index.vue b/vue-vben-admin/apps/web-antd/src/views/device/index.vue
index b760d3e..b42154d 100644
--- a/vue-vben-admin/apps/web-antd/src/views/device/index.vue
+++ b/vue-vben-admin/apps/web-antd/src/views/device/index.vue
@@ -18,7 +18,6 @@ const API_BASE_URL = import.meta.env.VITE_GLOB_API_URL || '';
const currentRow = ref(null);
const isEdit = ref(false);
const modalTitle = ref('新增');
-const uploadVisible = ref(false);
const uploadFieldName = ref('');
const uploadImageUrl = ref('');
const uploadedUrl = ref(''); // 上传成功后返回的
@@ -36,11 +35,9 @@ const hiddenColumns = ref(['fun_code', 'graduallyIntervalTime', 'funMsgTitle', '
const editFields = ['userId', 'createdAt', 'createdBy', 'updatedAt', 'updatedBy', 'deletedFlag'];
// ========== 判断是否是图片字段 ==========
-function isImageField(fieldName: string): boolean {
- const lowerName = fieldName.toLowerCase();
- return lowerName.includes('img') || lowerName.includes('face') || lowerName.includes('picture');
+function isImageField(field: string) {
+ return /img|face|picture/i.test(field);
}
-
// ========== 初始化枚举数据和查询表单 ==========
async function initEnumData() {
try {
@@ -111,7 +108,6 @@ onMounted(() => {
initEnumData();
});
-
// ========== 查询表单配置 (初始为空 schema) ==========
const [QueryForm, queryFormApi] = useVbenForm({
schema: [], // 初始化为空数组
@@ -137,6 +133,11 @@ watch(
// 存储当前页码
const currentPageRef = ref(1);
// ========== 表格配置 ==========
+function getFullUrl(url: string) {
+ if (!url) return '';
+ if (url.startsWith('http')) return url;
+ return `${API_BASE_URL}${url}`;
+}
const gridOptions = {
columns: [
...columns.map(col => {
@@ -149,126 +150,27 @@ const gridOptions = {
slots: {
default: ({row}: any) => {
const imgUrl = row[col.field];
-
- // 如果没有图片,显示提示文字
+ const handleClick = (e: Event) => {
+ e.stopPropagation();
+ currentRow.value = row;
+ isEdit.value = true;
+ openUploadDialog(col.field, imgUrl);
+ };
if (!imgUrl) {
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- gap: '8px',
- height: '50px',
- }
- }, [
- h('span', {
- style: {
- color: '#999',
- fontSize: '12px'
- }
- }, '无图片'),
- h('button', {
- onClick: (e: Event) => {
- e.stopPropagation();
- // 设置当前行数据
- currentRow.value = row;
- isEdit.value = true; // 设置为编辑模式
- openUploadDialog(col.field, imgUrl);
- },
- style: {
- padding: '4px 8px',
- fontSize: '12px',
- color: '#1890ff',
- backgroundColor: '#e6f7ff',
- border: '1px solid #1890ff',
- borderRadius: '4px',
- cursor: 'pointer',
- }
- }, '上传')
- ]);
- }
-
- // 判断是否是完整的 URL
- let fullUrl = imgUrl;
- if (!imgUrl.startsWith('http://') && !imgUrl.startsWith('https://')) {
- // 如果不是完整 URL,拼接基础 API 地址
- const apiURL = import.meta.env.VITE_GLOB_API_URL || '';
- fullUrl = `${apiURL}${imgUrl}`;
- }
-
- console.log('🖼️ 图片 URL:', fullUrl);
-
- // 返回图片组件和上传按钮
- try {
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- gap: '8px',
- }
- }, [
- h(Image, {
- src: fullUrl,
- height: 60,
- width: 80,
- preview: true,
- style: {
- borderRadius: '4px',
- objectFit: 'cover',
- cursor: 'pointer',
- boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
- },
- onError: () => {
- console.error('❌ 图片加载失败:', fullUrl);
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- height: '50px',
- backgroundColor: '#f5f5f5',
- borderRadius: '4px',
- color: '#999',
- fontSize: '12px'
- }
- }, '加载失败');
- }
- }),
- h('button', {
- onClick: (e: Event) => {
- e.stopPropagation();
- // 设置当前行数据
- currentRow.value = row;
- isEdit.value = true; // 设置为编辑模式
- openUploadDialog(col.field, imgUrl);
- },
- style: {
- padding: '4px 8px',
- fontSize: '12px',
- color: '#1890ff',
- backgroundColor: '#e6f7ff',
- border: '1px solid #1890ff',
- borderRadius: '4px',
- cursor: 'pointer',
- }
- }, '更换')
+ return h('div', { class: 'flex items-center justify-center gap-2 h-[50px]' }, [
+ h('span', { class: 'text-gray-400 text-xs' }, '无图片'),
+ h('button', { onClick: handleClick, class: 'text-blue-500 text-xs' }, '上传'),
]);
- } catch (error) {
- console.error('❌ 图片渲染错误:', error);
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- height: '50px',
- backgroundColor: '#fffbe6',
- borderRadius: '4px',
- color: '#faad14',
- fontSize: '12px'
- }
- }, '渲染失败');
}
+ return h('div', { class: 'flex items-center gap-2 justify-center' }, [
+ h(Image, {
+ src: getFullUrl(imgUrl),
+ width: 80,
+ height: 60,
+ preview: true,
+ }),
+ h('button', { onClick: handleClick, class: 'text-blue-500 text-xs' }, '更换'),
+ ]);
}
}
};
@@ -343,6 +245,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
},
onConfirm: async () => {
+ let loadingMessage: any = null;
try {
const values = await formApi.validateAndSubmitForm();
if (!values) return;
@@ -357,22 +260,31 @@ const [Modal, modalApi] = useVbenModal({
...submitValues,
userBirthday: submitValues.userBirthday ? dayjs(submitValues.userBirthday).format('YYYY-MM-DD') : null,
};
+ // 显示 loading 提示
+ loadingMessage = message.loading(isEdit.value ? '保存中...' : '新增中...', 0);
if (isEdit.value && currentRow.value?.id) {
await deviceApi.save({...finalSubmitValues, id: currentRow.value.id});
Object.assign(currentRow.value, finalSubmitValues);
modalApi.close();
gridApi.reloadRow(currentRow.value);
+ loadingMessage();
isEdit.value = false;
+ message.success('保存成功!');
} else {
await deviceApi.add(finalSubmitValues);
// 新增才 reload(必须)
modalApi.close();
gridApi.reload();
formUploadUrls.value = {};
+ loadingMessage();
+ message.success('新增成功!');
}
} catch (error) {
console.error('保存失败:', error);
+ if (loadingMessage) {
+ loadingMessage();
+ }
}
},
onOpenChange(isOpen: boolean) {
@@ -399,6 +311,7 @@ const [UploadModal, uploadModalApi] = useVbenModal({
uploadedUrl.value = '';
},
onConfirm: async () => {
+ let loadingMessage: any = null;
console.log('=== 点击确认保存 ===', {
uploadedUrl: uploadedUrl.value,
isEdit: isEdit.value,
@@ -427,14 +340,15 @@ const [UploadModal, uploadModalApi] = useVbenModal({
id: currentRow.value.id
};
console.log('📤 提交保存数据:', submitData);
-
+ // 显示 loading 提示
+ loadingMessage = message.loading('保存图片中...', 0);
await deviceApi.save(submitData);
message.success('保存成功!');
// 关闭弹窗并刷新表格
uploadModalApi.close();
// gridApi.reload();
-
+ loadingMessage()
// 重置状态
uploadFileList.value = [];
uploadedUrl.value = '';
@@ -452,6 +366,9 @@ const [UploadModal, uploadModalApi] = useVbenModal({
} catch (error: any) {
console.error('❌ 保存失败:', error);
+ if (loadingMessage) {
+ loadingMessage();
+ }
message.error(error?.message || '保存失败');
}
} else {
@@ -497,13 +414,7 @@ const getEditFormSchema = () => {
console.log('📦 新增表单内上传文件:', file);
try {
- const formData = new FormData();
- formData.append('file', file);
-
- // 调用上传 API
- const res = await deviceApi.upload(formData);
- const resultUrl = res.result || res.message || res.url || res;
-
+ const resultUrl = await uploadFile(file);
console.log(item.fieldName + ' 新增表单内上传成功,URL:', resultUrl);
message.success('上传成功!');
@@ -545,6 +456,19 @@ const [Form, formApi] = useVbenForm({
},
})
+// ========== 上传文件 ==========
+
+async function uploadFile(file: File) {
+ let loadingMessage: any = null;
+ // 显示 loading 提示
+ loadingMessage = message.loading('图片上传中...', 0);
+ const formData = new FormData();
+ formData.append('file', file);
+ const res = await deviceApi.upload(formData);
+ loadingMessage();
+ return res.result || res.message || res.url || res;
+}
+
// ========== 打开上传对话框 ==========
function openUploadDialog(fieldName: string, currentUrl: string) {
console.log('=== 打开上传对话框 ===', {
@@ -559,7 +483,6 @@ function openUploadDialog(fieldName: string, currentUrl: string) {
uploadImageUrl.value = currentUrl || '';
uploadedUrl.value = ''; // 重置上传后的 URL
uploadFileList.value = []; // 清空文件列表
- uploadVisible.value = true;
uploadModalApi.open();
}
@@ -575,17 +498,9 @@ async function handleCustomRequest(options: any) {
size: file.size,
lastModified: file.lastModified,
});
-
- const formData = new FormData();
- formData.append('file', file);
-
- // 调用上传 API
- const res = await deviceApi.upload(formData);
- const resultUrl = res.result || res.message || res.url || res;
-
+ const resultUrl = await uploadFile(file);
console.log('✅ 上传成功,URL:', resultUrl);
message.success('上传成功!');
-
// 保存上传返回的 URL
uploadedUrl.value = resultUrl;
console.log('=== uploadedUrl 赋值后 ===', uploadedUrl.value);
@@ -608,20 +523,6 @@ async function handleCustomRequest(options: any) {
}
}
-// ========== 上传成功或失败后的处理
-function handleChange(info: any) {
- const {status} = info.file;
- console.log('📋 文件状态变化:', status, info.file);
-
- if (status === 'done') {
- console.log('✅ 上传完成响应:', info);
- } else if (status === 'error') {
- console.error('❌ 上传失败:', info);
- message.error(`${info.file.name} 上传失败`);
- }
-}
-
-
// ========== 打开新增弹窗 ==========
function handleAdd() {
isEdit.value = false;
@@ -679,7 +580,6 @@ function handleReset() {
queryFormApi.resetForm();
gridApi.reload();
}
-
@@ -728,7 +628,6 @@ function handleReset() {
-
当前图片:
diff --git a/vue-vben-admin/apps/web-antd/src/views/fun/index.vue b/vue-vben-admin/apps/web-antd/src/views/fun/index.vue
index 9cda98c..779a556 100644
--- a/vue-vben-admin/apps/web-antd/src/views/fun/index.vue
+++ b/vue-vben-admin/apps/web-antd/src/views/fun/index.vue
@@ -18,7 +18,6 @@ const API_BASE_URL = import.meta.env.VITE_GLOB_API_URL || '';
const currentRow = ref(null);
const isEdit = ref(false);
const modalTitle = ref('新增');
-const uploadVisible = ref(false);
const uploadFieldName = ref('');
const uploadImageUrl = ref('');
const uploadedUrl = ref(''); // 上传成功后返回的
@@ -33,14 +32,12 @@ const enumData = reactive({
});
//todo 枚举数据在查询里面不展示的配置
const hiddenColumns = ref(['fun_code', 'graduallyIntervalTime', 'funMsgTitle', 'funImg', 'createdAt', 'updatedBy', 'updatedAt', 'userPassword', 'userId', 'userSys', 'deletedFlag', "userFace"])
-const editFields = ['userId', 'createdAt', 'createdBy', 'updatedAt', 'updatedBy', 'deletedFlag'];
+const editFields = ['userId','createdAt','createdBy','updatedAt','updatedBy','deletedFlag'];
// ========== 判断是否是图片字段 ==========
-function isImageField(fieldName: string): boolean {
- const lowerName = fieldName.toLowerCase();
- return lowerName.includes('img') || lowerName.includes('face') || lowerName.includes('picture');
+function isImageField(field: string) {
+ return /img|face|picture/i.test(field);
}
-
// ========== 初始化枚举数据和查询表单 ==========
async function initEnumData() {
try {
@@ -111,7 +108,6 @@ onMounted(() => {
initEnumData();
});
-
// ========== 查询表单配置 (初始为空 schema) ==========
const [QueryForm, queryFormApi] = useVbenForm({
schema: [], // 初始化为空数组
@@ -134,9 +130,13 @@ watch(
{immediate: false}
);
-// 存储当前页码
-const currentPageRef = ref(1);
+
// ========== 表格配置 ==========
+function getFullUrl(url: string) {
+ if (!url) return '';
+ if (url.startsWith('http')) return url;
+ return `${API_BASE_URL}${url}`;
+}
const gridOptions = {
columns: [
...columns.map(col => {
@@ -149,126 +149,27 @@ const gridOptions = {
slots: {
default: ({row}: any) => {
const imgUrl = row[col.field];
-
- // 如果没有图片,显示提示文字
+ const handleClick = (e: Event) => {
+ e.stopPropagation();
+ currentRow.value = row;
+ isEdit.value = true;
+ openUploadDialog(col.field, imgUrl);
+ };
if (!imgUrl) {
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- gap: '8px',
- height: '50px',
- }
- }, [
- h('span', {
- style: {
- color: '#999',
- fontSize: '12px'
- }
- }, '无图片'),
- h('button', {
- onClick: (e: Event) => {
- e.stopPropagation();
- // 设置当前行数据
- currentRow.value = row;
- isEdit.value = true; // 设置为编辑模式
- openUploadDialog(col.field, imgUrl);
- },
- style: {
- padding: '4px 8px',
- fontSize: '12px',
- color: '#1890ff',
- backgroundColor: '#e6f7ff',
- border: '1px solid #1890ff',
- borderRadius: '4px',
- cursor: 'pointer',
- }
- }, '上传')
+ return h('div', { class: 'flex items-center justify-center gap-2 h-[50px]' }, [
+ h('span', { class: 'text-gray-400 text-xs' }, '无图片'),
+ h('button', { onClick: handleClick, class: 'text-blue-500 text-xs' }, '上传'),
]);
}
-
- // 判断是否是完整的 URL
- let fullUrl = imgUrl;
- if (!imgUrl.startsWith('http://') && !imgUrl.startsWith('https://')) {
- // 如果不是完整 URL,拼接基础 API 地址
- const apiURL = import.meta.env.VITE_GLOB_API_URL || '';
- fullUrl = `${apiURL}${imgUrl}`;
- }
-
- console.log('🖼️ 图片 URL:', fullUrl);
-
- // 返回图片组件和上传按钮
- try {
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- gap: '8px',
- }
- }, [
- h(Image, {
- src: fullUrl,
- height: 60,
- width: 80,
- preview: true,
- style: {
- borderRadius: '4px',
- objectFit: 'cover',
- cursor: 'pointer',
- boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
- },
- onError: () => {
- console.error('❌ 图片加载失败:', fullUrl);
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- height: '50px',
- backgroundColor: '#f5f5f5',
- borderRadius: '4px',
- color: '#999',
- fontSize: '12px'
- }
- }, '加载失败');
- }
- }),
- h('button', {
- onClick: (e: Event) => {
- e.stopPropagation();
- // 设置当前行数据
- currentRow.value = row;
- isEdit.value = true; // 设置为编辑模式
- openUploadDialog(col.field, imgUrl);
- },
- style: {
- padding: '4px 8px',
- fontSize: '12px',
- color: '#1890ff',
- backgroundColor: '#e6f7ff',
- border: '1px solid #1890ff',
- borderRadius: '4px',
- cursor: 'pointer',
- }
- }, '更换')
- ]);
- } catch (error) {
- console.error('❌ 图片渲染错误:', error);
- return h('div', {
- style: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- height: '50px',
- backgroundColor: '#fffbe6',
- borderRadius: '4px',
- color: '#faad14',
- fontSize: '12px'
- }
- }, '渲染失败');
- }
+ return h('div', { class: 'flex items-center gap-2 justify-center' }, [
+ h(Image, {
+ src: getFullUrl(imgUrl),
+ width: 80,
+ height: 60,
+ preview: true,
+ }),
+ h('button', { onClick: handleClick, class: 'text-blue-500 text-xs' }, '更换'),
+ ]);
}
}
};
@@ -289,14 +190,6 @@ const gridOptions = {
try {
// 获取查询表单的值
const queryValues = await queryFormApi.getValues();
-
- console.log('=== 查询参数 ===', {
- pageNum: page?.currentPage || 1,
- pageSize: page?.pageSize || 10,
- currentPageRef: currentPageRef.value,
- ...queryValues,
- })
-
const res = await funApi.page({
pageNum: page.currentPage || 1,
pageSize: page?.pageSize || 10,
@@ -343,6 +236,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
},
onConfirm: async () => {
+ let loadingMessage: any = null;
try {
const values = await formApi.validateAndSubmitForm();
if (!values) return;
@@ -357,22 +251,31 @@ const [Modal, modalApi] = useVbenModal({
...submitValues,
userBirthday: submitValues.userBirthday ? dayjs(submitValues.userBirthday).format('YYYY-MM-DD') : null,
};
+ // 显示 loading 提示
+ loadingMessage = message.loading(isEdit.value ? '保存中...' : '新增中...', 0);
if (isEdit.value && currentRow.value?.id) {
await funApi.save({...finalSubmitValues, id: currentRow.value.id});
Object.assign(currentRow.value, finalSubmitValues);
modalApi.close();
gridApi.reloadRow(currentRow.value);
+ loadingMessage();
isEdit.value = false;
+ message.success('保存成功!');
} else {
await funApi.add(finalSubmitValues);
// 新增才 reload(必须)
modalApi.close();
gridApi.reload();
formUploadUrls.value = {};
+ loadingMessage();
+ message.success('新增成功!');
}
} catch (error) {
console.error('保存失败:', error);
+ if (loadingMessage) {
+ loadingMessage();
+ }
}
},
onOpenChange(isOpen: boolean) {
@@ -399,6 +302,7 @@ const [UploadModal, uploadModalApi] = useVbenModal({
uploadedUrl.value = '';
},
onConfirm: async () => {
+ let loadingMessage: any = null;
console.log('=== 点击确认保存 ===', {
uploadedUrl: uploadedUrl.value,
isEdit: isEdit.value,
@@ -427,14 +331,15 @@ const [UploadModal, uploadModalApi] = useVbenModal({
id: currentRow.value.id
};
console.log('📤 提交保存数据:', submitData);
-
+ // 显示 loading 提示
+ loadingMessage = message.loading('保存图片中...', 0);
await funApi.save(submitData);
message.success('保存成功!');
// 关闭弹窗并刷新表格
uploadModalApi.close();
// gridApi.reload();
-
+ loadingMessage()
// 重置状态
uploadFileList.value = [];
uploadedUrl.value = '';
@@ -452,6 +357,9 @@ const [UploadModal, uploadModalApi] = useVbenModal({
} catch (error: any) {
console.error('❌ 保存失败:', error);
+ if (loadingMessage) {
+ loadingMessage();
+ }
message.error(error?.message || '保存失败');
}
} else {
@@ -497,13 +405,7 @@ const getEditFormSchema = () => {
console.log('📦 新增表单内上传文件:', file);
try {
- const formData = new FormData();
- formData.append('file', file);
-
- // 调用上传 API
- const res = await funApi.upload(formData);
- const resultUrl = res.result || res.message || res.url || res;
-
+ const resultUrl = await uploadFile(file);
console.log(item.fieldName + ' 新增表单内上传成功,URL:', resultUrl);
message.success('上传成功!');
@@ -545,6 +447,19 @@ const [Form, formApi] = useVbenForm({
},
})
+// ========== 上传文件 ==========
+
+async function uploadFile(file: File) {
+ let loadingMessage: any = null;
+ // 显示 loading 提示
+ loadingMessage = message.loading('图片上传中...', 0);
+ const formData = new FormData();
+ formData.append('file', file);
+ const res = await funApi.upload(formData);
+ loadingMessage();
+ return res.result || res.message || res.url || res;
+}
+
// ========== 打开上传对话框 ==========
function openUploadDialog(fieldName: string, currentUrl: string) {
console.log('=== 打开上传对话框 ===', {
@@ -559,7 +474,6 @@ function openUploadDialog(fieldName: string, currentUrl: string) {
uploadImageUrl.value = currentUrl || '';
uploadedUrl.value = ''; // 重置上传后的 URL
uploadFileList.value = []; // 清空文件列表
- uploadVisible.value = true;
uploadModalApi.open();
}
@@ -575,17 +489,9 @@ async function handleCustomRequest(options: any) {
size: file.size,
lastModified: file.lastModified,
});
-
- const formData = new FormData();
- formData.append('file', file);
-
- // 调用上传 API
- const res = await funApi.upload(formData);
- const resultUrl = res.result || res.message || res.url || res;
-
+ const resultUrl = await uploadFile(file);
console.log('✅ 上传成功,URL:', resultUrl);
message.success('上传成功!');
-
// 保存上传返回的 URL
uploadedUrl.value = resultUrl;
console.log('=== uploadedUrl 赋值后 ===', uploadedUrl.value);
@@ -608,20 +514,6 @@ async function handleCustomRequest(options: any) {
}
}
-// ========== 上传成功或失败后的处理
-function handleChange(info: any) {
- const {status} = info.file;
- console.log('📋 文件状态变化:', status, info.file);
-
- if (status === 'done') {
- console.log('✅ 上传完成响应:', info);
- } else if (status === 'error') {
- console.error('❌ 上传失败:', info);
- message.error(`${info.file.name} 上传失败`);
- }
-}
-
-
// ========== 打开新增弹窗 ==========
function handleAdd() {
isEdit.value = false;
@@ -679,7 +571,6 @@ function handleReset() {
queryFormApi.resetForm();
gridApi.reload();
}
-
@@ -728,7 +619,6 @@ function handleReset() {
-