match.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <template>
  2. <div class="index">
  3. <el-row>
  4. <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
  5. <custom-form v-model="form" :fields="formFields" :rules="rules" @save="toSave" @draftSave="toDraftSave">
  6. <template #video>
  7. <custom-upload model="video" :list="form.video" :limit="1" url="/files/web/cxyy_match/upload" @change="onUpload"></custom-upload>
  8. </template>
  9. <template #file>
  10. <custom-upload model="file" :list="form.file" :limit="1" listType="picture-card" url="/files/web/cxyy_match/upload" @change="onUpload"></custom-upload>
  11. </template>
  12. <template #is_use>
  13. <el-radio v-for="i in isUseList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
  14. </template>
  15. <template #industry>
  16. <el-option v-for="i in sectorList" :key="i.id" :label="i.title" :value="i.title"></el-option>
  17. </template>
  18. <template #scale>
  19. <el-radio v-for="i in scaleList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
  20. </template>
  21. <template #match_type>
  22. <el-radio v-for="i in matchTypeList" :key="i.id" :label="i.value">{{ i.label }}</el-radio>
  23. </template>
  24. <template #type>
  25. <el-option v-for="i in typeList" :key="i.id" :label="i.label" :value="i.value"></el-option>
  26. </template>
  27. <template #form>
  28. <el-option v-for="i in formList" :key="i.id" :label="i.label" :value="i.value"></el-option>
  29. </template>
  30. <template #tags>
  31. <el-select v-model="form.tags" multiple filterable allow-create default-first-option :reserve-keyword="false" placeholder="请选择标签" style="width: 100%">
  32. <el-option v-for="item in tagsList" :key="item.id" :label="item.title" :value="item.title" />
  33. </el-select>
  34. </template>
  35. <template #rules>
  36. <div class="rules">
  37. <custom-form v-model="form.rules" :fields="rulesFields" :useSave="false">
  38. <template #rules1>
  39. <WangEditor v-model="form.rules.rules1" />
  40. </template>
  41. <template #rules2>
  42. <WangEditor v-model="form.rules.rules2" />
  43. </template>
  44. <template #rules3>
  45. <WangEditor v-model="form.rules.rules3" />
  46. </template>
  47. <template #rules4>
  48. <WangEditor v-model="form.rules.rules4" />
  49. </template>
  50. <template #rules5>
  51. <WangEditor v-model="form.rules.rules5" />
  52. </template>
  53. <template #rules6>
  54. <WangEditor v-model="form.rules.rules6" />
  55. </template>
  56. <template #rules7>
  57. <WangEditor v-model="form.rules.rules7" />
  58. </template>
  59. <template #rules8>
  60. <WangEditor v-model="form.rules.rules8" />
  61. </template>
  62. <template #rules9>
  63. <WangEditor v-model="form.rules.rules9" />
  64. </template>
  65. <template #rules10>
  66. <WangEditor v-model="form.rules.rules10" />
  67. </template>
  68. <template #rules11>
  69. <WangEditor v-model="form.rules.rules11" />
  70. </template>
  71. <template #rules12>
  72. <WangEditor v-model="form.rules.rules12" />
  73. </template>
  74. </custom-form>
  75. </div>
  76. </template>
  77. <template #brief>
  78. <WangEditor v-model="form.brief" />
  79. </template>
  80. <template #process>
  81. <el-col :span="24" class="tables">
  82. <el-col :span="24" class="tables_1">
  83. <el-button type="primary" @click="addProcess()">添加</el-button>
  84. </el-col>
  85. <el-col :span="24">
  86. <el-table :data="processList" border>
  87. <el-table-column type="index" label="序号" width="80" align="center"> </el-table-column>
  88. <el-table-column prop="name" label="流程名称" align="center">
  89. <template #default="scope">
  90. <el-input v-model="scope.row.name" placeholder="请输入流程名称" />
  91. </template>
  92. </el-table-column>
  93. <el-table-column prop="order_num" label="排序" align="center">
  94. <template #default="scope">
  95. <el-input v-model="scope.row.order_num" type="number" placeholder="请输入排序" />
  96. </template>
  97. </el-table-column>
  98. <el-table-column prop="is_use" label="是否启用" align="center">
  99. <template #default="scope">
  100. <el-select v-model="scope.row.is_use" placeholder="请选择是否启用">
  101. <el-option v-for="item in isUseList" :key="item.value" :label="item.label" :value="item.value" />
  102. </el-select>
  103. </template>
  104. </el-table-column>
  105. <el-table-column label="操作" align="center" width="100">
  106. <template #default="scope">
  107. <el-button type="danger" @click="delProcess(scope.row)">删除</el-button>
  108. </template>
  109. </el-table-column>
  110. </el-table>
  111. </el-col>
  112. </el-col>
  113. </template>
  114. </custom-form>
  115. </el-col>
  116. </el-row>
  117. </div>
  118. </template>
  119. <script setup>
  120. // 组件
  121. import moment from 'moment'
  122. import { cloneDeep, get } from 'lodash-es'
  123. const $checkRes = inject('$checkRes')
  124. import { UserStore } from '@/store/user'
  125. const userStore = UserStore()
  126. const user = computed(() => userStore.user)
  127. // 接口
  128. import { MatchStore } from '@/store/api/platform/match'
  129. import { ProcessStore } from '@/store/api/platform/process'
  130. import { DictDataStore } from '@/store/api/system/dictData'
  131. import { TagsStore } from '@/store/api/system/tags'
  132. import { SectorStore } from '@/store/api/platform/sector'
  133. const store = MatchStore()
  134. const dictDataStore = DictDataStore()
  135. const tagsStore = TagsStore()
  136. const sectorStore = SectorStore()
  137. const processStore = ProcessStore()
  138. // 加载中
  139. const loading = ref(false)
  140. // 字典表
  141. const isUseList = ref([])
  142. const statusList = ref([])
  143. const typeList = ref([])
  144. const matchList = ref([])
  145. const formList = ref([])
  146. const tagsList = ref([])
  147. const sectorList = ref([])
  148. const matchTypeList = ref([])
  149. const scaleList = ref([])
  150. // 流程列表
  151. const processList = ref([])
  152. const form = ref({ time: [], rules: {} })
  153. const formFields = ref([
  154. { label: '封面', model: 'file', custom: true },
  155. { label: '赛事名称', model: 'name' },
  156. { label: '标签', model: 'tags', custom: true },
  157. { label: '类型', model: 'type', type: 'select' },
  158. { label: '赛事规模', model: 'scale', type: 'radio' },
  159. { label: '赛事类型', model: 'match_type', type: 'radio' },
  160. { label: '路由', model: 'href', display: () => form.value.match_type == '1' },
  161. { label: '组织单位', model: 'work' },
  162. { label: '所属产业', model: 'industry', type: 'select' },
  163. { label: '类别', model: 'form', type: 'select' },
  164. { label: '奖金(万元)', model: 'money' },
  165. { label: '有效期', model: 'time', type: 'daterange' },
  166. { label: '是否启用', model: 'is_use', type: 'radio' },
  167. { model: 'rules', custom: true },
  168. { label: '简介', model: 'brief', custom: true },
  169. { label: '视频', model: 'video', custom: true },
  170. { label: '赛事流程', model: 'process', custom: true }
  171. ])
  172. // 赛事规则
  173. const rulesFields = ref([
  174. { label: '大赛背景', model: 'rules1', custom: true },
  175. { label: '大赛主题和目标', model: 'rules2', custom: true },
  176. { label: '大赛基本情况介绍', model: 'rules3', custom: true },
  177. { label: '赛题任务', model: 'rules4', custom: true },
  178. { label: '赛程安排', model: 'rules5', custom: true },
  179. { label: '赛制阶段', model: 'rules6', custom: true },
  180. { label: '参赛资格', model: 'rules7', custom: true },
  181. { label: '参赛报名', model: 'rules8', custom: true },
  182. { label: '奖项设置与奖励办法', model: 'rules9', custom: true },
  183. { label: '组织单位', model: 'rules10', custom: true },
  184. { label: '赛事联络', model: 'rules11', custom: true },
  185. { label: '赛事交流', model: 'rules12', custom: true }
  186. ])
  187. const rules = reactive({ name: [{ required: true, message: '请输入赛事名称', trigger: 'blur' }], form: [{ required: true, message: '请选择类别', trigger: 'blur' }] })
  188. // 请求
  189. onMounted(async () => {
  190. loading.value = true
  191. await searchOther()
  192. loading.value = false
  193. })
  194. const searchOther = async () => {
  195. let result
  196. // 是否使用
  197. result = await dictDataStore.query({ code: 'isUse', is_use: '0' })
  198. if ($checkRes(result)) isUseList.value = result.data
  199. // 类型
  200. result = await dictDataStore.query({ code: 'matchType', is_use: '0' })
  201. if ($checkRes(result)) typeList.value = result.data
  202. // 赛事类型
  203. result = await dictDataStore.query({ code: 'activeType', is_use: '0' })
  204. if ($checkRes(result)) matchTypeList.value = result.data
  205. // 类别
  206. result = await dictDataStore.query({ code: 'matchForm', is_use: '0' })
  207. if ($checkRes(result)) formList.value = result.data
  208. // 状态
  209. result = await dictDataStore.query({ code: 'examStatus', is_use: '0' })
  210. if ($checkRes(result)) statusList.value = result.data
  211. // 赛事状态
  212. result = await dictDataStore.query({ code: 'matchStatus', is_use: '0' })
  213. if ($checkRes(result)) matchList.value = result.data
  214. // 赛事规模
  215. result = await dictDataStore.query({ code: 'matchScale', is_use: '0' })
  216. if ($checkRes(result)) scaleList.value = result.data
  217. // 标签
  218. result = await tagsStore.query({ is_use: '0' })
  219. if ($checkRes(result)) tagsList.value = result.data
  220. // 行业
  221. result = await sectorStore.query({ is_use: '0' })
  222. if ($checkRes(result)) sectorList.value = result.data
  223. }
  224. const toSave = async () => {
  225. const data = cloneDeep(form.value)
  226. const other = { status: '0', user: user.value.id }
  227. if (data.time && data.time.length > 1) {
  228. data.start_time = data.time[0]
  229. data.end_time = data.time[1]
  230. }
  231. delete data.time
  232. let res
  233. if (get(data, 'id')) res = await store.update({ ...data, ...other })
  234. else res = await store.create({ ...data, ...other })
  235. if ($checkRes(res, true)) {
  236. ElMessage({ message: `发布成功可以上历史发布查看`, type: 'success' })
  237. form.value = {}
  238. }
  239. }
  240. const toDraftSave = async () => {
  241. const data = cloneDeep(form.value)
  242. const other = { status: '-2', user: user.value.id }
  243. if (data.time && data.time.length > 1) {
  244. data.start_time = data.time[0]
  245. data.end_time = data.time[1]
  246. }
  247. delete data.time
  248. let res
  249. if (get(data, 'id')) res = await store.update({ ...data, ...other })
  250. else res = await store.create({ ...data, ...other })
  251. if ($checkRes(res, true)) {
  252. ElMessage({ message: `发布成功可以上历史发布查看`, type: 'success' })
  253. form.value = {}
  254. }
  255. }
  256. // 上传图片
  257. const onUpload = (e) => {
  258. const { model, value } = e
  259. form.value[model] = value
  260. }
  261. // 流程添加
  262. const addProcess = () => {
  263. let list = processList.value || []
  264. list.push({ sid: moment().valueOf(), name: '', time: '', is_use: '' })
  265. processList.value = list
  266. }
  267. // 流程删除
  268. const delProcess = async (e) => {
  269. let list = processList.value.filter((i) => i.sid != e.sid)
  270. processList.value = list
  271. if (e.id) await processStore.del(e.id)
  272. }
  273. </script>
  274. <style scoped lang="scss">
  275. .main {
  276. .tables {
  277. .tables_1 {
  278. margin: 0 0 10px 0;
  279. }
  280. }
  281. }
  282. </style>