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,
|
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: '传承价值',
|
label: '传承价值',
|
||||||
field: 'value',
|
field: 'value',
|
||||||
@ -573,20 +585,21 @@ export const superQuerySchema = {
|
|||||||
fullDescription: {title: '详细描述',order: 7,view: 'textarea', type: 'string',},
|
fullDescription: {title: '详细描述',order: 7,view: 'textarea', type: 'string',},
|
||||||
history: {title: '历史渊源',order: 8,view: 'textarea', type: 'string',},
|
history: {title: '历史渊源',order: 8,view: 'textarea', type: 'string',},
|
||||||
features: {title: '技艺特点',order: 9,view: 'textarea', type: 'string',},
|
features: {title: '技艺特点',order: 9,view: 'textarea', type: 'string',},
|
||||||
value: {title: '传承价值',order: 10,view: 'textarea', type: 'string',},
|
craftProcess: {title: '制作流程',order: 10,view: 'textarea', type: 'string',},
|
||||||
coverImage: {title: '封面图片',order: 11,view: 'text', type: 'string',},
|
value: {title: '传承价值',order: 11,view: 'textarea', type: 'string',},
|
||||||
images: {title: '图片集',order: 12,view: 'textarea', type: 'string',},
|
coverImage: {title: '封面图片',order: 12,view: 'text', type: 'string',},
|
||||||
videoUrl: {title: '视频链接',order: 13,view: 'text', type: 'string',},
|
images: {title: '图片集',order: 13,view: 'textarea', type: 'string',},
|
||||||
audioUrl: {title: '音频链接',order: 14,view: 'text', type: 'string',},
|
videoUrl: {title: '视频链接',order: 14,view: 'text', type: 'string',},
|
||||||
tags: {title: '标签',order: 15,view: 'text', type: 'string',},
|
audioUrl: {title: '音频链接',order: 15,view: 'text', type: 'string',},
|
||||||
inheritorIds: {title: '关联传承人ID',order: 16,view: 'textarea', type: 'string',},
|
tags: {title: '标签',order: 16,view: 'text', type: 'string',},
|
||||||
protectionUnit: {title: '保护单位',order: 17,view: 'text', type: 'string',},
|
inheritorIds: {title: '关联传承人ID',order: 17,view: 'textarea', type: 'string',},
|
||||||
protectionMeasures: {title: '保护措施',order: 18,view: 'text', type: 'string',},
|
protectionUnit: {title: '保护单位',order: 18,view: 'text', type: 'string',},
|
||||||
currentStatus: {title: '保护现状',order: 19,view: 'text', type: 'string',},
|
protectionMeasures: {title: '保护措施',order: 19,view: 'text', type: 'string',},
|
||||||
isRecommended: {title: '是否推荐',order: 20,view: 'number', type: 'number',},
|
currentStatus: {title: '保护现状',order: 20,view: 'text', type: 'string',},
|
||||||
viewCount: {title: '浏览次数',order: 21,view: 'number', type: 'number',},
|
isRecommended: {title: '是否推荐',order: 21,view: 'number', type: 'number',},
|
||||||
likeCount: {title: '点赞次数',order: 22,view: 'number', type: 'number',},
|
viewCount: {title: '浏览次数',order: 22,view: 'number', type: 'number',},
|
||||||
status: {title: '状态',order: 23,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 { Image, Tag } from 'ant-design-vue';
|
||||||
import { render } from '/@/utils/common/renderUtils';
|
import { render } from '/@/utils/common/renderUtils';
|
||||||
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
|
||||||
|
import { getHeritageProjectOptions } from '/@/api/oroqen/OroqenHeritageProject';
|
||||||
|
|
||||||
//列表数据
|
//列表数据
|
||||||
export const columns: BasicColumn[] = [
|
export const columns: BasicColumn[] = [
|
||||||
@ -63,10 +64,19 @@ export const columns: BasicColumn[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '传承项目',
|
title: '传承项目',
|
||||||
dataIndex: 'heritageProject',
|
dataIndex: 'heritageSkills',
|
||||||
width: 150,
|
width: 150,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
|
customRender: ({ text }) => {
|
||||||
|
if (!text) return '-';
|
||||||
|
// 如果是数组格式的项目ID,需要转换为项目名称显示
|
||||||
|
// 这里暂时直接显示,后续可以通过API获取项目名称
|
||||||
|
if (Array.isArray(text)) {
|
||||||
|
return text.join(', ');
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '传承级别',
|
title: '传承级别',
|
||||||
@ -227,11 +237,40 @@ export const formSchema: FormSchema[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '传承项目',
|
label: '传承项目',
|
||||||
field: 'heritageProject',
|
field: 'heritageSkills',
|
||||||
component: 'Input',
|
component: 'ApiSelect',
|
||||||
required: true,
|
|
||||||
componentProps: {
|
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 },
|
colProps: { span: 12 },
|
||||||
},
|
},
|
||||||
@ -390,6 +429,46 @@ export const formSchema: FormSchema[] = [
|
|||||||
}, 100);
|
}, 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';
|
isDetail.value = data?.mode === 'detail';
|
||||||
|
|
||||||
if (unref(isUpdate)) {
|
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({
|
await setFieldsValue(record);
|
||||||
...data.record,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// 详情模式时禁用整个表单
|
// 详情模式时禁用整个表单
|
||||||
setProps({ disabled: unref(isDetail) });
|
setProps({ disabled: unref(isDetail) });
|
||||||
@ -56,6 +60,11 @@
|
|||||||
let values = await validate();
|
let values = await validate();
|
||||||
console.log('表单验证通过,提交数据:', values);
|
console.log('表单验证通过,提交数据:', values);
|
||||||
|
|
||||||
|
// 处理传承项目字段的数据转换
|
||||||
|
if (values.heritageSkills && Array.isArray(values.heritageSkills)) {
|
||||||
|
values.heritageSkills = values.heritageSkills.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
// 预处理日期数据
|
// 预处理日期数据
|
||||||
changeDateValue(values);
|
changeDateValue(values);
|
||||||
setModalProps({ confirmLoading: true });
|
setModalProps({ confirmLoading: true });
|
||||||
@ -108,8 +117,8 @@
|
|||||||
console.log('开始处理文件上传,表单数据:', formData);
|
console.log('开始处理文件上传,表单数据:', formData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 传承人模块只有一个头像字段
|
// 传承人模块有头像和作品图片字段
|
||||||
const fileFields = ['avatar'];
|
const fileFields = ['avatar', 'workImages'];
|
||||||
|
|
||||||
for (const field of fileFields) {
|
for (const field of fileFields) {
|
||||||
// 如果字段有值且包含blob URL,说明有新文件需要上传
|
// 如果字段有值且包含blob URL,说明有新文件需要上传
|
||||||
@ -176,8 +185,11 @@
|
|||||||
throw new Error('无法获取文件对象');
|
throw new Error('无法获取文件对象');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确定业务路径 - 传承人模块只有头像
|
// 确定业务路径 - 传承人模块有头像和作品图片
|
||||||
let bizPath = 'inheritor/avatar';
|
let bizPath = 'inheritor/avatar';
|
||||||
|
if (fieldName === 'workImages') {
|
||||||
|
bizPath = 'inheritor/works';
|
||||||
|
}
|
||||||
|
|
||||||
// 上传文件参数
|
// 上传文件参数
|
||||||
const uploadParams = {
|
const uploadParams = {
|
||||||
|
Loading…
Reference in New Issue
Block a user