diff --git a/src/api/oroqen/OroqenHeritageProject.ts b/src/api/oroqen/OroqenHeritageProject.ts new file mode 100644 index 0000000..09d0552 --- /dev/null +++ b/src/api/oroqen/OroqenHeritageProject.ts @@ -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 } }); +}; \ No newline at end of file diff --git a/src/views/oroqen/heritage-project/OroqenHeritageProject.data.ts b/src/views/oroqen/heritage-project/OroqenHeritageProject.data.ts index c2bf7fa..7639016 100644 --- a/src/views/oroqen/heritage-project/OroqenHeritageProject.data.ts +++ b/src/views/oroqen/heritage-project/OroqenHeritageProject.data.ts @@ -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',}, }; /** diff --git a/src/views/oroqen/inheritor/OroqenInheritor.data.ts b/src/views/oroqen/inheritor/OroqenInheritor.data.ts index 857bb8a..4dfc97d 100644 --- a/src/views/oroqen/inheritor/OroqenInheritor.data.ts +++ b/src/views/oroqen/inheritor/OroqenInheritor.data.ts @@ -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 }, }, ]; \ No newline at end of file diff --git a/src/views/oroqen/inheritor/components/OroqenInheritorModal.vue b/src/views/oroqen/inheritor/components/OroqenInheritorModal.vue index 22c836f..5e99aa6 100644 --- a/src/views/oroqen/inheritor/components/OroqenInheritorModal.vue +++ b/src/views/oroqen/inheritor/components/OroqenInheritorModal.vue @@ -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 = {