competitionCommon.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <template>
  2. <div class="p-8px bg-white">
  3. <div class="px-4">
  4. <BasicForm @register="registerForm">
  5. <template #title1>
  6. <TypographyTitle :level="4">基础信息</TypographyTitle>
  7. <Divider></Divider>
  8. </template>
  9. <template #RangePicker>
  10. <TypographyTitle :level="4">比赛时间及赛程安排</TypographyTitle>
  11. <Divider></Divider>
  12. </template>
  13. <template #ZtCustomTable1="{ model, field }">
  14. <ZtCustomTable
  15. :tableColumn="ScheduleArrangementColums"
  16. v-model:value="model[field]"
  17. v-model:deleteId="model['scheduleDTOSList']"
  18. ></ZtCustomTable>
  19. </template>
  20. <template #title3>
  21. <TypographyTitle :level="4">比赛项目、价格、地点、说明</TypographyTitle>
  22. <Divider></Divider>
  23. </template>
  24. <template #ZtCustomTable2="{ model, field }">
  25. <ZtCustomTable
  26. :tableColumn="SchedulePricesColums"
  27. v-model:value="model[field]"
  28. v-model:deleteId="model['gamePriceRulesList']"
  29. ></ZtCustomTable>
  30. </template>
  31. <template #title4>
  32. <TypographyTitle :level="4">配套保险</TypographyTitle>
  33. <Divider></Divider>
  34. </template>
  35. <template #address="{ model, field }">
  36. <JAreaSelect v-model:province="model['provinceCode']" v-model:city="model['cityCode']" v-model:area="model['areaCode']"></JAreaSelect>
  37. </template>
  38. <template #aptitudes="{ model, field }">
  39. <div class="flex flex-wrap">
  40. <a-button type="primary" @click="model[field].push({ name: '' })">添加资质</a-button>
  41. <div class="ml20px flex mb-20px" v-for="(item, idx) in model[field]" :key="idx">
  42. <FormItem>
  43. <a-input v-model:value="item.name" placeholder="请输入资质">
  44. <template #suffix>
  45. <a-button type="primary" danger @click="model[field].splice(idx, 1)">删除</a-button>
  46. </template>
  47. </a-input>
  48. </FormItem>
  49. </div>
  50. </div>
  51. </template>
  52. <template #formFooter>
  53. <div style="margin: 0 auto">
  54. <a-button type="primary" @click="save" class="mr-2" :loading="isSubmit"> 保存 </a-button>
  55. <a-button type="error" @click="back" class="mr-2"> 关闭 </a-button>
  56. </div>
  57. </template>
  58. </BasicForm>
  59. <div class="h-20px"></div>
  60. </div>
  61. </div>
  62. </template>
  63. <script lang="ts" setup name="business-management-competitionCommon">
  64. import { TypographyTitle, Divider, FormItem, Input, Button } from 'ant-design-vue';
  65. import { BasicForm, useForm, JAreaSelect } from '/@/components/Form/index';
  66. import ZtCustomTable from '/@/components/ZtCustomTable/index.vue';
  67. import { formSchema, SchedulePricesColums } from './competition.data';
  68. import { BasicColumn } from '/@/components/Table';
  69. import { getSprotProject } from '@/api/common/api';
  70. import { getDetaile, saveOrUpdate } from './competition.api';
  71. import dayjs from 'dayjs';
  72. import { nextTick, onUnmounted, ref, toRefs, unref, watch, watchEffect } from 'vue';
  73. import { areAllItemsAllFieldsFilled, extractRefs } from '/@/utils';
  74. import { message } from 'ant-design-vue/lib';
  75. import { useRoute } from 'vue-router';
  76. import { useTabs } from '/@/hooks/web/useTabs';
  77. import { getDataByCode } from '@/components/Form/src/utils/areaDataUtil';
  78. import { matchCityByFirstFourDigits, matchProvinceByFirstThreeDigits } from '/@/utils/map';
  79. const { close: closeTab } = useTabs();
  80. const route = useRoute();
  81. const [registerForm, { setProps, resetFields, setFieldsValue, updateSchema, validate, clearValidate, getFieldsValue }] = useForm({
  82. schemas: formSchema,
  83. showActionButtonGroup: false,
  84. });
  85. const isSubmit = ref(false);
  86. async function back() {
  87. await closeTab();
  88. }
  89. async function save() {
  90. await validate();
  91. const form = getFieldsValue();
  92. const gamePriceRules = form.gamePriceRules.map((it) => {
  93. return {
  94. ...extractRefs(it.editValueRefs),
  95. id: it.id,
  96. };
  97. });
  98. const scheduleRules = form.scheduleDTOS.map((it) => {
  99. return {
  100. ...extractRefs(it.editValueRefs),
  101. id: it.id,
  102. };
  103. });
  104. console.log(form, '表单数据');
  105. if (!valiDataCustom(gamePriceRules) || !valiDataCustom(scheduleRules)) {
  106. return message.error('请填写完整');
  107. }
  108. const newObj = {
  109. game: {
  110. ...form,
  111. aptitudes: form.aptitudes ? form.aptitudes.map((it) => it.name).join(',') : null,
  112. endTime: form.competitionTime.split(',')[1],
  113. startTime: form.competitionTime.split(',')[0],
  114. id: route.query.id,
  115. gamePriceRules: null,
  116. scheduleDTOS: null,
  117. },
  118. gamePriceRules: gamePriceRules,
  119. scheduleDTOSList: form.scheduleDTOSList,
  120. gamePriceRulesList: form.gamePriceRulesList,
  121. scheduleDTOS: scheduleRules.map((it) => {
  122. return {
  123. ...it,
  124. startTime: it.time[0],
  125. endTime: it.time[1],
  126. };
  127. }),
  128. };
  129. isSubmit.value = true;
  130. try {
  131. await saveOrUpdate(newObj, Number(route.query.type) == 1);
  132. isSubmit.value = false;
  133. back();
  134. } catch (error) {
  135. console.log(error);
  136. isSubmit.value = false;
  137. }
  138. }
  139. const ScheduleArrangementColums: BasicColumn[] = [
  140. {
  141. title: '名称',
  142. dataIndex: 'name',
  143. width: 220,
  144. editComponent: 'Input',
  145. editRule: true,
  146. editRow: true,
  147. editable: true,
  148. editComponentProps: {
  149. placeholder: '请输入名称',
  150. size: 'middle',
  151. },
  152. },
  153. {
  154. title: '时间段',
  155. dataIndex: 'time',
  156. width: 450,
  157. editComponent: 'RangePicker',
  158. editRule: true,
  159. editComponentProps: {
  160. showTime: true,
  161. size: 'middle',
  162. placeholder: ['开始时间', '结束时间'],
  163. valueFormat: 'YYYY-MM-DD HH:mm:ss',
  164. disabledDate: (current) => {
  165. const fields = getFieldsValue();
  166. if (fields.competitionTime && fields.competitionTime.length >= 2) {
  167. const [startDate, endDate] = fields.competitionTime.split(',');
  168. return current && (current < dayjs(startDate).startOf('day') || current > dayjs(endDate).endOf('day'));
  169. }
  170. return current && current < dayjs().endOf('day');
  171. },
  172. },
  173. editRow: true,
  174. editable: true,
  175. },
  176. {
  177. title: '安排',
  178. dataIndex: 'arrange',
  179. width: 220,
  180. editComponent: 'Input',
  181. editRule: true,
  182. editRow: true,
  183. editable: true,
  184. editComponentProps: {
  185. size: 'middle',
  186. },
  187. },
  188. {
  189. key: 'op',
  190. dataIndex: 'operation',
  191. title: 'operation',
  192. fixed: 'right',
  193. width: 80,
  194. },
  195. ];
  196. function valiDataCustom(data) {
  197. if (!areAllItemsAllFieldsFilled(data)) {
  198. return false;
  199. }
  200. return true;
  201. }
  202. async function getDetaileData() {
  203. const res = await getDetaile({ id: route.query.id });
  204. setFieldsValue({
  205. ...res.game,
  206. competitionTime: [res.game.startTime, res.game.endTime],
  207. gamePriceRules: res.gamePriceRules.map((it) => {
  208. return {
  209. ...it,
  210. type: String(it.type),
  211. };
  212. }),
  213. scheduleDTOS: res.scheduleDTOS.map((it) => {
  214. return {
  215. ...it,
  216. time: [it.startTime, it.endTime],
  217. };
  218. }),
  219. aptitudes: res.game.aptitudes.split(',').map((it) => {
  220. return {
  221. name: it,
  222. };
  223. }),
  224. });
  225. }
  226. watch(
  227. () => route.query.type,
  228. () => {
  229. if (Number(route.query.type) != 0) {
  230. getDetaileData();
  231. }
  232. },
  233. { immediate: true }
  234. );
  235. </script>
  236. <style>
  237. /* #panel {
  238. position: absolute;
  239. background-color: white;
  240. max-height: 300px;
  241. overflow-y: auto;
  242. top: 10px;
  243. right: 10px;
  244. width: 280px;
  245. } */
  246. </style>