ich.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <template>
  2. <!-- 非遗基础表单
  3. :extendFormModel="formExtendModel"
  4. :extendFormOptions="formExtendOptions"-->
  5. <Form
  6. ref="formRef"
  7. :formModel="formModel"
  8. :formOptions="formOptions"
  9. :load="loadData"
  10. :model="IchInfo"
  11. />
  12. </template>
  13. <script setup lang="ts">
  14. import { h, ref, type Ref } from 'vue';
  15. import { useImageSimpleUploadCo } from '@/common/upload/ImageUploadCo';
  16. import Form from './form.vue';
  17. import InheritorContent, { IchExpandInfo, IchInfo } from '@/api/inheritor/InheritorContent';
  18. import CommonContent from '@/api/CommonContent';
  19. import type { IDynamicFormOptions, IDynamicFormRef } from '@imengyu/vue-dynamic-form';
  20. import type { SelectProps } from 'ant-design-vue';
  21. import { useBeforeUploadImageChecker, useBeforeUploadVideoChecker, type UploadImageFormItemProps } from '@/components/dynamicf/UploadImageFormItem';
  22. import type { AddressItem } from '@/components/dynamicf/Map/AddressSercher.vue';
  23. import { useAuthStore } from '@/stores/auth';
  24. import { useAliOssUploadCo } from '@/common/upload/AliOssUploadCo';
  25. import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
  26. const authStore = useAuthStore();
  27. const formRef = ref();
  28. const formModel = ref(new IchInfo()) as Ref<IchInfo>;
  29. const formOptions = ref<IDynamicFormOptions>({
  30. formLabelCol: { span: 6 },
  31. formWrapperCol: { span: 24 },
  32. formAdditionaProps: {
  33. layout: 'vertical',
  34. scrollToFirstError: true,
  35. },
  36. formNestNameGenerateType: 'array',
  37. formItems: [
  38. {
  39. type: 'group-flat', label: '非遗基础档案', name: 'ichInfo',
  40. childrenColProps: { span: 24 },
  41. children: [
  42. {
  43. label: '非遗项目名称', name: 'title', type: 'text',
  44. additionalProps: {
  45. placeholder: '请输入标题',
  46. },
  47. },
  48. {
  49. label: '级别', name: 'level', type: 'select-id',
  50. additionalProps: {
  51. placeholder: '请选择级别',
  52. loadData: async () => (await CommonContent.getCategoryList(2)).map(p => ({ label: p.title, value: p.id, raw: p }))
  53. },
  54. },
  55. {
  56. label: '非遗分类', name: 'ichType', type: 'select-id',
  57. additionalProps: {
  58. placeholder: '请选择非遗类型',
  59. loadData: async () => (await CommonContent.getCategoryList(4)).map(p => ({ label: p.title, value: p.id, raw: p }))
  60. },
  61. },
  62. {
  63. label: '批次', name: 'batch', type: 'select-id',
  64. additionalProps: {
  65. placeholder: '请选择批次',
  66. loadData: async () => (await CommonContent.getCategoryList(289)).map(p => ({ label: p.title, value: p.id, raw: p }))
  67. },
  68. },
  69. { label: '申报区域', name: 'regionText', type: 'text', additionalProps: { placeholder: '请输入申报地区' } },
  70. { label: '非遗项目简介', name: 'intro', type: 'richtext', additionalProps: { placeholder: '请输入简介' } },
  71. {
  72. label: '传承谱系', name: 'pedigree', type: 'richtext',
  73. additionalProps: { placeholder: '请输入传承谱系' },
  74. formProps: {
  75. extra: h('div', { class: 'd-flex flex-row align-items-start mt-2' }, [
  76. h(ExclamationCircleOutlined),
  77. h('pre', { class: 'ms-2' }, `请按传承脉络顺序填写:
  78. 1、传承人:姓名(附简短介绍,如技艺特长/代表成就)
  79. 2、传承代数:标注第几代(示例:第五代传人)
  80. 3、师从关系:明确师承对象(如:师从第四代传人XXX)
  81. 注:信息需真实可考,传承脉络清晰有序`),
  82. ]),
  83. },
  84. },
  85. //{ label: '非遗详细描述', name: 'description', type: 'richtext', additionalProps: { placeholder: '请输入项目描述' } },
  86. //{ label: '传承值', name: 'heritage', type: 'text', additionalProps: { placeholder: '请输入传承值' } },
  87. {
  88. label: '保护单位地址', name: 'address', type: 'address-sercher',
  89. additionalProps: { placeholder: '请输入地址' },
  90. additionalEvents: {
  91. choosedAddress: (address: AddressItem) => {
  92. ((formRef.value?.getFormRef() as IDynamicFormRef).getFormItemControlRef('lonlat') as any).moveTo([
  93. address.lng, address.lat
  94. ], 20)
  95. },
  96. }
  97. },
  98. {
  99. label: '地图坐标', name: 'lonlat', type: 'map-pick-point',
  100. formProps: {
  101. extra: h('div', {}, [
  102. h(ExclamationCircleOutlined),
  103. h('span', { class: 'ms-2' }, '输入模糊地址后可以点击搜索跳转到指定位置,如果地图位置不正确,可以手动调整位置'),
  104. ]),
  105. },
  106. },
  107. {
  108. type: 'simple-flat', label: '', name: 'map',
  109. childrenColProps: { span: 12 },
  110. children: [
  111. { label: '平面坐标X', name: 'mapX', type: 'number', additionalProps: { placeholder: '请输入平面坐标X' } },
  112. { label: '平面坐标Y', name: 'mapY', type: 'number', additionalProps: { placeholder: '请输入平面坐标Y' } },
  113. ]
  114. },
  115. { label: '保护单位(多个保护单位请用逗号隔开)', name: 'unit', type: 'text', additionalProps: { placeholder: '请输入保护单位' } },
  116. //{ label: '非遗编号', name: 'code', type: 'text', additionalProps: { placeholder: '请输入非遗编号' } },
  117. //{ label: '流行地区', name: 'popularRegion', type: 'text', additionalProps: { placeholder: '请输入流行地区' } },
  118. //{ label: '批准时间', name: 'approveTime', type: 'text', additionalProps: { placeholder: '请输入批准时间' } },
  119. {
  120. label: '非遗项目相关图片', name: 'images', type: 'mulit-image',
  121. //hidden: { callback: (_, model) => (model as IchInfo).type !== 4 },
  122. formProps: {
  123. extra: '建议分辨率:1920*1080以上',
  124. },
  125. additionalProps: {
  126. placeholder: '请上传图片',
  127. maxCount: 20,
  128. name: 'file',
  129. beforeUpload: useBeforeUploadImageChecker(),
  130. uploadCo: useAliOssUploadCo('ich/images'),
  131. } as UploadImageFormItemProps,
  132. },
  133. {
  134. label: '相关视频', name: 'video', type: 'single-video',
  135. //hidden: { callback: (_, model) => (model as IchInfo).type !== 3 },
  136. additionalProps: {
  137. placeholder: '请上传视频',
  138. name: 'file',
  139. beforeUpload: useBeforeUploadVideoChecker(),
  140. uploadCo: useAliOssUploadCo('ich/video'),
  141. } as UploadImageFormItemProps,
  142. },
  143. {
  144. label: '审核人员', name: 'text1', type: 'static-text',
  145. additionalProps: {
  146. text: '黄念旭,李向群,卢志明',
  147. style: { color: '#999', }
  148. }
  149. },
  150. {
  151. label: '审核状态', name: 'text2', type: 'static-text',
  152. additionalProps: {
  153. text: '暂未审核',
  154. style: { color: '#999', }
  155. }
  156. },
  157. {
  158. label: '填报人', name: 'text3', type: 'static-text',
  159. hidden: { callback: (_, model) => authStore.loginType !== 0 },
  160. additionalProps: {
  161. text: authStore.userInfo?.nickname,
  162. }
  163. },
  164. {
  165. label: '初审状态', name: 'progress', type: 'select',
  166. hidden: { callback: (_, model) => authStore.loginType !== 1 },
  167. additionalProps: {
  168. options: [
  169. { text: '审核退回', value: -1 },
  170. { text: '暂未审核', value: 0 },
  171. { text: '初审通过', value: 1 },
  172. ],
  173. }
  174. },
  175. {
  176. label: '审核意见', name: 'comment', type: 'text-area',
  177. disabled: { callback: (_, model) => authStore.loginType !== 1 },
  178. additionalProps: {
  179. placeholder: { callback: (_: any, model: any) => authStore.loginType === 1 ? '若审核不通过,请输入审核意见' : '暂无审核意见' },
  180. }
  181. },
  182. ]
  183. },
  184. /* {
  185. type: 'group-flat', label: '通用信息', name: 'commonInfo',
  186. childrenColProps: { span: 24 },
  187. children: [
  188. {
  189. label: '地区', name: 'region', type: 'select-id',
  190. additionalProps: {
  191. placeholder: '请选择地区',
  192. loadData: async () => (await CommonContent.getCategoryList(1)).map(p => ({ label: p.title, value: p.id, raw: p })) ,
  193. },
  194. },
  195. {
  196. label: '类型', name: 'type', type: 'select',
  197. additionalProps: {
  198. placeholder: '请选择类型',
  199. options: [
  200. { text: '文章', value: 1 },
  201. { text: '音频', value: 2 },
  202. { text: '视频', value: 3 },
  203. { text: '相册', value: 4 },
  204. { text: '数字档案', value: 5 }]
  205. },
  206. },
  207. {
  208. label: '转自', name: 'from', type: 'text',
  209. additionalProps: { placeholder: '请输入来源' },
  210. },
  211. {
  212. label: '组图', name: 'images', type: 'mulit-image',
  213. hidden: { callback: (_, model) => (model as IchInfo).type !== 4 },
  214. additionalProps: {
  215. placeholder: '请上传图片',
  216. maxCount: 20,
  217. name: 'file',
  218. uploadCo: useImageSimpleUploadCo(),
  219. } as UploadImageFormItemProps,
  220. },
  221. {
  222. label: '音频', name: 'audio', type: 'single-image',
  223. hidden: { callback: (_, model) => (model as IchInfo).type !== 2 },
  224. additionalProps: {
  225. placeholder: '请上传音频',
  226. name: 'file',
  227. uploadCo: useImageSimpleUploadCo()
  228. } as UploadImageFormItemProps,
  229. },
  230. {
  231. label: '数字档案', name: 'archives', type: 'mulit-image',
  232. hidden: { callback: (_, model) => (model as IchInfo).type !== 5 },
  233. additionalProps: {
  234. placeholder: '请上传数字档案',
  235. maxCount: 20,
  236. name: 'file',
  237. uploadCo: useImageSimpleUploadCo()
  238. } as UploadImageFormItemProps,
  239. },
  240. {
  241. label: '标志', name: 'flag', type: 'select',
  242. additionalProps: {
  243. mode: 'tags',
  244. options: [
  245. { text: '热门', value: 'hot' },
  246. { text: '推荐', value: 'recommend' },
  247. { text: '置顶', value: 'top' },
  248. ],
  249. placeholder: '请输入标志'
  250. } as SelectProps,
  251. },
  252. {
  253. label: '关键字', name: 'keywords', type: 'select',
  254. additionalProps: {
  255. mode: 'tags',
  256. options: [],
  257. placeholder: '请输入关键字,回车添加'
  258. } as SelectProps,
  259. },
  260. {
  261. label: '描述', name: 'desc', type: 'text-area',
  262. additionalProps: { placeholder: '请输入描述' },
  263. },
  264. {
  265. label: 'TAG', name: 'tags', type: 'text',
  266. additionalProps: { placeholder: '请输入TAG' },
  267. },
  268. {
  269. label: '备注', name: 'memo', type: 'text-area',
  270. additionalProps: { placeholder: '请输入备注' },
  271. },
  272. ]
  273. }, */
  274. ],
  275. formRules: {
  276. title: [{ required: true, message: '请输入标题' }],
  277. region: [{ required: true, message: '请选择地区' }],
  278. type: [{ required: true, message: '请选择类型' }],
  279. image: [{ required: true, message: '请上传图片' }],
  280. level: [{ required: true, message: '请选择级别' }],
  281. ichType: [{ required: true, message: '请选择非遗类型' }],
  282. batch: [{ required: true, message: '请输入批次' }],
  283. }
  284. });
  285. const formExtendModel = ref(new IchExpandInfo()) as Ref<IchExpandInfo>;
  286. const formExtendOptions = ref<IDynamicFormOptions>({
  287. formLabelCol: { span: 6 },
  288. formWrapperCol: { span: 24 },
  289. formAdditionaProps: {
  290. layout: 'vertical',
  291. scrollToFirstError: true,
  292. },
  293. formNestNameGenerateType: 'array',
  294. formItems: [
  295. {
  296. type: 'select-id', label: '保护级别', name: 'protectLevel',
  297. additionalProps: {
  298. placeholder: '请选择保护级别',
  299. loadData: async () => (await CommonContent.getCategoryList(171)).map(p => ({ label: p.title, value: p.id, raw: p }))
  300. }
  301. },
  302. { type: 'text', label: '其他名称', name: 'otherNames', additionalProps: { placeholder: '请输入其他名称' } },
  303. { type: 'text', label: '实践方式', name: 'practice', additionalProps: { placeholder: '请输入实践方式' } },
  304. { type: 'text', label: '表现形式', name: 'expression', additionalProps: { placeholder: '请输入表现形式' } },
  305. { type: 'text', label: '遗产持有者', name: 'holders', additionalProps: { placeholder: '请输入遗产持有者' } },
  306. { type: 'text', label: '列入名录时间', name: 'joinday', additionalProps: { placeholder: '请选择列入名录时间' } },
  307. { type: 'text', label: '形成时间', name: 'formation', additionalProps: { placeholder: '请选择形成时间' } },
  308. { type: 'text', label: '分布区域', name: 'area', additionalProps: { placeholder: '请输入分布区域' } },
  309. { type: 'text', label: '源流', name: 'origin', additionalProps: { placeholder: '请输入源流' } },
  310. { type: 'text', label: '主要特点', name: 'feature', additionalProps: { placeholder: '请输入主要特点' } },
  311. { type: 'text', label: '重要功能', name: 'functions', additionalProps: { placeholder: '请输入重要功能' } },
  312. { type: 'text', label: '代表作品', name: 'works', additionalProps: { placeholder: '请输入代表作品' } },
  313. { type: 'text', label: '保护单位', name: 'unit', additionalProps: { placeholder: '请输入保护单位' } },
  314. { type: 'text', label: '保护情况', name: 'protect', additionalProps: { placeholder: '请输入保护情况' } },
  315. { type: 'text-area', label: '综合概述', name: 'overview', additionalProps: { placeholder: '请输入综合概述' } },
  316. { type: 'text', label: '代表人物', name: 'figures', additionalProps: { placeholder: '请输入代表人物' } },
  317. { type: 'text', label: '传承群体', name: 'group', additionalProps: { placeholder: '请输入传承群体' } },
  318. { type: 'text', label: '传承方式', name: 'inherit', additionalProps: { placeholder: '请输入传承方式' } },
  319. { type: 'text', label: '发展现状', name: 'develop', additionalProps: { placeholder: '请输入发展现状' } },
  320. { type: 'text', label: '相关民俗', name: 'customs', additionalProps: { placeholder: '请输入相关民俗' } },
  321. { type: 'text', label: '相关信仰', name: 'religion', additionalProps: { placeholder: '请输入相关信仰' } },
  322. { type: 'text', label: '文化空间', name: 'space', additionalProps: { placeholder: '请输入文化空间' } },
  323. { type: 'text', label: '自然环境', name: 'natural', additionalProps: { placeholder: '请输入自然环境' } },
  324. { type: 'text', label: '社会环境', name: 'social', additionalProps: { placeholder: '请输入社会环境' } },
  325. { type: 'text', label: '历史沿革', name: 'history', additionalProps: { placeholder: '请输入历史沿革' } },
  326. { type: 'text', label: '续存状态', name: 'existence', additionalProps: { placeholder: '请输入续存状态' } },
  327. { type: 'text', label: '价值', name: 'meaning', additionalProps: { placeholder: '请输入价值' } },
  328. { type: 'text', label: '相关实物', name: 'prop', additionalProps: { placeholder: '请输入相关实物' } },
  329. { type: 'text', label: '其他基本情况', name: 'other', additionalProps: { placeholder: '请输入其他基本情况' } },
  330. { type: 'mulit-image', label: '相关图片', name: 'images', additionalProps: { placeholder: '请上传相关图片', uploadCo: useImageSimpleUploadCo() } },
  331. { type: 'text', label: '相关习俗', name: 'folkCulture', additionalProps: { placeholder: '请输入相关习俗' } },
  332. { type: 'text', label: '文物古迹', name: 'culturalRelic', additionalProps: { placeholder: '请输入文物古迹' } },
  333. { type: 'text', label: '文献资料', name: 'literature', additionalProps: { placeholder: '请输入文献资料' } },
  334. { type: 'text', label: '组织机构', name: 'organization', additionalProps: { placeholder: '请输入组织机构' } },
  335. { type: 'text-area', label: '项目描述', name: 'description', additionalProps: { placeholder: '请输入项目描述' } },
  336. { type: 'text-area', label: '简介', name: 'desc', additionalProps: { placeholder: '请输入简介' } },
  337. { type: 'text', label: '申报地区', name: 'declarationRegion', additionalProps: { placeholder: '请输入申报地区' } },
  338. { type: 'text', label: '流行地区', name: 'popularRegion', additionalProps: { placeholder: '请输入流行地区' } },
  339. ],
  340. formRules: {
  341. protectLevel: [{ required: true, message: '请选择保护级别' }],
  342. }
  343. });
  344. async function loadData(id: number|undefined) {
  345. formModel.value = await InheritorContent.getIchInfo(id);
  346. formModel.value.expandInfo = await InheritorContent.getIchExpandInfo(id);
  347. formExtendModel.value = formModel.value.expandInfo || new IchExpandInfo();
  348. }
  349. </script>