forked from Qi/Oroqen-Manage
传承人卡片优化
This commit is contained in:
parent
1fe792a910
commit
07420c01af
127
src/api/oroqen/OroqenHeritageProject.ts
Normal file
127
src/api/oroqen/OroqenHeritageProject.ts
Normal file
@ -0,0 +1,127 @@
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { createConfirm } = useMessage();
|
||||
|
||||
enum Api {
|
||||
list = '/oroqen/heritageProject/list',
|
||||
save = '/oroqen/heritageProject/add',
|
||||
edit = '/oroqen/heritageProject/edit',
|
||||
deleteOne = '/oroqen/heritageProject/delete',
|
||||
deleteBatch = '/oroqen/heritageProject/deleteBatch',
|
||||
importExcel = '/oroqen/heritageProject/importExcel',
|
||||
exportXls = '/oroqen/heritageProject/exportXls',
|
||||
queryById = '/oroqen/heritageProject/queryById',
|
||||
recommended = '/oroqen/heritageProject/recommended',
|
||||
byLevel = '/oroqen/heritageProject/byLevel',
|
||||
byCategory = '/oroqen/heritageProject/byCategory',
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出api
|
||||
*/
|
||||
export const getExportUrl = Api.exportXls;
|
||||
|
||||
/**
|
||||
* 导入api
|
||||
*/
|
||||
export const getImportUrl = Api.importExcel;
|
||||
|
||||
/**
|
||||
* 列表接口
|
||||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* 删除单个
|
||||
*/
|
||||
export const deleteOne = (params, handleSuccess) => {
|
||||
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*/
|
||||
export const batchDelete = (params, handleSuccess) => {
|
||||
createConfirm({
|
||||
iconType: 'warning',
|
||||
title: '确认删除',
|
||||
content: '是否删除选中数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
return defHttp.delete({ url: Api.deleteBatch, data: params }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存或者更新
|
||||
*/
|
||||
export const saveOrUpdate = (params, isUpdate) => {
|
||||
let url = isUpdate ? Api.edit : Api.save;
|
||||
return defHttp.post({ url: url, params });
|
||||
};
|
||||
|
||||
/**
|
||||
* 通过ID查询
|
||||
*/
|
||||
export const queryById = (id) => {
|
||||
return defHttp.get({ url: Api.queryById, params: { id } });
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取非遗项目选项列表(用于下拉选择)
|
||||
*/
|
||||
export const getHeritageProjectOptions = () => {
|
||||
return defHttp.get({
|
||||
url: Api.list,
|
||||
params: {
|
||||
pageNo: 1,
|
||||
pageSize: 1000,
|
||||
status: 1 // 只获取启用状态的项目
|
||||
}
|
||||
}).then(res => {
|
||||
console.log('非遗项目API响应:', res);
|
||||
// 修正数据结构判断,直接使用 res.records
|
||||
if (res && res.records && Array.isArray(res.records)) {
|
||||
const options = res.records.map(item => ({
|
||||
label: item.projectName, // 使用 projectName 字段
|
||||
value: item.projectName, // 使用项目名称作为值
|
||||
key: item.id
|
||||
}));
|
||||
console.log('非遗项目选项数据:', options);
|
||||
return options;
|
||||
}
|
||||
console.log('非遗项目数据为空或格式错误');
|
||||
return [];
|
||||
}).catch(error => {
|
||||
console.error('获取非遗项目数据失败:', error);
|
||||
return [];
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取推荐项目列表
|
||||
*/
|
||||
export const getRecommendedProjects = () => {
|
||||
return defHttp.get({ url: Api.recommended });
|
||||
};
|
||||
|
||||
/**
|
||||
* 按级别获取项目列表
|
||||
*/
|
||||
export const getProjectsByLevel = (level) => {
|
||||
return defHttp.get({ url: Api.byLevel, params: { level } });
|
||||
};
|
||||
|
||||
/**
|
||||
* 按类别获取项目列表
|
||||
*/
|
||||
export const getProjectsByCategory = (category) => {
|
||||
return defHttp.get({ url: Api.byCategory, params: { category } });
|
||||
};
|
@ -340,6 +340,18 @@ export const formSchema: FormSchema[] = [
|
||||
showCount: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '制作流程',
|
||||
field: 'craftProcess',
|
||||
component: 'InputTextArea',
|
||||
componentProps: {
|
||||
placeholder: '请输入制作流程,多个步骤用逗号分隔,或输入JSON数组格式',
|
||||
rows: 4,
|
||||
maxlength: 2000,
|
||||
showCount: true,
|
||||
},
|
||||
helpMessage: '可以输入逗号分隔的步骤(如:步骤1,步骤2,步骤3)或JSON数组格式(如:["步骤1","步骤2","步骤3"])',
|
||||
},
|
||||
{
|
||||
label: '传承价值',
|
||||
field: 'value',
|
||||
@ -573,20 +585,21 @@ export const superQuerySchema = {
|
||||
fullDescription: {title: '详细描述',order: 7,view: 'textarea', type: 'string',},
|
||||
history: {title: '历史渊源',order: 8,view: 'textarea', type: 'string',},
|
||||
features: {title: '技艺特点',order: 9,view: 'textarea', type: 'string',},
|
||||
value: {title: '传承价值',order: 10,view: 'textarea', type: 'string',},
|
||||
coverImage: {title: '封面图片',order: 11,view: 'text', type: 'string',},
|
||||
images: {title: '图片集',order: 12,view: 'textarea', type: 'string',},
|
||||
videoUrl: {title: '视频链接',order: 13,view: 'text', type: 'string',},
|
||||
audioUrl: {title: '音频链接',order: 14,view: 'text', type: 'string',},
|
||||
tags: {title: '标签',order: 15,view: 'text', type: 'string',},
|
||||
inheritorIds: {title: '关联传承人ID',order: 16,view: 'textarea', type: 'string',},
|
||||
protectionUnit: {title: '保护单位',order: 17,view: 'text', type: 'string',},
|
||||
protectionMeasures: {title: '保护措施',order: 18,view: 'text', type: 'string',},
|
||||
currentStatus: {title: '保护现状',order: 19,view: 'text', type: 'string',},
|
||||
isRecommended: {title: '是否推荐',order: 20,view: 'number', type: 'number',},
|
||||
viewCount: {title: '浏览次数',order: 21,view: 'number', type: 'number',},
|
||||
likeCount: {title: '点赞次数',order: 22,view: 'number', type: 'number',},
|
||||
status: {title: '状态',order: 23,view: 'number', type: 'number',},
|
||||
craftProcess: {title: '制作流程',order: 10,view: 'textarea', type: 'string',},
|
||||
value: {title: '传承价值',order: 11,view: 'textarea', type: 'string',},
|
||||
coverImage: {title: '封面图片',order: 12,view: 'text', type: 'string',},
|
||||
images: {title: '图片集',order: 13,view: 'textarea', type: 'string',},
|
||||
videoUrl: {title: '视频链接',order: 14,view: 'text', type: 'string',},
|
||||
audioUrl: {title: '音频链接',order: 15,view: 'text', type: 'string',},
|
||||
tags: {title: '标签',order: 16,view: 'text', type: 'string',},
|
||||
inheritorIds: {title: '关联传承人ID',order: 17,view: 'textarea', type: 'string',},
|
||||
protectionUnit: {title: '保护单位',order: 18,view: 'text', type: 'string',},
|
||||
protectionMeasures: {title: '保护措施',order: 19,view: 'text', type: 'string',},
|
||||
currentStatus: {title: '保护现状',order: 20,view: 'text', type: 'string',},
|
||||
isRecommended: {title: '是否推荐',order: 21,view: 'number', type: 'number',},
|
||||
viewCount: {title: '浏览次数',order: 22,view: 'number', type: 'number',},
|
||||
likeCount: {title: '点赞次数',order: 23,view: 'number', type: 'number',},
|
||||
status: {title: '状态',order: 24,view: 'number', type: 'number',},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,7 @@ import { h } from 'vue';
|
||||
import { Image, Tag } from 'ant-design-vue';
|
||||
import { render } from '/@/utils/common/renderUtils';
|
||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||
import { getHeritageProjectOptions } from '/@/api/oroqen/OroqenHeritageProject';
|
||||
|
||||
//列表数据
|
||||
export const columns: BasicColumn[] = [
|
||||
@ -63,10 +64,19 @@ export const columns: BasicColumn[] = [
|
||||
},
|
||||
{
|
||||
title: '传承项目',
|
||||
dataIndex: 'heritageProject',
|
||||
dataIndex: 'heritageSkills',
|
||||
width: 150,
|
||||
align: 'left',
|
||||
ellipsis: true,
|
||||
customRender: ({ text }) => {
|
||||
if (!text) return '-';
|
||||
// 如果是数组格式的项目ID,需要转换为项目名称显示
|
||||
// 这里暂时直接显示,后续可以通过API获取项目名称
|
||||
if (Array.isArray(text)) {
|
||||
return text.join(', ');
|
||||
}
|
||||
return text;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '传承级别',
|
||||
@ -227,11 +237,40 @@ export const formSchema: FormSchema[] = [
|
||||
},
|
||||
{
|
||||
label: '传承项目',
|
||||
field: 'heritageProject',
|
||||
component: 'Input',
|
||||
required: true,
|
||||
field: 'heritageSkills',
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
placeholder: '请输入传承项目',
|
||||
api: getHeritageProjectOptions,
|
||||
params: {},
|
||||
resultField: '',
|
||||
labelField: 'label',
|
||||
valueField: 'value',
|
||||
placeholder: '请选择传承项目',
|
||||
mode: 'multiple',
|
||||
showSearch: true,
|
||||
filterOption: (input: string, option: any) => {
|
||||
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
|
||||
},
|
||||
},
|
||||
// 数据转换:数据库存储为逗号分隔的字符串,前端显示为数组
|
||||
dynamicRules: ({ model, schema }) => {
|
||||
return [];
|
||||
},
|
||||
// 表单值转换
|
||||
valueFormat: (value) => {
|
||||
// 从数据库读取时:字符串转数组
|
||||
if (typeof value === 'string' && value) {
|
||||
return value.split(',').filter(v => v.trim());
|
||||
}
|
||||
return value || [];
|
||||
},
|
||||
// 提交时转换
|
||||
valueTransform: (value) => {
|
||||
// 提交到数据库时:数组转字符串
|
||||
if (Array.isArray(value)) {
|
||||
return value.join(',');
|
||||
}
|
||||
return value || '';
|
||||
},
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
@ -390,6 +429,46 @@ export const formSchema: FormSchema[] = [
|
||||
}, 100);
|
||||
},
|
||||
},
|
||||
colProps: { span: 24 },
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
{
|
||||
label: '作品图片',
|
||||
field: 'workImages',
|
||||
component: 'JUpload',
|
||||
componentProps: {
|
||||
fileType: 'image',
|
||||
maxCount: 10,
|
||||
maxSize: 5,
|
||||
bizPath: 'inheritor/works',
|
||||
customRequest: (options) => {
|
||||
// 验证文件类型和大小
|
||||
const { file } = options;
|
||||
const isImage = file.type.startsWith('image/');
|
||||
if (!isImage) {
|
||||
console.error('只能上传图片文件!');
|
||||
return;
|
||||
}
|
||||
const isLt5M = file.size / 1024 / 1024 < 5;
|
||||
if (!isLt5M) {
|
||||
console.error('图片大小不能超过5MB!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建本地预览URL
|
||||
const localUrl = URL.createObjectURL(file);
|
||||
|
||||
// 直接设置文件的url为本地预览URL
|
||||
file.url = localUrl;
|
||||
|
||||
// 模拟上传成功响应,返回blob URL作为message
|
||||
setTimeout(() => {
|
||||
options.onSuccess({
|
||||
success: true,
|
||||
message: localUrl, // 返回blob URL
|
||||
}, file);
|
||||
}, 100);
|
||||
},
|
||||
},
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
];
|
@ -37,10 +37,14 @@
|
||||
isDetail.value = data?.mode === 'detail';
|
||||
|
||||
if (unref(isUpdate)) {
|
||||
// 处理传承项目字段的数据转换
|
||||
const record = { ...data.record };
|
||||
if (record.heritageSkills && typeof record.heritageSkills === 'string') {
|
||||
record.heritageSkills = record.heritageSkills.split(',').filter(v => v.trim());
|
||||
}
|
||||
|
||||
//表单赋值
|
||||
await setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
await setFieldsValue(record);
|
||||
}
|
||||
// 详情模式时禁用整个表单
|
||||
setProps({ disabled: unref(isDetail) });
|
||||
@ -56,6 +60,11 @@
|
||||
let values = await validate();
|
||||
console.log('表单验证通过,提交数据:', values);
|
||||
|
||||
// 处理传承项目字段的数据转换
|
||||
if (values.heritageSkills && Array.isArray(values.heritageSkills)) {
|
||||
values.heritageSkills = values.heritageSkills.join(',');
|
||||
}
|
||||
|
||||
// 预处理日期数据
|
||||
changeDateValue(values);
|
||||
setModalProps({ confirmLoading: true });
|
||||
@ -108,8 +117,8 @@
|
||||
console.log('开始处理文件上传,表单数据:', formData);
|
||||
|
||||
try {
|
||||
// 传承人模块只有一个头像字段
|
||||
const fileFields = ['avatar'];
|
||||
// 传承人模块有头像和作品图片字段
|
||||
const fileFields = ['avatar', 'workImages'];
|
||||
|
||||
for (const field of fileFields) {
|
||||
// 如果字段有值且包含blob URL,说明有新文件需要上传
|
||||
@ -176,8 +185,11 @@
|
||||
throw new Error('无法获取文件对象');
|
||||
}
|
||||
|
||||
// 确定业务路径 - 传承人模块只有头像
|
||||
// 确定业务路径 - 传承人模块有头像和作品图片
|
||||
let bizPath = 'inheritor/avatar';
|
||||
if (fieldName === 'workImages') {
|
||||
bizPath = 'inheritor/works';
|
||||
}
|
||||
|
||||
// 上传文件参数
|
||||
const uploadParams = {
|
||||
|
Loading…
Reference in New Issue
Block a user