EventDetailsView.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. <!--
  2. * @Author: fxs bjnsfxs@163.com
  3. * @Date: 2024-09-18
  4. * @LastEditors: fxs bjnsfxs@163.com
  5. * @LastEditTime: 2024-12-07
  6. * @Description:
  7. *
  8. -->
  9. <script setup lang="ts">
  10. import type { ReqConfig } from '@/types/dataAnalysis'
  11. import type { FormConfig, FormField } from '@/types/form'
  12. import { FormFieldType } from '@/types/form'
  13. import type { FormRules } from 'element-plus'
  14. import { ElMessageBox } from 'element-plus'
  15. import type { DialogConfig } from '@/types/dialog'
  16. import type { TableFieldInfo, TablePaginationSetting, TableToolsConfig } from '@/types/table'
  17. import { FieldSpecialEffectType, TextType } from '@/types/tableText'
  18. import { onUnmounted, reactive, ref, watch } from 'vue'
  19. import { useRoute } from 'vue-router'
  20. import { useRequest } from '@/hooks/useRequest'
  21. import { useCommonStore } from '@/stores/useCommon'
  22. import Form from '@/components/form/CustomForm.vue'
  23. import Table from '@/components/table/CustomTable.vue'
  24. import Dialog from '@/components/common/CustomDialog.vue'
  25. import FileUpload from '@/components/form/FileUpload.vue'
  26. import axiosInstance from '@/utils/axios/axiosInstance'
  27. import router from '@/router'
  28. const { selectInfo } = useCommonStore()
  29. const { AllApi, analysisResCode } = useRequest()
  30. defineEmits(['tableDataLoaded', 'upload'])
  31. // 事件表单对象
  32. const eventFormRef = ref()
  33. // 参数表格ref对象
  34. const optionTableRef = ref()
  35. // 是否是新增触发
  36. const isAdd = ref(true)
  37. // 事件ID,这里的actionID,在获取事件详情的时候传入的字段是id字段,但是在获取
  38. // 参数列表的时候,传入的是actionId字段
  39. const actionId = ref()
  40. // 编辑状态
  41. const eventEditState = ref(false)
  42. // 属性对话框
  43. const attrDialog = ref()
  44. // 上传ref
  45. const uploadRef = ref<InstanceType<typeof FileUpload> | null>(null)
  46. // 上传的信息
  47. const uploadInfo = reactive({
  48. dialogTitle: '上传事件信息'
  49. })
  50. // 表单规则字段
  51. const ruleForm = reactive({
  52. // actionId:"",
  53. actionName: '',
  54. status: 1,
  55. remark: ''
  56. })
  57. // 表单规则
  58. const rules = reactive<FormRules<typeof ruleForm>>({
  59. actionName: [
  60. { required: true, message: '事件名称是必填项', trigger: 'blur' },
  61. { min: 5, max: 20, message: '事件名称长度必须在5到20之间', trigger: 'blur' }
  62. ],
  63. remark: [
  64. { required: false, message: '备注是可选项', trigger: 'blur' },
  65. { max: 100, message: '备注长度不能超过100个字符', trigger: 'blur' }
  66. ],
  67. status: [
  68. { required: true, message: '是否启用是必选项', trigger: 'change' },
  69. { type: 'number', message: '启用状态必须是数字', trigger: 'change' }
  70. ]
  71. })
  72. // 表单字段信息
  73. const FormFields: Array<FormField> = [
  74. {
  75. name: 'actionName',
  76. cnName: '事件名',
  77. type: FormFieldType.INPUT
  78. },
  79. {
  80. name: 'status',
  81. cnName: '使用状态',
  82. type: FormFieldType.SELECT,
  83. otherOptions: {
  84. placeholder: '请选择状态',
  85. options: [
  86. {
  87. name: 'disabled',
  88. label: '禁用',
  89. value: 0
  90. },
  91. {
  92. name: 'able',
  93. label: '启用',
  94. value: 1
  95. }
  96. ]
  97. }
  98. },
  99. {
  100. name: 'remark',
  101. cnName: '备注',
  102. type: FormFieldType.RICHTEXT,
  103. otherOptions: {
  104. placeholder: '请输入备注'
  105. }
  106. }
  107. ]
  108. // 表单请求参数
  109. const formReq = reactive<ReqConfig>({
  110. url: AllApi.updateGameAction,
  111. otherOptions: {}
  112. })
  113. // 表单设置
  114. const formConfig = reactive<FormConfig>({
  115. reqConfig: formReq,
  116. fieldsInfo: FormFields,
  117. rules
  118. })
  119. // 表格分页设置
  120. const pageConfig = reactive<TablePaginationSetting>({
  121. limit: 20,
  122. currentPage: 1,
  123. total: 0,
  124. pageSizeList: [20, 30]
  125. })
  126. // 表格字段信息
  127. const tableFieldConfig = reactive<Array<TableFieldInfo>>([
  128. {
  129. name: 'id',
  130. cnName: 'ID',
  131. isShow: true,
  132. needSort: true
  133. },
  134. {
  135. name: 'actionId',
  136. cnName: '事件ID',
  137. isShow: false,
  138. needSort: false
  139. },
  140. {
  141. name: 'optionId',
  142. cnName: '选项ID',
  143. isShow: true,
  144. needSort: false
  145. },
  146. {
  147. name: 'optionName',
  148. cnName: '选项名称',
  149. isShow: true,
  150. needSort: false
  151. },
  152. {
  153. name: 'optionType',
  154. cnName: '选项类型',
  155. isShow: true,
  156. needSort: false,
  157. specialEffect: {
  158. type: FieldSpecialEffectType.TEXT,
  159. otherInfo: {
  160. textType: TextType.TEXT,
  161. translateMap: {
  162. string: '字符串',
  163. int: '数字',
  164. array: '数组'
  165. }
  166. }
  167. }
  168. },
  169. {
  170. name: 'status',
  171. cnName: '使用状态状态',
  172. isShow: true,
  173. needSort: false,
  174. specialEffect: {
  175. type: FieldSpecialEffectType.TEXT,
  176. otherInfo: {
  177. textType: TextType.TEXT,
  178. translateMap: ['启用', '禁用']
  179. }
  180. }
  181. },
  182. {
  183. name: 'createdAt',
  184. cnName: '创建时间',
  185. isShow: true,
  186. needSort: false
  187. },
  188. {
  189. name: 'updatedAt',
  190. cnName: '更新时间',
  191. isShow: true,
  192. needSort: false
  193. }
  194. ])
  195. // 表格请求配置
  196. const tableReqConfig = reactive<ReqConfig>({
  197. url: AllApi.gameActionOptionList,
  198. otherOptions: {}
  199. })
  200. // 工具栏配置
  201. const tableToolsConfig: TableToolsConfig = {
  202. add: true,
  203. filterFields: true,
  204. refresh: true,
  205. download: false
  206. }
  207. // 对话框请求参数
  208. const dialogReqConfig = reactive<ReqConfig>({
  209. url: AllApi.addGameActionOption,
  210. otherOptions: {
  211. formData: {}
  212. }
  213. })
  214. // 对话框表单规则字段
  215. const dialogRuleForm = reactive({
  216. optionName: '',
  217. optionId: '',
  218. status: 1,
  219. optionType: ''
  220. })
  221. // 表单规则
  222. const dialogRules = reactive<FormRules<typeof dialogRuleForm>>({
  223. optionName: [{ required: true, message: '选项名称是必填项', trigger: 'change', type: 'string' }],
  224. optionId: [{ required: true, message: '选项ID是必填项', trigger: 'change', type: 'string' }],
  225. status: [{ required: true, message: '选项状态是必填项', trigger: 'change', type: 'number' }],
  226. optionType: [
  227. {
  228. required: true,
  229. message: '选项类型是必填项',
  230. trigger: 'change'
  231. }
  232. ]
  233. })
  234. // 表单字段信息
  235. const dialogFormFields: Array<FormField> = [
  236. {
  237. name: 'optionId',
  238. cnName: '选项ID',
  239. type: FormFieldType.INPUT
  240. },
  241. {
  242. name: 'optionName',
  243. cnName: '选项名称',
  244. type: FormFieldType.INPUT
  245. },
  246. {
  247. name: 'status',
  248. cnName: '选项状态',
  249. type: FormFieldType.SELECT,
  250. defaultValue: 1,
  251. otherOptions: {
  252. placeholder: '请选择状态',
  253. options: [
  254. {
  255. name: 'disabled',
  256. label: '禁用',
  257. value: 0 // 对应int型状态
  258. },
  259. {
  260. name: 'able',
  261. label: '启用',
  262. value: 1 // 对应int型状态
  263. }
  264. ]
  265. }
  266. },
  267. {
  268. name: 'optionType',
  269. cnName: '选项类型',
  270. type: FormFieldType.SELECT,
  271. defaultValue: 'string',
  272. otherOptions: {
  273. placeholder: '请选择类型',
  274. options: [
  275. {
  276. name: 'string',
  277. label: '字符串',
  278. value: 'string'
  279. },
  280. {
  281. name: 'int',
  282. label: '整数',
  283. value: 'int'
  284. },
  285. {
  286. name: 'array',
  287. label: '数组',
  288. value: 'array'
  289. }
  290. ]
  291. }
  292. }
  293. ]
  294. // 对话框设置
  295. const dialogConfig = reactive<DialogConfig>({
  296. title: '自定义属性',
  297. reqConfig: dialogReqConfig,
  298. rules: dialogRules,
  299. fieldsInfo: dialogFormFields
  300. })
  301. /**
  302. * 获取事件详情
  303. * @param {*} id 这个id还是路由参数中query传过来的id
  304. */
  305. const getEventInfo = (id: number) => {
  306. axiosInstance
  307. .post(AllApi.gameActionDetail, { id })
  308. .then((data: any) => {
  309. analysisResCode(data, '请求', true).then((info) => {
  310. let result = info.data
  311. let updateEventField = {
  312. gid: '',
  313. actionId: '',
  314. actionName: '',
  315. remark: '',
  316. status: 1
  317. }
  318. eventFormRef.value.fillForm(Object.assign(updateEventField, { ...result }))
  319. })
  320. })
  321. .catch((err) => {
  322. console.log(err)
  323. })
  324. }
  325. // 新增属性
  326. const addNewAttr = () => {
  327. attrDialog.value.addForm()
  328. }
  329. // 改变编辑状态
  330. const changeEditState = (state: boolean) => {
  331. eventEditState.value = state
  332. }
  333. /**
  334. * 取消编辑,同时把数据恢复
  335. */
  336. const cancelEdit = () => {
  337. changeEditState(false)
  338. eventFormRef.value.clearValid()
  339. eventFormRef.value.resumeFormData()
  340. }
  341. /**
  342. * 保存编辑,提交表单,只有表单验证通过了才能更改编辑状态
  343. */
  344. const saveEdit = () => {
  345. eventFormRef.value
  346. .submitFormData()
  347. .then(() => {
  348. changeEditState(false)
  349. })
  350. .catch((err: any) => {
  351. console.log(err)
  352. })
  353. }
  354. /**
  355. * 开始编辑,备份一份现有的表单数据
  356. */
  357. const startEdit = () => {
  358. changeEditState(true)
  359. eventFormRef.value.backupFormData()
  360. }
  361. /**
  362. * 接受到表单提交事件后,需要去重新请求一下表格的数据
  363. */
  364. const formSub = () => {
  365. optionTableRef.value.getData()
  366. }
  367. /**
  368. * 修改选项
  369. */
  370. const editOption = (row: any) => {
  371. attrDialog.value.editForm(row, AllApi.updateGameActionOption)
  372. }
  373. /**
  374. * 删除选项
  375. */
  376. const delOption = (row: any) => {
  377. ElMessageBox.confirm('确认删除该配置吗', '警告', {
  378. confirmButtonText: '确定',
  379. cancelButtonText: '取消',
  380. type: 'warning'
  381. })
  382. .then(() => {
  383. optionTableRef.value.deleteRow(AllApi.deleteGameActionOption, { id: row.id })
  384. })
  385. .catch(() => {})
  386. }
  387. /**
  388. * 初始化参数
  389. * 加载时如果有actionId,则代表是修改页面,需要去请求数据,没有则是新增页面
  390. * 这里的actionId,是返回参数中id、actionID中的前者,在这个页面会被用于请求事件详情和相关的参数列表
  391. * 在请求的时候,他们的名字不同,但传入的都是这个id
  392. */
  393. const initParams = () => {
  394. const routes = useRoute()
  395. let query_actionId = routes.query.id as string
  396. console.log(query_actionId)
  397. if (query_actionId) {
  398. isAdd.value = false
  399. actionId.value = parseInt(query_actionId)
  400. getEventInfo(parseInt(actionId.value))
  401. tableReqConfig.otherOptions.actionId = actionId.value
  402. dialogReqConfig.otherOptions.formData.actionId = actionId.value
  403. }
  404. }
  405. // 初始化参数
  406. initParams()
  407. const watchGid = watch(
  408. () => selectInfo.gid,
  409. () => {
  410. router.replace({ name: 'EventManage' })
  411. }
  412. )
  413. onUnmounted(() => {
  414. watchGid()
  415. })
  416. </script>
  417. <template>
  418. <div class="eventDetail">
  419. <div class="header">
  420. <span>基本信息</span>
  421. <div class="headerBtn">
  422. <span v-if="eventEditState">
  423. <el-button class="handleBtn" @click="cancelEdit" color="#626aef" plain>取消</el-button>
  424. <el-button class="handleBtn" @click="saveEdit" color="#626aef">保存</el-button>
  425. </span>
  426. <span v-else>
  427. <el-button class="handleBtn" @click="startEdit" color="#626aef">编辑</el-button>
  428. </span>
  429. </div>
  430. </div>
  431. </div>
  432. <div class="eventForm">
  433. <div class="formBody">
  434. <Form
  435. :disabled="eventEditState"
  436. ref="eventFormRef"
  437. :inline="true"
  438. :config="formConfig"
  439. ></Form>
  440. </div>
  441. </div>
  442. <div class="attrList">
  443. <div class="header">
  444. <span>属性列表</span>
  445. </div>
  446. <div class="list">
  447. <Table
  448. :tools="tableToolsConfig"
  449. :open-page-query="true"
  450. :open-filter-query="false"
  451. :pagination-config="pageConfig"
  452. :table-fields-info="tableFieldConfig"
  453. :request-config="tableReqConfig"
  454. @add-new-item="addNewAttr"
  455. ref="optionTableRef"
  456. >
  457. <template #tableOperation>
  458. <el-table-column label="操作" align="center">
  459. <template #default="scope">
  460. <el-button
  461. size="small"
  462. color="#626aef"
  463. @click="editOption(scope.row)"
  464. class="operationBtn"
  465. >
  466. 修改
  467. </el-button>
  468. <el-button
  469. size="small"
  470. color="#EF5A6F"
  471. @click="delOption(scope.row)"
  472. class="operationBtn"
  473. >
  474. 删除
  475. </el-button>
  476. </template>
  477. </el-table-column>
  478. </template>
  479. </Table>
  480. </div>
  481. </div>
  482. <div class="addAttrDialog">
  483. <Dialog ref="attrDialog" :config="dialogConfig" @form-submit="formSub"></Dialog>
  484. </div>
  485. <div class="uploadFileBox">
  486. <FileUpload ref="uploadRef" :title="uploadInfo.dialogTitle"></FileUpload>
  487. </div>
  488. </template>
  489. <style scoped>
  490. .eventDetail,
  491. .eventForm,
  492. .attrList {
  493. width: 98%;
  494. margin: 0 auto;
  495. background-color: white;
  496. box-sizing: border-box;
  497. }
  498. .header {
  499. width: 100%;
  500. box-sizing: border-box;
  501. background-color: white;
  502. display: flex;
  503. align-items: center;
  504. justify-content: space-between;
  505. height: 56px;
  506. box-shadow: inset 0 -1px 0 0 rgba(23, 35, 61, 0.1);
  507. font-weight: 600;
  508. font-size: 14px;
  509. color: #17233d;
  510. padding: 12px 24px;
  511. }
  512. .headerBtn {
  513. box-sizing: border-box;
  514. }
  515. .handleBtn {
  516. margin-right: 15px;
  517. }
  518. .eventForm {
  519. padding: 24px;
  520. }
  521. .formBody {
  522. width: 45%;
  523. }
  524. .operationBtn {
  525. cursor: pointer;
  526. margin-right: 5px;
  527. color: white;
  528. }
  529. </style>