瀏覽代碼

feat(ticketSetting): implement ticket type group management

Add functionality to manage ticket type groups, including creating,
editing, deleting, and assigning ticket types to specific groups.

- Add `ticketTypeGroup` API module for group CRUD and batch assignment
- Implement `TicketTypeGroup` management interface with list, dialog,
  and assignment components
- Add print template binding to ticket dialogs
- Update router to include the new ticket type group management route
- Refactor ticket dialog to use local scenic list and async data fetching
LaveyD 3 月之前
父節點
當前提交
bffa1d387d

+ 3 - 1
.gitignore

@@ -25,4 +25,6 @@ yarn-error.log*
 /dist_electron
 /dist_electron_other
 
-node_modules*.zip
+node_modules*.zip
+
+.kilo

+ 26 - 0
src/api/ticketTypeGroup.js

@@ -0,0 +1,26 @@
+import http from '@/utils/request'
+
+// 获取票种分组列表
+export function getTicketTypeGroupList (params) {
+  return http.post('/admin/ticketTypeGroup', { data: params })
+}
+
+// 新增分组
+export function addTicketTypeGroup (params) {
+  return http.post('/admin/ticketTypeGroup/add', { data: params })
+}
+
+// 编辑分组
+export function updateTicketTypeGroup (params) {
+  return http.post('/admin/ticketTypeGroup/update', { data: params })
+}
+
+// 删除分组
+export function deleteTicketTypeGroup (idList) {
+  return http.post('/admin/ticketTypeGroup/delete', { data: { idList } })
+}
+
+// 批量修改分组内票种列表
+export function batchAddTicketType (params) {
+  return http.post('/admin/ticketTypeGroup/batchAdd', { data: params })
+}

+ 4 - 7
src/pages/ticketSetting/ticket.vue

@@ -369,14 +369,11 @@ export default {
       })
     },
     // 获取景点列表
-    getScenicList () {
-      getScenic().then(res => {
-        this.scenicList = res?.data.records || []
-      })
+    async getScenicList () {
+      const res = await getScenic()
+      this.scenicList = res?.data.records || []
     },
-    showDialog (type, item) {
-      this.$store.dispatch('getScenicList')
-
+    async showDialog (type, item) {
       if (type === 'priceCalendar') {
         this.$refs.priceCalendarRef.show(item)
         return

+ 123 - 0
src/pages/ticketSetting/ticketTypeGroup/Dialog.vue

@@ -0,0 +1,123 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="visible"
+    width="600px"
+    @close="handleClose">
+    <el-form
+      :model="form"
+      ref="form"
+      class="form-wrap"
+      label-width="100px">
+      <div class="dialog-info">
+        <el-form-item
+          style="width:100%"
+          label="分组名称"
+          prop="name"
+          :rules="[{ required: true, message: '请输入分组名称', trigger: 'blur' }]"
+        >
+          <el-input v-model="form.name"></el-input>
+        </el-form-item>
+        <el-form-item
+          style="width:100%"
+          label="描述"
+          prop="description">
+          <el-input
+            type="textarea"
+            v-model="form.description"></el-input>
+        </el-form-item>
+      </div>
+    </el-form>
+
+    <div slot="footer">
+      <el-button @click="handleClose">
+        取 消
+      </el-button>
+      <el-button
+        type="primary"
+        :loading="loading"
+        @click="handleSubmit">
+        确 定
+      </el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { addTicketTypeGroup, updateTicketTypeGroup } from '@/api/ticketTypeGroup'
+
+const defaultForm = {
+  id: '',
+  name: '',
+  description: ''
+}
+
+export default {
+  data () {
+    return {
+      title: '',
+      type: '',
+      visible: false,
+      loading: false,
+      form: {
+        ...defaultForm
+      }
+    }
+  },
+  methods: {
+    show (type, row) {
+      this.type = type
+      this.title = type === 'edit' ? '编辑分组' : '新增分组'
+      this.visible = true
+
+      this.$nextTick(() => {
+        this.reset()
+        if (type === 'edit' && row) {
+          this.form = Object.assign({}, this.form, JSON.parse(JSON.stringify(row)))
+        } else {
+          this.form = JSON.parse(JSON.stringify(defaultForm))
+        }
+      })
+    },
+    reset () {
+      this.$refs.form.resetFields()
+    },
+    handleClose () {
+      this.visible = false
+    },
+    handleSubmit () {
+      this.$refs.form.validate(valid => {
+        if (valid) {
+          let params = JSON.parse(JSON.stringify(this.form))
+          this.loading = true
+          if (this.type === 'edit') {
+            updateTicketTypeGroup(params).then(res => {
+              this.$message.success('修改成功')
+              this.$emit('update')
+              this.handleClose()
+            }).finally(() => {
+              this.loading = false
+            })
+          } else {
+            addTicketTypeGroup(params).then(res => {
+              this.$message.success('新增成功')
+              this.$emit('update')
+              this.handleClose()
+            }).finally(() => {
+              this.loading = false
+            })
+          }
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.form-wrap {
+  .el-input,.el-select,.el-date-editor,.el-date-editor.el-input,.el-input-number {
+    width: 100%;
+  }
+}
+</style>

+ 107 - 0
src/pages/ticketSetting/ticketTypeGroup/TicketAssignDialog.vue

@@ -0,0 +1,107 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="visible"
+    width="700px"
+    @close="handleClose"
+  >
+    <div style="margin-bottom: 10px;">
+      当前分组:{{ groupName }}
+    </div>
+    <el-form :model="form" ref="form" label-width="100px">
+      <el-form-item
+        label="选择票种"
+        prop="ticketTypeIds"
+        :rules="[{ required: true, message: '请至少选择一个票种', trigger: 'change' }]"
+      >
+        <el-select
+          v-model="form.ticketTypeIds"
+          multiple
+          filterable
+          placeholder="请选择票种"
+          style="width: 100%"
+        >
+          <el-option
+            v-for="item in ticketTypeList"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+
+    <div slot="footer">
+      <el-button @click="handleClose">
+        取 消
+      </el-button>
+      <el-button
+        type="primary"
+        :loading="loading"
+        @click="handleSubmit"
+      >
+        确 定
+      </el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { batchAddTicketType } from '@/api/ticketTypeGroup'
+import { getTicketTypeList } from '@/api/ticketType'
+
+export default {
+  data () {
+    return {
+      title: '分配票种',
+      visible: false,
+      loading: false,
+      groupId: '',
+      groupName: '',
+      form: {
+        ticketTypeIds: []
+      },
+      ticketTypeList: []
+    }
+  },
+  methods: {
+    show (row) {
+      this.groupId = row.id
+      this.groupName = row.name
+      this.visible = true
+      this.form.ticketTypeIds = (row.ticketTypes || []).map(t => t.id)
+      this.getTicketTypeList()
+    },
+    getTicketTypeList () {
+      getTicketTypeList({
+        pageNum: 1,
+        pageSize: 1000
+      }).then(res => {
+        this.ticketTypeList = res?.data?.records || []
+      })
+    },
+    handleClose () {
+      this.visible = false
+      this.form.ticketTypeIds = []
+    },
+    handleSubmit () {
+      if (this.form.ticketTypeIds.length === 0) {
+        this.$message.warning('请至少选择一个票种')
+        return
+      }
+      this.loading = true
+      batchAddTicketType({
+        groupId: this.groupId,
+        ticketTypeIds: this.form.ticketTypeIds
+      }).then(res => {
+        this.$message.success('分配成功')
+        this.$emit('update')
+        this.handleClose()
+      }).finally(() => {
+        this.loading = false
+      })
+    }
+  }
+}
+</script>

+ 6 - 0
src/router/index.js

@@ -144,6 +144,12 @@ let routerMap = [
         component: require('@/pages/ticketSetting/ticket').default,
         meta: { title: '票种管理', permissionName: 'ticket-manage:ticketType-manage' }
       },
+      {
+        path: 'ticketTypeGroup',
+        name: 'ticketTypeGroup',
+        component: require('@/pages/ticketSetting/ticketTypeGroup/index').default,
+        meta: { title: '票种分组管理', permissionName: 'ticket-manage:ticketTypeGroup-manage' }
+      },
       {
         path: 'scenic',
         name: 'scenic',