seminar.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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="SeminarInfo"
  11. />
  12. </template>
  13. <script setup lang="ts">
  14. import { ref, type Ref } from 'vue';
  15. import Form from './form.vue';
  16. import InheritorContent, { SeminarExpandInfo, SeminarInfo } from '@/api/inheritor/InheritorContent';
  17. import CommonContent from '@/api/CommonContent';
  18. import type { IDynamicFormOptions, IDynamicFormRef } from '@imengyu/vue-dynamic-form';
  19. import type { AddressItem } from '@/components/dynamicf/Map/AddressSercher.vue';
  20. import { useAuthStore } from '@/stores/auth';
  21. import { useAliOssUploadCo } from '@/common/upload/AliOssUploadCo';
  22. import { useBeforeUploadImageChecker, type UploadImageFormItemProps } from '@/components/dynamicf/UploadImageFormItem';
  23. import { useRoute } from 'vue-router';
  24. const authStore = useAuthStore();
  25. const formRef = ref();
  26. const formModel = ref(new SeminarInfo()) as Ref<SeminarInfo>;
  27. const formOptions = ref<IDynamicFormOptions>({
  28. formLabelCol: { span: 6 },
  29. formWrapperCol: { span: 24 },
  30. formAdditionaProps: {
  31. layout: 'vertical',
  32. scrollToFirstError: true,
  33. },
  34. formNestNameGenerateType: 'array',
  35. formItems: [
  36. {
  37. type: 'group-flat', label: '传习所/保护单位信息', name: 'seminarInfo',
  38. childrenColProps: { span: 24 },
  39. children: [
  40. {
  41. label: '传习所名称', name: 'title', type: 'text',
  42. additionalProps: { placeholder: '请输入标题' },
  43. },
  44. {
  45. label: '批次', name: 'batch', type: 'select-id',
  46. additionalProps: {
  47. placeholder: '请选择批次',
  48. loadData: async () => (await CommonContent.getCategoryList(289)).map(p => ({ label: p.title, value: p.id, raw: p }))
  49. },
  50. },
  51. {
  52. label: '传习所级别', name: 'level', type: 'select-id',
  53. additionalProps: {
  54. placeholder: '请选择传习所级别',
  55. loadData: async () => (await CommonContent.getCategoryList(2)).map(p => ({ label: p.title, value: p.id, raw: p }))
  56. },
  57. },{
  58. label: '图片', name: 'image', type: 'single-image',
  59. additionalProps: {
  60. placeholder: '请上传图片',
  61. name: 'file',
  62. accept: 'image/*',
  63. beforeUpload: useBeforeUploadImageChecker(),
  64. uploadCo: useAliOssUploadCo('seminar/images')
  65. } as UploadImageFormItemProps,
  66. },
  67. { label: '传习所介绍', name: 'content', type: 'richtext', additionalProps: { placeholder: '请输入内容' } },
  68. { label: '传习所地址', name: 'address', type: 'address-sercher',
  69. additionalProps: { placeholder: '请输入地址' },
  70. additionalEvents: {
  71. choosedAddress: (address: AddressItem) => {
  72. ((formRef.value?.getFormRef() as IDynamicFormRef).getFormItemControlRef('lonlat') as any).moveTo([
  73. address.lng, address.lat
  74. ], 20)
  75. },
  76. }
  77. },
  78. { label: '地图坐标', name: 'lonlat', type: 'map-pick-point' },
  79. /* {
  80. type: 'simple-flat', label: '', name: 'map',
  81. childrenColProps: { span: 12 },
  82. children: [
  83. { label: '平面坐标X', name: 'mapX', type: 'number', additionalProps: { placeholder: '请输入平面坐标X' } },
  84. { label: '平面坐标Y', name: 'mapY', type: 'number', additionalProps: { placeholder: '请输入平面坐标Y' } },
  85. ]
  86. }, */
  87. { label: '联系人', name: 'contact', type: 'text', additionalProps: { placeholder: '请输入联系人' } },
  88. { label: '联系电话', name: 'mobile', type: 'text', additionalProps: { placeholder: '请输入联系电话' } },
  89. {
  90. label: '传习所/保护单位类型', name: 'ichSiteType', type: 'select',
  91. additionalProps: {
  92. placeholder: '请选择非遗单位类型',
  93. options: [
  94. { text: '传习所', value: 1 },
  95. { text: '保护单位', value: 2 }
  96. ]
  97. },
  98. },
  99. {
  100. label: '是否对游客开放', name: 'visit', type: 'select',
  101. additionalProps: {
  102. placeholder: '请选择是否对游客开放',
  103. options: [
  104. { text: '否', value: 0 },
  105. { text: '是', value: 1 }
  106. ]
  107. },
  108. },
  109. {
  110. label: '审核人员', name: 'text1', type: 'static-text',
  111. additionalProps: {
  112. text: '黄念旭,李向群,卢志明',
  113. style: { color: '#999', }
  114. }
  115. },
  116. {
  117. label: '审核状态', name: 'text2', type: 'static-text',
  118. additionalProps: {
  119. text: '暂未审核',
  120. style: { color: '#999', }
  121. }
  122. },
  123. {
  124. label: '填报人', name: 'text3', type: 'static-text',
  125. additionalProps: {
  126. text: authStore.userInfo?.nickname,
  127. }
  128. },
  129. ]
  130. },
  131. /* {
  132. type: 'group-flat', label: '通用信息', name: 'commonInfo',
  133. childrenColProps: { span: 24 },
  134. children: [
  135. {
  136. label: '地区', name: 'region', type: 'select-id',
  137. additionalProps: {
  138. placeholder: '请选择地区',
  139. loadData: async () => (await CommonContent.getCategoryList(1)).map(p => ({ label: p.title, value: p.id, raw: p })) ,
  140. },
  141. },
  142. {
  143. label: '类型', name: 'type', type: 'select',
  144. additionalProps: {
  145. placeholder: '请选择类型',
  146. options: [
  147. { text: '文章', value: 1 },
  148. { text: '音频', value: 2 },
  149. { text: '视频', value: 3 },
  150. { text: '相册', value: 4 },
  151. { text: '数字档案', value: 5 }]
  152. },
  153. },
  154. {
  155. label: '图片说明', name: 'imageDesc', type: 'text',
  156. additionalProps: { placeholder: '请输入图片说明' }
  157. },
  158. {
  159. label: '转自', name: 'from', type: 'text',
  160. additionalProps: { placeholder: '请输入来源' },
  161. },
  162. {
  163. label: '组图', name: 'images', type: 'mulit-image',
  164. hidden: { callback: (_, model) => (model as SeminarInfo).type !== 4 },
  165. additionalProps: {
  166. placeholder: '请上传图片',
  167. maxCount: 20,
  168. name: 'file',
  169. accept: 'image/*',
  170. beforeUpload: useBeforeUploadImageChecker(),
  171. uploadCo: useAliOssUploadCo('seminar/images'),
  172. } as UploadImageFormItemProps,
  173. },
  174. {
  175. label: '音频', name: 'audio', type: 'single-image',
  176. hidden: { callback: (_, model) => (model as SeminarInfo).type !== 2 },
  177. additionalProps: {
  178. placeholder: '请上传音频',
  179. name: 'file',
  180. accept: 'audio/*',
  181. beforeUpload: useBeforeUploadAudioChecker(),
  182. uploadCo: useAliOssUploadCo('seminar/audios')
  183. } as UploadImageFormItemProps,
  184. },
  185. {
  186. label: '相关视频', name: 'video', type: 'single-video',
  187. hidden: { callback: (_, model) => (model as SeminarInfo).type !== 3 },
  188. additionalProps: {
  189. placeholder: '请上传视频',
  190. name: 'file',
  191. accept: 'video/*',
  192. beforeUpload: useBeforeUploadVideoChecker(),
  193. uploadCo: useAliOssUploadCo('seminar/videos')
  194. } as UploadImageFormItemProps,
  195. },
  196. {
  197. label: '数字档案', name: 'archives', type: 'mulit-image',
  198. hidden: { callback: (_, model) => (model as SeminarInfo).type !== 5 },
  199. additionalProps: {
  200. placeholder: '请上传数字档案',
  201. maxCount: 20,
  202. name: 'file',
  203. uploadCo: useAliOssUploadCo('seminar/archives')
  204. } as UploadImageFormItemProps,
  205. },
  206. {
  207. label: '标志', name: 'flag', type: 'select',
  208. additionalProps: {
  209. mode: 'tags',
  210. options: [
  211. { text: '热门', value: 'hot' },
  212. { text: '推荐', value: 'recommend' },
  213. { text: '置顶', value: 'top' },
  214. ],
  215. placeholder: '请输入标志'
  216. } as SelectProps,
  217. },
  218. {
  219. label: '关键字', name: 'keywords', type: 'select',
  220. additionalProps: {
  221. mode: 'tags',
  222. options: [],
  223. placeholder: '请输入关键字,回车添加'
  224. } as SelectProps,
  225. },
  226. {
  227. label: '描述', name: 'desc', type: 'text-area',
  228. additionalProps: { placeholder: '请输入描述' },
  229. },
  230. {
  231. label: 'TAG', name: 'tags', type: 'text',
  232. additionalProps: { placeholder: '请输入TAG' },
  233. },
  234. {
  235. label: '备注', name: 'memo', type: 'text-area',
  236. additionalProps: { placeholder: '请输入备注' },
  237. },
  238. ]
  239. }, */
  240. ],
  241. formRules: {
  242. expandInfo: {
  243. protectLevel: [{ required: true, message: '请选择保护级别' }],
  244. },
  245. title: [{ required: true, message: '请输入标题' }],
  246. region: [{ required: true, message: '请选择地区' }],
  247. type: [{ required: true, message: '请选择类型' }],
  248. image: [{ required: true, message: '请上传图片' }],
  249. level: [{ required: true, message: '请选择级别' }],
  250. ichType: [{ required: true, message: '请选择非遗类型' }],
  251. batch: [{ required: true, message: '请输入批次' }]
  252. }
  253. });
  254. const formExtendModel = ref(new SeminarExpandInfo()) as Ref<SeminarExpandInfo>;
  255. const formExtendOptions = ref<IDynamicFormOptions>({
  256. formLabelCol: { span: 6 },
  257. formWrapperCol: { span: 24 },
  258. formAdditionaProps: {
  259. layout: 'vertical',
  260. scrollToFirstError: true,
  261. },
  262. formNestNameGenerateType: 'array',
  263. formItems: [
  264. { label: '持有者', name: 'holders', type: 'text', additionalProps: { placeholder: '请输入持有者' } },
  265. { label: '地区', name: 'region', type: 'select-id', additionalProps: { placeholder: '请选择地区', loadData: async () => (await CommonContent.getCategoryList(1)).map(p => ({ label: p.title, value: p.id, raw: p })) } },
  266. { label: '地图坐标', name: 'lonlat', type: 'map-pick-point' },
  267. {
  268. type: 'simple-flat', label: '', name: 'map',
  269. childrenColProps: { span: 12 },
  270. children: [
  271. { label: '平面坐标X', name: 'mapX', type: 'number', additionalProps: { placeholder: '请输入平面坐标X' } },
  272. { label: '平面坐标Y', name: 'mapY', type: 'number', additionalProps: { placeholder: '请输入平面坐标Y' } },
  273. ]
  274. },
  275. { label: '成立时间', name: 'openTime', type: 'date-time', additionalProps: { placeholder: '请选择成立时间' } },
  276. { label: '图片', name: 'image', type: 'single-image', additionalProps: { placeholder: '请上传图片', uploadCo: useAliOssUploadCo('seminar/images') } },
  277. { label: '相关图片', name: 'images', type: 'mulit-image', additionalProps: { placeholder: '请上传相关图片', uploadCo: useAliOssUploadCo('seminar/images') } },
  278. { label: '地址', name: 'address', type: 'text', additionalProps: { placeholder: '请输入地址' } },
  279. { label: '描述', name: 'intro', type: 'text-area', additionalProps: { placeholder: '请输入描述' } },
  280. { label: '简介', name: 'desc', type: 'text-area', additionalProps: { placeholder: '请输入简介' } }
  281. ],
  282. formRules: {
  283. region: [{ required: true, message: '请选择地区' }]
  284. }
  285. });
  286. const route = useRoute();
  287. async function loadData(id: number|undefined) {
  288. formModel.value = id === undefined || id > 0 ? await InheritorContent.getSeminarInfo(id) : new SeminarInfo();
  289. if (id === -1)
  290. formModel.value.associationId = (route.query.ichId ? parseFloat(route.query.ichId as string) : undefined) ?? 0;
  291. formModel.value.expandInfo = id ? await InheritorContent.getSeminarExpandInfo(id) : new SeminarExpandInfo();
  292. formExtendModel.value = formModel.value.expandInfo || new SeminarExpandInfo();
  293. }
  294. </script>