diff --git a/src/api/oroqen/OroqenHeritageInheritor.ts b/src/api/oroqen/OroqenHeritageInheritor.ts
new file mode 100644
index 0000000..8d150de
--- /dev/null
+++ b/src/api/oroqen/OroqenHeritageInheritor.ts
@@ -0,0 +1,95 @@
+import { defHttp } from '/@/utils/http/axios';
+import { useMessage } from '/@/hooks/web/useMessage';
+
+const { createConfirm } = useMessage();
+
+enum Api {
+ list = '/oroqen/heritageInheritor/list',
+ save = '/oroqen/heritageInheritor/add',
+ edit = '/oroqen/heritageInheritor/edit',
+ deleteOne = '/oroqen/heritageInheritor/delete',
+ deleteBatch = '/oroqen/heritageInheritor/deleteBatch',
+ importExcel = '/oroqen/heritageInheritor/importExcel',
+ exportXls = '/oroqen/heritageInheritor/exportXls',
+}
+
+/**
+ * 导出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 });
+};
+
+/**
+ * 获取传承人选项列表(用于下拉选择)
+ */
+export const getInheritorOptions = () => {
+ 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.name,
+ value: item.id,
+ key: item.id
+ }));
+ console.log('传承人选项数据:', options);
+ return options;
+ }
+ console.log('传承人数据为空或格式错误');
+ return [];
+ }).catch(error => {
+ console.error('获取传承人数据失败:', error);
+ return [];
+ });
+};
\ No newline at end of file
diff --git a/src/components/Form/src/jeecg/components/JUpload/JUpload.vue b/src/components/Form/src/jeecg/components/JUpload/JUpload.vue
index 66a0fe0..4bb8fc1 100644
--- a/src/components/Form/src/jeecg/components/JUpload/JUpload.vue
+++ b/src/components/Form/src/jeecg/components/JUpload/JUpload.vue
@@ -163,10 +163,12 @@
// 添加可左右移动的按钮
function onAddActionsButton(event) {
const getUploadItem = () => {
- for (const path of event.path) {
- if (path.classList.contains(antUploadItemCls)) {
- return path;
- } else if (path.classList.contains(`${prefixCls}-container`)) {
+ // 兼容不同浏览器的事件路径获取方式
+ const path = event.path || (event.composedPath && event.composedPath()) || [];
+ for (const element of path) {
+ if (element.classList && element.classList.contains(antUploadItemCls)) {
+ return element;
+ } else if (element.classList && element.classList.contains(`${prefixCls}-container`)) {
return null;
}
}
@@ -206,7 +208,8 @@
const result = split(paths);
// update-end--author:liaozhiyang---date:20250325---for:【issues/7990】图片参数中包含逗号会错误的识别成多张图
for (const item of result) {
- let url = getFileAccessHttpUrl(item);
+ // 如果是blob URL,直接使用,不通过getFileAccessHttpUrl处理
+ let url = item.startsWith('blob:') ? item : getFileAccessHttpUrl(item);
list.push({
uid: uidGenerator(),
name: getFileName(item),
@@ -226,7 +229,8 @@
}
let list: any[] = [];
for (const item of array) {
- let url = getFileAccessHttpUrl(item.filePath);
+ // 如果是blob URL,直接使用,不通过getFileAccessHttpUrl处理
+ let url = item.filePath.startsWith('blob:') ? item.filePath : getFileAccessHttpUrl(item.filePath);
list.push({
uid: uidGenerator(),
name: item.fileName,
@@ -273,6 +277,7 @@
// upload组件change事件
function onFileChange(info) {
+ console.log('onFileChange 被调用:', info.file.status, info.file.url);
if (!info.file.status && uploadGoOn.value === false) {
info.fileList.pop();
}
@@ -295,7 +300,19 @@
successFileList = fileListTemp.map((file) => {
if (file.response) {
let reUrl = file.response.message;
- file.url = getFileAccessHttpUrl(reUrl);
+ console.log('处理文件URL:', file.url, '是否为blob:', file.url?.startsWith('blob:'));
+ // 如果文件已经有URL且是blob URL(本地预览URL),则保持不变
+ if (!file.url || !file.url.startsWith('blob:')) {
+ file.url = getFileAccessHttpUrl(reUrl);
+ console.log('设置新URL:', file.url);
+ } else {
+ console.log('保持blob URL:', file.url);
+ }
+ // 关键修复:确保response.message也使用blob URL,避免Ant Design Upload组件直接使用它作为缩略图src
+ if (file.url && file.url.startsWith('blob:')) {
+ file.response.message = file.url;
+ console.log('同步response.message为blob URL:', file.response.message);
+ }
}
return file;
});
@@ -361,10 +378,23 @@
// 预览文件、图片
function onFilePreview(file) {
+ console.log('预览文件URL:', file.url);
+ // 确保预览时使用正确的URL
+ let previewUrl = file.url;
+ // 如果URL不是blob URL且response中有message,优先使用blob URL
+ if (!previewUrl.startsWith('blob:') && file.response && file.response.message) {
+ // 检查是否有本地预览URL可用
+ const fileInList = fileList.value.find(f => f.uid === file.uid);
+ if (fileInList && fileInList.url && fileInList.url.startsWith('blob:')) {
+ previewUrl = fileInList.url;
+ console.log('使用本地预览URL:', previewUrl);
+ }
+ }
+
if (isImageMode.value) {
- createImgPreview({ imageList: [file.url], maskClosable: true });
+ createImgPreview({ imageList: [previewUrl], maskClosable: true });
} else {
- window.open(file.url);
+ window.open(previewUrl);
}
}
diff --git a/src/utils/common/compUtils.ts b/src/utils/common/compUtils.ts
index f03b807..91e9fda 100644
--- a/src/utils/common/compUtils.ts
+++ b/src/utils/common/compUtils.ts
@@ -23,6 +23,10 @@ export const getFileAccessHttpUrl = (fileUrl, prefix = 'http') => {
let result = fileUrl;
try {
if (fileUrl && fileUrl.length > 0 && !fileUrl.startsWith(prefix)) {
+ // 检查是否是blob URL,如果是则直接返回
+ if (fileUrl.startsWith('blob:')) {
+ return fileUrl;
+ }
//判断是否是数组格式
let isArray = fileUrl.indexOf('[') != -1;
if (!isArray) {
diff --git a/src/views/oroqen/heritage-project/OroqenHeritageProject.api.ts b/src/views/oroqen/heritage-project/OroqenHeritageProject.api.ts
new file mode 100644
index 0000000..2c66506
--- /dev/null
+++ b/src/views/oroqen/heritage-project/OroqenHeritageProject.api.ts
@@ -0,0 +1,75 @@
+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',
+ recommend = '/oroqen/heritageProject/recommend',
+}
+/**
+ * 导出api
+ * @param params
+ */
+export const getExportUrl = Api.exportXls;
+/**
+ * 导入api
+ */
+export const getImportUrl = Api.importExcel;
+/**
+ * 列表接口
+ * @param params
+ */
+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();
+ });
+}
+/**
+ * 批量删除
+ * @param params
+ */
+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();
+ });
+ }
+ });
+}
+/**
+ * 保存或者更新
+ * @param params
+ */
+export const saveOrUpdate = (params, isUpdate) => {
+ let url = isUpdate ? Api.edit : Api.save;
+ return defHttp.post({url: url, params});
+}
+
+/**
+ * 推荐/取消推荐
+ * @param params
+ */
+export const toggleRecommend = (params, handleSuccess) => {
+ return defHttp.put({url: Api.recommend, params}, { joinParamsToUrl: true }).then(() => {
+ handleSuccess();
+ });
+}
diff --git a/src/views/oroqen/heritage-project/OroqenHeritageProject.data.ts b/src/views/oroqen/heritage-project/OroqenHeritageProject.data.ts
new file mode 100644
index 0000000..c2bf7fa
--- /dev/null
+++ b/src/views/oroqen/heritage-project/OroqenHeritageProject.data.ts
@@ -0,0 +1,599 @@
+import {BasicColumn} from '/@/components/Table';
+import {FormSchema} from '/@/components/Table';
+import { h } from 'vue';
+import { Image } from 'ant-design-vue';
+import { getInheritorOptions } from '/@/api/oroqen/OroqenHeritageInheritor';
+import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
+
+//列表数据
+export const columns: BasicColumn[] = [
+ {
+ title: '项目名称',
+ align:"left",
+ dataIndex: 'projectName',
+ ellipsis: true,
+ fixed: 'left',
+ },
+ {
+ title: '封面图片',
+ align:"center",
+ dataIndex: 'coverImage',
+ customRender: ({ text, record }) => {
+ if (!text) return '-';
+ // 使用 getFileAccessHttpUrl 函数来正确处理图片URL
+ const imageUrl = getFileAccessHttpUrl(text);
+
+ return h(Image, {
+ src: imageUrl,
+ alt: record?.projectName || '封面图片',
+ width: 60,
+ height: 60,
+ style: { objectFit: 'cover', borderRadius: '4px' },
+ preview: true,
+ fallback: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAYAAADQvc6UAAABRWlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGASSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8LAwSDCIMogwMCcmFxc4BgQ4ANUwgCjUcG3awyMIPqyLsis7PPOq3QdDFcvjV3jOD1boQVTPQrgSkktTgbSf4A4LbmgqISBgTEFyFYuLykAsTuAbJEioKOA7DkgdjqEvQHEToKwj4DVhAQ5A9k3gGyB5IxEoBmML4BsnSQk8XQkNtReEOBxcfXxUQg1Mjc0dyHgXNJBSWpFCYh2zi+oLMpMzyhRcASGUqqCZ16yno6CkYGRAQMDKMwhqj/fAIcloxgHQqxAjIHBEugw5sUIsSQpBobtQPdLciLEVJYzMPBHMDBsayhILEqEO4DxG0txmrERhM29nYGBddr//5/DGRjYNRkY/l7////39v///y4Dmn+LgeHANwDrkl1AuO+pmgAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAAwqADAAQAAAABAAAAwwAAAAD9b/HnAAAHlklEQVR4Ae3dP3Ik1RnG4W+FgYxN'
+ });
+ }
+ },
+ {
+ title: '项目编码',
+ align:"center",
+ dataIndex: 'projectCode',
+ },
+ {
+ title: '项目类别',
+ align:"center",
+ dataIndex: 'category',
+ customRender: ({ text }) => {
+ const categoryMap = {
+ 'TRADITIONAL_CRAFT': '传统技艺',
+ 'FOLK_CUSTOM': '民俗',
+ 'TRADITIONAL_MUSIC': '传统音乐',
+ 'TRADITIONAL_DANCE': '传统舞蹈',
+ 'TRADITIONAL_DRAMA': '传统戏剧',
+ 'QUYI': '曲艺',
+ 'TRADITIONAL_SPORTS': '传统体育',
+ 'TRADITIONAL_ART': '传统美术',
+ 'TRADITIONAL_MEDICINE': '传统医药',
+ 'LITERATURE': '文学'
+ };
+ return categoryMap[text] || text;
+ }
+ },
+ {
+ title: '非遗级别',
+ align:"center",
+ dataIndex: 'heritageLevel',
+ customRender: ({ text }) => {
+ const levelMap = {
+ 'NATIONAL': '国家级',
+ 'PROVINCIAL': '省级',
+ 'MUNICIPAL': '市级',
+ 'COUNTY': '县级'
+ };
+ const level = levelMap[text] || text;
+ const colorMap = {
+ '国家级': '#cf1322',
+ '省级': '#fa541c',
+ '市级': '#fa8c16',
+ '县级': '#52c41a'
+ };
+ return h('span', {
+ style: {
+ color: colorMap[level] || '#666',
+ fontWeight: '500'
+ }
+ }, level);
+ }
+ },
+ {
+ title: '批准年份',
+ align:"center",
+ dataIndex: 'approvalYear',
+ },
+ {
+ title: '保护单位',
+ align:"center",
+ dataIndex: 'protectionUnit',
+ ellipsis: true,
+ },
+ {
+ title: '浏览次数',
+ align:"center",
+ dataIndex: 'viewCount',
+ },
+ {
+ title: '状态',
+ align:"center",
+ dataIndex: 'status',
+ customRender: ({ text }) => {
+ return text === 1 ?
+ h('span', { style: { color: '#52c41a', fontWeight: '500' } }, '启用') :
+ h('span', { style: { color: '#ff4d4f', fontWeight: '500' } }, '禁用');
+ }
+ },
+ {
+ title: '推荐状态',
+ align:"center",
+ dataIndex: 'isRecommended',
+ customRender: ({ text }) => {
+ return text === 1 ?
+ h('span', { style: { color: '#1890ff', fontWeight: '500' } }, '已推荐') :
+ h('span', { style: { color: '#999', fontWeight: '500' } }, '未推荐');
+ }
+ },
+];
+//查询数据
+export const searchFormSchema: FormSchema[] = [
+ {
+ label: '项目名称',
+ field: 'projectName',
+ component: 'Input',
+ componentProps: {
+ placeholder: '请输入项目名称',
+ },
+ colProps: { span: 6 },
+ },
+ {
+ label: '项目编码',
+ field: 'projectCode',
+ component: 'Input',
+ componentProps: {
+ placeholder: '请输入项目编码',
+ },
+ colProps: { span: 6 },
+ },
+ {
+ label: '项目类别',
+ field: 'category',
+ component: 'Select',
+ componentProps: {
+ placeholder: '请选择项目类别',
+ options: [
+ { label: '传统技艺', value: 'TRADITIONAL_CRAFT' },
+ { label: '民俗', value: 'FOLK_CUSTOM' },
+ { label: '传统音乐', value: 'TRADITIONAL_MUSIC' },
+ { label: '传统舞蹈', value: 'TRADITIONAL_DANCE' },
+ { label: '传统戏剧', value: 'TRADITIONAL_DRAMA' },
+ { label: '曲艺', value: 'QUYI' },
+ { label: '传统体育', value: 'TRADITIONAL_SPORTS' },
+ { label: '传统美术', value: 'TRADITIONAL_ART' },
+ { label: '传统医药', value: 'TRADITIONAL_MEDICINE' },
+ { label: '文学', value: 'LITERATURE' },
+ ]
+ },
+ colProps: { span: 6 },
+ },
+ {
+ label: '非遗级别',
+ field: 'heritageLevel',
+ component: 'Select',
+ componentProps: {
+ placeholder: '请选择非遗级别',
+ options: [
+ { label: '国家级', value: 'NATIONAL' },
+ { label: '省级', value: 'PROVINCIAL' },
+ { label: '市级', value: 'MUNICIPAL' },
+ { label: '县级', value: 'COUNTY' },
+ ]
+ },
+ colProps: { span: 6 },
+ },
+ {
+ label: '保护单位',
+ field: 'protectionUnit',
+ component: 'Input',
+ componentProps: {
+ placeholder: '请输入保护单位',
+ },
+ colProps: { span: 6 },
+ },
+ {
+ label: '状态',
+ field: 'status',
+ component: 'Select',
+ componentProps: {
+ placeholder: '请选择状态',
+ options: [
+ { label: '启用', value: 1 },
+ { label: '禁用', value: 0 },
+ ]
+ },
+ colProps: { span: 6 },
+ },
+];
+//表单数据
+export const formSchema: FormSchema[] = [
+ {
+ label: '项目名称',
+ field: 'projectName',
+ component: 'Input',
+ componentProps: {
+ placeholder: '请输入项目名称',
+ },
+ dynamicRules: ({model,schema}) => {
+ return [
+ { required: true, message: '请输入项目名称!'},
+ ];
+ },
+ },
+ {
+ label: '项目编码',
+ field: 'projectCode',
+ component: 'Input',
+ componentProps: {
+ placeholder: '请输入项目编码',
+ },
+ dynamicRules: ({model,schema}) => {
+ return [
+ { required: true, message: '请输入项目编码!'},
+ ];
+ },
+ },
+ {
+ label: '项目类别',
+ field: 'category',
+ component: 'Select',
+ componentProps: {
+ placeholder: '请选择项目类别',
+ options: [
+ { label: '传统技艺', value: 'TRADITIONAL_CRAFT' },
+ { label: '民俗', value: 'FOLK_CUSTOM' },
+ { label: '传统音乐', value: 'TRADITIONAL_MUSIC' },
+ { label: '传统舞蹈', value: 'TRADITIONAL_DANCE' },
+ { label: '传统戏剧', value: 'TRADITIONAL_DRAMA' },
+ { label: '曲艺', value: 'QUYI' },
+ { label: '传统体育', value: 'TRADITIONAL_SPORTS' },
+ { label: '传统美术', value: 'TRADITIONAL_ART' },
+ { label: '传统医药', value: 'TRADITIONAL_MEDICINE' },
+ { label: '文学', value: 'LITERATURE' },
+ ]
+ },
+ dynamicRules: ({model,schema}) => {
+ return [
+ { required: true, message: '请选择项目类别!'},
+ ];
+ },
+ },
+ {
+ label: '非遗级别',
+ field: 'heritageLevel',
+ component: 'Select',
+ componentProps: {
+ placeholder: '请选择非遗级别',
+ options: [
+ { label: '国家级', value: 'NATIONAL' },
+ { label: '省级', value: 'PROVINCIAL' },
+ { label: '市级', value: 'MUNICIPAL' },
+ { label: '县级', value: 'COUNTY' },
+ ]
+ },
+ dynamicRules: ({model,schema}) => {
+ return [
+ { required: true, message: '请选择非遗级别!'},
+ ];
+ },
+ },
+ {
+ label: '批准年份',
+ field: 'approvalYear',
+ component: 'InputNumber',
+ componentProps: {
+ placeholder: '请输入批准年份',
+ min: 1900,
+ max: new Date().getFullYear(),
+ },
+ },
+ {
+ label: '批准文号',
+ field: 'approvalNumber',
+ component: 'Input',
+ componentProps: {
+ placeholder: '请输入批准文号',
+ },
+ },
+ {
+ label: '项目描述',
+ field: 'description',
+ component: 'InputTextArea',
+ componentProps: {
+ placeholder: '请输入项目描述',
+ rows: 3,
+ maxlength: 500,
+ showCount: true,
+ },
+ dynamicRules: ({model,schema}) => {
+ return [
+ { required: true, message: '请输入项目描述!'},
+ ];
+ },
+ },
+ {
+ label: '详细描述',
+ field: 'fullDescription',
+ component: 'InputTextArea',
+ componentProps: {
+ placeholder: '请输入详细描述',
+ rows: 4,
+ maxlength: 2000,
+ showCount: true,
+ },
+ },
+ {
+ label: '历史渊源',
+ field: 'history',
+ component: 'InputTextArea',
+ componentProps: {
+ placeholder: '请输入历史渊源',
+ rows: 4,
+ maxlength: 2000,
+ showCount: true,
+ },
+ },
+ {
+ label: '技艺特点',
+ field: 'features',
+ component: 'InputTextArea',
+ componentProps: {
+ placeholder: '请输入技艺特点',
+ rows: 4,
+ maxlength: 2000,
+ showCount: true,
+ },
+ },
+ {
+ label: '传承价值',
+ field: 'value',
+ component: 'InputTextArea',
+ componentProps: {
+ placeholder: '请输入传承价值',
+ rows: 4,
+ maxlength: 2000,
+ showCount: true,
+ },
+ },
+ {
+ label: '封面图片',
+ field: 'coverImage',
+ component: 'JUpload',
+ componentProps: {
+ fileType: 'image',
+ maxCount: 1,
+ maxSize: 5,
+ bizPath: 'heritage-project/cover',
+ 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;
+
+ // 模拟上传成功响应,但不返回local:前缀,避免被解析
+ setTimeout(() => {
+ options.onSuccess({
+ success: true,
+ message: file.name, // 仅使用文件名,不使用local:前缀
+ }, file);
+ }, 100);
+ },
+ },
+ colProps: { lg: 12, md: 12 },
+ },
+ {
+ label: '图片集',
+ field: 'images',
+ component: 'JUpload',
+ componentProps: {
+ fileType: 'image',
+ maxCount: 10,
+ maxSize: 5,
+ bizPath: 'heritage-project/images',
+ 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;
+
+ // 模拟上传成功响应,但不返回local:前缀,避免被解析
+ setTimeout(() => {
+ options.onSuccess({
+ success: true,
+ message: file.name, // 仅使用文件名,不使用local:前缀
+ }, file);
+ }, 100);
+ },
+ },
+ colProps: { lg: 12, md: 12 },
+ },
+ {
+ label: '视频链接',
+ field: 'videoUrl',
+ component: 'JUpload',
+ componentProps: {
+ fileType: 'video',
+ maxCount: 1,
+ maxSize: 50,
+ bizPath: 'heritage-project/video',
+ customRequest: (options) => {
+ // 验证文件类型和大小
+ const { file } = options;
+ const isVideo = file.type.startsWith('video/');
+ if (!isVideo) {
+ console.error('只能上传视频文件!');
+ return;
+ }
+ const isLt50M = file.size / 1024 / 1024 < 50;
+ if (!isLt50M) {
+ console.error('视频大小不能超过50MB!');
+ return;
+ }
+
+ // 创建本地预览URL
+ const localUrl = URL.createObjectURL(file);
+
+ // 直接设置文件的url为本地预览URL
+ file.url = localUrl;
+
+ // 模拟上传成功响应,但不返回local:前缀,避免被解析
+ setTimeout(() => {
+ options.onSuccess({
+ success: true,
+ message: file.name, // 仅使用文件名,不使用local:前缀
+ }, file);
+ }, 100);
+ },
+ },
+ colProps: { lg: 24, md: 24 },
+ },
+ // {
+ // label: '音频链接',
+ // field: 'audioUrl',
+ // component: 'JUpload',
+ // componentProps: {
+ // fileType: 'audio',
+ // maxCount: 1,
+ // maxSize: 20,
+ // bizPath: 'heritage-project/audio',
+ // },
+ // },
+ {
+ label: '标签',
+ field: 'tags',
+ component: 'Input',
+ componentProps: {
+ placeholder: '请输入标签,多个标签用逗号分隔',
+ },
+ },
+ {
+ label: '关联传承人',
+ field: 'inheritorIds',
+ component: 'ApiSelect',
+ componentProps: {
+ placeholder: '请选择关联传承人',
+ mode: 'multiple',
+ allowClear: true,
+ showSearch: true,
+ api: getInheritorOptions,
+ immediate: true,
+ resultField: '',
+ labelField: 'label',
+ valueField: 'value',
+ },
+ },
+ {
+ label: '保护单位',
+ field: 'protectionUnit',
+ component: 'Input',
+ componentProps: {
+ placeholder: '请输入保护单位',
+ },
+ },
+ {
+ label: '保护措施',
+ field: 'protectionMeasures',
+ component: 'InputTextArea',
+ componentProps: {
+ placeholder: '请输入保护措施',
+ rows: 3,
+ maxlength: 1000,
+ showCount: true,
+ },
+ },
+ {
+ label: '保护现状',
+ field: 'currentStatus',
+ component: 'InputTextArea',
+ componentProps: {
+ placeholder: '请输入保护现状',
+ rows: 3,
+ maxlength: 1000,
+ showCount: true,
+ },
+ },
+ {
+ label: '状态',
+ field: 'status',
+ component: 'RadioGroup',
+ componentProps: {
+ options: [
+ { label: '禁用', value: 0 },
+ { label: '启用', value: 1 },
+ ]
+ },
+ defaultValue: 1,
+ ifShow: ({ values }) => {
+ // 新增时隐藏状态字段,编辑时显示
+ return !!values.id;
+ },
+ },
+ // TODO 主键隐藏字段,目前写死为ID
+ {
+ label: '',
+ field: 'id',
+ component: 'Input',
+ show: false
+ },
+];
+
+// 高级查询数据
+export const superQuerySchema = {
+ projectName: {title: '项目名称',order: 0,view: 'text', type: 'string',},
+ projectCode: {title: '项目编码',order: 1,view: 'text', type: 'string',},
+ category: {title: '项目类别',order: 2,view: 'text', type: 'string',},
+ heritageLevel: {title: '非遗级别',order: 3,view: 'text', type: 'string',},
+ approvalYear: {title: '批准年份',order: 4,view: 'number', type: 'number',},
+ approvalNumber: {title: '批准文号',order: 5,view: 'text', type: 'string',},
+ description: {title: '项目描述',order: 6,view: 'text', type: 'string',},
+ 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',},
+};
+
+/**
+* 流程表单调用这个方法获取formSchema
+* @param param
+*/
+export function getBpmFormSchema(_formData): FormSchema[]{
+ // 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
+ return formSchema;
+}
\ No newline at end of file
diff --git a/src/views/oroqen/heritage-project/OroqenHeritageProjectList.vue b/src/views/oroqen/heritage-project/OroqenHeritageProjectList.vue
new file mode 100644
index 0000000..e30bc67
--- /dev/null
+++ b/src/views/oroqen/heritage-project/OroqenHeritageProjectList.vue
@@ -0,0 +1,219 @@
+
+
+
+
+
+
+ 新增
+
+ 导出
+ 导入
+
+
+
+
+
+
+ 删除
+
+
+
+ 批量操作
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/oroqen/heritage-project/components/OroqenHeritageProjectForm.vue b/src/views/oroqen/heritage-project/components/OroqenHeritageProjectForm.vue
new file mode 100644
index 0000000..2759a3e
--- /dev/null
+++ b/src/views/oroqen/heritage-project/components/OroqenHeritageProjectForm.vue
@@ -0,0 +1,70 @@
+
+
+
+
+
diff --git a/src/views/oroqen/heritage-project/components/OroqenHeritageProjectModal.vue b/src/views/oroqen/heritage-project/components/OroqenHeritageProjectModal.vue
new file mode 100644
index 0000000..1e5f523
--- /dev/null
+++ b/src/views/oroqen/heritage-project/components/OroqenHeritageProjectModal.vue
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+