Commit d080a458558d76c23a6fe41a5f819eef637003c2

Authored by 李宇
1 parent 5e827127

拓客活动

antis-ncc-admin/src/api/extend/lqevent.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取拓客活动列表
  4 +export function getLqEventList(data) {
  5 + return request({
  6 + url: '/api/Extend/lqevent',
  7 + method: 'GET',
  8 + data
  9 + })
  10 +}
  11 +
  12 +// 获取拓客活动详情
  13 +export function getLqEventInfo(id) {
  14 + return request({
  15 + url: `/api/Extend/lqevent/${id}`,
  16 + method: 'GET'
  17 + })
  18 +}
  19 +
  20 +// 新增拓客活动
  21 +export function createLqEvent(data) {
  22 + return request({
  23 + url: '/api/Extend/lqevent',
  24 + method: 'POST',
  25 + data
  26 + })
  27 +}
  28 +
  29 +// 更新拓客活动
  30 +export function updateLqEvent(id, data) {
  31 + return request({
  32 + url: `/api/Extend/lqevent/${id}`,
  33 + method: 'PUT',
  34 + data
  35 + })
  36 +}
  37 +
  38 +// 删除拓客活动
  39 +export function deleteLqEvent(id) {
  40 + return request({
  41 + url: `/api/Extend/lqevent/${id}`,
  42 + method: 'DELETE'
  43 + })
  44 +}
  45 +
  46 +// 批量删除拓客活动
  47 +export function batchDeleteLqEvent(ids) {
  48 + return request({
  49 + url: '/api/Extend/lqevent/batch',
  50 + method: 'DELETE',
  51 + data: { ids }
  52 + })
  53 +}
  54 +
  55 +// 导出拓客活动
  56 +export function exportLqEvent(data) {
  57 + return request({
  58 + url: '/api/Extend/lqevent/export',
  59 + method: 'POST',
  60 + data,
  61 + responseType: 'blob'
  62 + })
  63 +}
... ...
antis-ncc-admin/src/router/modules/base.js
... ... @@ -64,6 +64,17 @@ const baseRouter = [{
64 64 zhTitle: '美业仪表板',
65 65 icon: 'icon-ym icon-ym-generator-kanban',
66 66 }
  67 + },
  68 + {
  69 + path: '/lqEvent',
  70 + component: (resolve) => require(['@/views/lqEvent'], resolve),
  71 + name: 'lqEvent',
  72 + meta: {
  73 + title: 'lqEvent',
  74 + affix: false,
  75 + zhTitle: '拓客活动',
  76 + icon: 'icon-ym icon-ym-s-data',
  77 + }
67 78 }
68 79 ]
69 80 export default baseRouter
70 81 \ No newline at end of file
... ...
antis-ncc-admin/src/views/lqEvent/ExportBox.vue 0 → 100644
  1 +<template>
  2 + <el-dialog title="导出拓客活动" :close-on-click-modal="false" :visible.sync="visible" width="500px">
  3 + <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="100px">
  4 + <el-form-item label="导出格式" prop="fileType">
  5 + <el-radio-group v-model="dataForm.fileType">
  6 + <el-radio label="excel">Excel</el-radio>
  7 + <el-radio label="csv">CSV</el-radio>
  8 + </el-radio-group>
  9 + </el-form-item>
  10 + <el-form-item label="导出范围" prop="exportRange">
  11 + <el-radio-group v-model="dataForm.exportRange">
  12 + <el-radio label="all">全部数据</el-radio>
  13 + <el-radio label="current">当前页</el-radio>
  14 + <el-radio label="selected">选中数据</el-radio>
  15 + </el-radio-group>
  16 + </el-form-item>
  17 + <el-form-item label="导出字段" prop="fields">
  18 + <el-checkbox-group v-model="dataForm.fields">
  19 + <el-checkbox label="eventName">活动名称</el-checkbox>
  20 + <el-checkbox label="eventNumber">活动编号</el-checkbox>
  21 + <el-checkbox label="eventCoordinator">活动负责人</el-checkbox>
  22 + <el-checkbox label="startTime">开始时间</el-checkbox>
  23 + <el-checkbox label="endTime">结束时间</el-checkbox>
  24 + <el-checkbox label="memberCount">参与人数</el-checkbox>
  25 + <el-checkbox label="createTime">创建时间</el-checkbox>
  26 + </el-checkbox-group>
  27 + </el-form-item>
  28 + <el-form-item label="文件名" prop="fileName">
  29 + <el-input v-model="dataForm.fileName" placeholder="请输入文件名" />
  30 + </el-form-item>
  31 + </el-form>
  32 + <span slot="footer" class="dialog-footer">
  33 + <el-button @click="visible = false">取消</el-button>
  34 + <el-button type="primary" @click="dataFormSubmit()" :loading="exportLoading">确定导出</el-button>
  35 + </span>
  36 + </el-dialog>
  37 +</template>
  38 +
  39 +<script>
  40 +import { exportLqEvent } from '@/api/extend/lqevent'
  41 +import { saveAs } from 'file-saver'
  42 +
  43 +export default {
  44 + name: 'LqEventExportBox',
  45 + data() {
  46 + return {
  47 + visible: false,
  48 + exportLoading: false,
  49 + dataForm: {
  50 + fileType: 'excel',
  51 + exportRange: 'all',
  52 + fields: ['eventName', 'eventNumber', 'eventCoordinator', 'startTime', 'endTime', 'memberCount', 'createTime'],
  53 + fileName: '拓客活动数据'
  54 + },
  55 + dataRule: {
  56 + fileType: [
  57 + { required: true, message: '请选择导出格式', trigger: 'change' }
  58 + ],
  59 + exportRange: [
  60 + { required: true, message: '请选择导出范围', trigger: 'change' }
  61 + ],
  62 + fields: [
  63 + { required: true, message: '请选择导出字段', trigger: 'change' }
  64 + ],
  65 + fileName: [
  66 + { required: true, message: '请输入文件名', trigger: 'blur' }
  67 + ]
  68 + }
  69 + }
  70 + },
  71 + methods: {
  72 + init() {
  73 + this.visible = true
  74 + this.$nextTick(() => {
  75 + this.$refs['dataForm'].resetFields()
  76 + this.dataForm = {
  77 + fileType: 'excel',
  78 + exportRange: 'all',
  79 + fields: ['eventName', 'eventNumber', 'eventCoordinator', 'startTime', 'endTime', 'memberCount', 'createTime'],
  80 + fileName: '拓客活动数据'
  81 + }
  82 + })
  83 + },
  84 + // 表单提交
  85 + dataFormSubmit() {
  86 + this.$refs['dataForm'].validate((valid) => {
  87 + if (valid) {
  88 + this.exportLoading = true
  89 +
  90 + const exportData = {
  91 + ...this.dataForm,
  92 + query: this.$parent.query || {}
  93 + }
  94 +
  95 + exportLqEvent(exportData).then(response => {
  96 + // 创建文件名
  97 + const timestamp = new Date().getTime()
  98 + const fileExtension = this.dataForm.fileType === 'excel' ? 'xlsx' : 'csv'
  99 + const fileName = `${this.dataForm.fileName}_${timestamp}.${fileExtension}`
  100 +
  101 + // 保存文件
  102 + const blob = new Blob([response], {
  103 + type: this.dataForm.fileType === 'excel'
  104 + ? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  105 + : 'text/csv;charset=utf-8'
  106 + })
  107 + saveAs(blob, fileName)
  108 +
  109 + this.$message({
  110 + message: '导出成功',
  111 + type: 'success'
  112 + })
  113 + this.visible = false
  114 + this.exportLoading = false
  115 + }).catch(() => {
  116 + this.exportLoading = false
  117 + })
  118 + }
  119 + })
  120 + }
  121 + }
  122 +}
  123 +</script>
  124 +
  125 +<style scoped>
  126 +.dialog-footer {
  127 + text-align: right;
  128 +}
  129 +
  130 +.el-checkbox-group {
  131 + display: flex;
  132 + flex-wrap: wrap;
  133 +}
  134 +
  135 +.el-checkbox {
  136 + margin-right: 20px;
  137 + margin-bottom: 10px;
  138 +}
  139 +</style>
... ...
antis-ncc-admin/src/views/lqEvent/Form.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="!dataForm.id ? '新增' : '修改'" :close-on-click-modal="false" :visible.sync="visible" width="800px">
  3 + <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="120px">
  4 + <el-row :gutter="20">
  5 + <el-col :span="12">
  6 + <el-form-item label="活动名称" prop="eventName">
  7 + <el-input v-model="dataForm.eventName" placeholder="请输入活动名称" />
  8 + </el-form-item>
  9 + </el-col>
  10 + <el-col :span="12">
  11 + <el-form-item label="活动编号" prop="eventNumber">
  12 + <el-input v-model="dataForm.eventNumber" placeholder="请输入活动编号" />
  13 + </el-form-item>
  14 + </el-col>
  15 + </el-row>
  16 + <el-row :gutter="20">
  17 + <el-col :span="12">
  18 + <el-form-item label="活动负责人" prop="eventCoordinator">
  19 + <el-input v-model="dataForm.eventCoordinator" placeholder="请输入活动负责人" />
  20 + </el-form-item>
  21 + </el-col>
  22 + <el-col :span="12">
  23 + <el-form-item label="参与人数" prop="memberCount">
  24 + <el-input-number v-model="memberCount" :min="0" :max="1000" placeholder="参与人数" />
  25 + </el-form-item>
  26 + </el-col>
  27 + </el-row>
  28 + <el-row :gutter="20">
  29 + <el-col :span="12">
  30 + <el-form-item label="开始时间" prop="startTime">
  31 + <el-date-picker
  32 + v-model="dataForm.startTime"
  33 + type="datetime"
  34 + placeholder="选择开始时间"
  35 + value-format="yyyy-MM-dd HH:mm:ss"
  36 + style="width: 100%"
  37 + />
  38 + </el-form-item>
  39 + </el-col>
  40 + <el-col :span="12">
  41 + <el-form-item label="结束时间" prop="endTime">
  42 + <el-date-picker
  43 + v-model="dataForm.endTime"
  44 + type="datetime"
  45 + placeholder="选择结束时间"
  46 + value-format="yyyy-MM-dd HH:mm:ss"
  47 + style="width: 100%"
  48 + />
  49 + </el-form-item>
  50 + </el-col>
  51 + </el-row>
  52 +
  53 + <!-- 成员管理 -->
  54 + <el-divider content-position="left">活动成员</el-divider>
  55 + <div class="member-management">
  56 + <div class="member-header">
  57 + <el-button type="primary" size="small" icon="el-icon-plus" @click="addMember">添加成员</el-button>
  58 + <span class="member-count">共 {{ dataForm.members.length }} 人</span>
  59 + </div>
  60 + <el-table :data="dataForm.members" border style="margin-top: 10px;">
  61 + <el-table-column prop="userId" label="用户ID" width="150">
  62 + <template slot-scope="scope">
  63 + <el-input v-model="scope.row.userId" placeholder="请输入用户ID" size="small" />
  64 + </template>
  65 + </el-table-column>
  66 + <el-table-column prop="depId" label="部门ID" width="150">
  67 + <template slot-scope="scope">
  68 + <el-input v-model="scope.row.depId" placeholder="请输入部门ID" size="small" />
  69 + </template>
  70 + </el-table-column>
  71 + <el-table-column prop="teamName" label="团队名称" min-width="200">
  72 + <template slot-scope="scope">
  73 + <el-input v-model="scope.row.teamName" placeholder="请输入团队名称" size="small" />
  74 + </template>
  75 + </el-table-column>
  76 + <el-table-column label="操作" width="80" align="center">
  77 + <template slot-scope="scope">
  78 + <el-button type="text" size="small" @click="removeMember(scope.$index)">删除</el-button>
  79 + </template>
  80 + </el-table-column>
  81 + </el-table>
  82 + </div>
  83 + </el-form>
  84 + <span slot="footer" class="dialog-footer">
  85 + <el-button @click="visible = false">取消</el-button>
  86 + <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
  87 + </span>
  88 + </el-dialog>
  89 +</template>
  90 +
  91 +<script>
  92 +import { getLqEventInfo, createLqEvent, updateLqEvent } from '@/api/extend/lqevent'
  93 +
  94 +export default {
  95 + name: 'LqEventForm',
  96 + data() {
  97 + return {
  98 + visible: false,
  99 + dataForm: {
  100 + id: '',
  101 + eventName: '',
  102 + eventNumber: '',
  103 + eventCoordinator: '',
  104 + startTime: '',
  105 + endTime: '',
  106 + members: []
  107 + },
  108 + memberCount: 0,
  109 + dataRule: {
  110 + eventName: [
  111 + { required: true, message: '活动名称不能为空', trigger: 'blur' }
  112 + ],
  113 + eventNumber: [
  114 + { required: true, message: '活动编号不能为空', trigger: 'blur' }
  115 + ],
  116 + eventCoordinator: [
  117 + { required: true, message: '活动负责人不能为空', trigger: 'blur' }
  118 + ],
  119 + startTime: [
  120 + { required: true, message: '开始时间不能为空', trigger: 'change' }
  121 + ],
  122 + endTime: [
  123 + { required: true, message: '结束时间不能为空', trigger: 'change' }
  124 + ]
  125 + }
  126 + }
  127 + },
  128 + methods: {
  129 + init(id) {
  130 + this.dataForm.id = id || ''
  131 + this.visible = true
  132 + this.$nextTick(() => {
  133 + this.$refs['dataForm'].resetFields()
  134 + if (this.dataForm.id) {
  135 + this.getInfo()
  136 + } else {
  137 + this.dataForm.members = []
  138 + this.memberCount = 0
  139 + }
  140 + })
  141 + },
  142 + // 获取信息
  143 + getInfo() {
  144 + getLqEventInfo(this.dataForm.id).then(response => {
  145 + this.dataForm = response.data
  146 + this.dataForm.members = response.data.Members || []
  147 + this.memberCount = this.dataForm.members ? this.dataForm.members.length : 0
  148 + })
  149 + },
  150 + // 添加成员
  151 + addMember() {
  152 + this.dataForm.members.push({
  153 + id: '',
  154 + eventId: this.dataForm.id || '',
  155 + userId: '',
  156 + depId: '',
  157 + teamName: ''
  158 + })
  159 + this.memberCount = this.dataForm.members.length
  160 + },
  161 + // 删除成员
  162 + removeMember(index) {
  163 + this.dataForm.members.splice(index, 1)
  164 + this.memberCount = this.dataForm.members.length
  165 + },
  166 + // 表单提交
  167 + dataFormSubmit() {
  168 + this.$refs['dataForm'].validate((valid) => {
  169 + if (valid) {
  170 + // 验证时间
  171 + if (this.dataForm.startTime && this.dataForm.endTime) {
  172 + if (new Date(this.dataForm.startTime) >= new Date(this.dataForm.endTime)) {
  173 + this.$message.error('结束时间必须大于开始时间')
  174 + return
  175 + }
  176 + }
  177 +
  178 + // 验证成员信息
  179 + for (let i = 0; i < this.dataForm.members.length; i++) {
  180 + const member = this.dataForm.members[i]
  181 + if (!member.userId || !member.depId || !member.teamName) {
  182 + this.$message.error(`第${i + 1}个成员信息不完整`)
  183 + return
  184 + }
  185 + }
  186 +
  187 + const data = { ...this.dataForm }
  188 + if (!data.id) {
  189 + // 新增
  190 + createLqEvent(data).then(() => {
  191 + this.$message({
  192 + message: '操作成功',
  193 + type: 'success'
  194 + })
  195 + this.visible = false
  196 + this.$emit('refreshDataList')
  197 + })
  198 + } else {
  199 + // 修改
  200 + updateLqEvent(data.id, data).then(() => {
  201 + this.$message({
  202 + message: '操作成功',
  203 + type: 'success'
  204 + })
  205 + this.visible = false
  206 + this.$emit('refreshDataList')
  207 + })
  208 + }
  209 + }
  210 + })
  211 + }
  212 + }
  213 +}
  214 +</script>
  215 +
  216 +<style scoped>
  217 +.member-management {
  218 + margin-top: 20px;
  219 +}
  220 +
  221 +.member-header {
  222 + display: flex;
  223 + justify-content: space-between;
  224 + align-items: center;
  225 + margin-bottom: 10px;
  226 +}
  227 +
  228 +.member-count {
  229 + color: #606266;
  230 + font-size: 14px;
  231 +}
  232 +
  233 +.dialog-footer {
  234 + text-align: right;
  235 +}
  236 +</style>
... ...
antis-ncc-admin/src/views/lqEvent/index.vue 0 → 100644
  1 +<template>
  2 + <div class="NCC-common-layout">
  3 + <div class="NCC-common-layout-center">
  4 + <el-row class="NCC-common-search-box" :gutter="16">
  5 + <el-form @submit.native.prevent>
  6 + <el-col :span="6">
  7 + <el-form-item label="活动名称">
  8 + <el-input v-model="query.eventName" placeholder="请输入活动名称" clearable />
  9 + </el-form-item>
  10 + </el-col>
  11 + <el-col :span="6">
  12 + <el-form-item label="活动编号">
  13 + <el-input v-model="query.eventNumber" placeholder="请输入活动编号" clearable />
  14 + </el-form-item>
  15 + </el-col>
  16 + <el-col :span="6">
  17 + <el-form-item label="活动负责人">
  18 + <el-input v-model="query.eventCoordinator" placeholder="请输入活动负责人" clearable />
  19 + </el-form-item>
  20 + </el-col>
  21 + <el-col :span="6">
  22 + <el-form-item>
  23 + <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
  24 + <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button>
  25 + </el-form-item>
  26 + </el-col>
  27 + </el-form>
  28 + </el-row>
  29 + <div class="NCC-common-layout-main NCC-flex-main">
  30 + <div class="NCC-common-head">
  31 + <div>
  32 + <el-button type="primary" icon="el-icon-plus" @click="addOrUpdateHandle()">新增</el-button>
  33 + <el-button type="text" icon="el-icon-download" @click="exportData()">导出</el-button>
  34 + <el-button type="text" icon="el-icon-delete" @click="handleBatchRemoveDel()">批量删除</el-button>
  35 + </div>
  36 + <div class="NCC-common-head-right">
  37 + <el-tooltip effect="dark" content="刷新" placement="top">
  38 + <el-link icon="icon-ym icon-ym-Refresh NCC-common-head-icon" :underline="false" @click="reset()" />
  39 + </el-tooltip>
  40 + <screenfull isContainer />
  41 + </div>
  42 + </div>
  43 + <NCC-table v-loading="listLoading" :data="list" has-c @selection-change="handleSelectionChange">
  44 + <el-table-column prop="eventName" label="活动名称" align="left" show-overflow-tooltip />
  45 + <el-table-column prop="eventNumber" label="活动编号" align="left" show-overflow-tooltip />
  46 + <el-table-column prop="eventCoordinator" label="活动负责人" align="left" show-overflow-tooltip />
  47 + <el-table-column prop="startTime" label="开始时间" align="left" width="180">
  48 + <template slot-scope="scope">
  49 + {{ scope.row.startTime | formatDate('yyyy-MM-dd HH:mm:ss') }}
  50 + </template>
  51 + </el-table-column>
  52 + <el-table-column prop="endTime" label="结束时间" align="left" width="180">
  53 + <template slot-scope="scope">
  54 + {{ scope.row.endTime | formatDate('yyyy-MM-dd HH:mm:ss') }}
  55 + </template>
  56 + </el-table-column>
  57 + <el-table-column prop="members" label="参与人数" align="center" width="100">
  58 + <template slot-scope="scope">
  59 + {{ scope.row.members ? scope.row.members.length : 0 }}人
  60 + </template>
  61 + </el-table-column>
  62 + <el-table-column prop="createTime" label="创建时间" align="left" width="180">
  63 + <template slot-scope="scope">
  64 + {{ scope.row.createTime | formatDate('yyyy-MM-dd HH:mm:ss') }}
  65 + </template>
  66 + </el-table-column>
  67 + <el-table-column label="操作" align="left" width="200" fixed="right">
  68 + <template slot-scope="scope">
  69 + <el-button type="text" @click="addOrUpdateHandle(scope.row.id)">编辑</el-button>
  70 + <el-button type="text" @click="handleDelete(scope.row.id)">删除</el-button>
  71 + <el-button type="text" @click="viewMembers(scope.row)">查看成员</el-button>
  72 + </template>
  73 + </el-table-column>
  74 + </NCC-table>
  75 + <pagination
  76 + v-show="total > 0"
  77 + :total="total"
  78 + :page.sync="query.currentPage"
  79 + :limit.sync="query.pageSize"
  80 + @pagination="getList"
  81 + />
  82 + </div>
  83 + </div>
  84 + <!-- 弹窗, 新增 / 修改 -->
  85 + <Form v-if="formVisible" ref="Form" @refreshDataList="getList" />
  86 + <!-- 导出弹窗 -->
  87 + <ExportBox v-if="exportVisible" ref="ExportBox" @refreshDataList="getList" />
  88 + <!-- 查看成员弹窗 -->
  89 + <el-dialog title="活动成员" :visible.sync="membersVisible" width="800px">
  90 + <el-table :data="currentMembers" v-loading="membersLoading">
  91 + <el-table-column prop="userId" label="用户ID" align="left" />
  92 + <el-table-column prop="depId" label="部门ID" align="left" />
  93 + <el-table-column prop="teamName" label="团队名称" align="left" />
  94 + </el-table>
  95 + </el-dialog>
  96 + </div>
  97 +</template>
  98 +
  99 +<script>
  100 +import { getLqEventList, deleteLqEvent, batchDeleteLqEvent } from '@/api/extend/lqevent'
  101 +import Form from './Form'
  102 +import ExportBox from './ExportBox'
  103 +import Pagination from '@/components/Pagination'
  104 +
  105 +export default {
  106 + name: 'LqEvent',
  107 + components: {
  108 + Form,
  109 + ExportBox,
  110 + Pagination
  111 + },
  112 + data() {
  113 + return {
  114 + query: {
  115 + eventName: '',
  116 + eventNumber: '',
  117 + eventCoordinator: '',
  118 + currentPage: 1,
  119 + pageSize: 20
  120 + },
  121 + list: [],
  122 + total: 0,
  123 + listLoading: true,
  124 + formVisible: false,
  125 + exportVisible: false,
  126 + membersVisible: false,
  127 + membersLoading: false,
  128 + currentMembers: [],
  129 + selectedIds: []
  130 + }
  131 + },
  132 + created() {
  133 + this.getList()
  134 + },
  135 + methods: {
  136 + // 获取数据列表
  137 + getList() {
  138 + this.listLoading = true
  139 + getLqEventList(this.query).then(response => {
  140 + this.list = response.data.list
  141 + this.total = response.data.pagination.total
  142 + this.listLoading = false
  143 + }).catch(() => {
  144 + this.listLoading = false
  145 + })
  146 + },
  147 + // 搜索
  148 + search() {
  149 + this.query.currentPage = 1
  150 + this.getList()
  151 + },
  152 + // 重置
  153 + reset() {
  154 + this.query = {
  155 + eventName: '',
  156 + eventNumber: '',
  157 + eventCoordinator: '',
  158 + currentPage: 1,
  159 + pageSize: 20
  160 + }
  161 + this.getList()
  162 + },
  163 + // 新增 / 修改
  164 + addOrUpdateHandle(id) {
  165 + this.formVisible = true
  166 + this.$nextTick(() => {
  167 + this.$refs.Form.init(id)
  168 + })
  169 + },
  170 + // 删除
  171 + handleDelete(id) {
  172 + this.$confirm('确定要删除该拓客活动吗?', '提示', {
  173 + confirmButtonText: '确定',
  174 + cancelButtonText: '取消',
  175 + type: 'warning'
  176 + }).then(() => {
  177 + deleteLqEvent(id).then(() => {
  178 + this.$message({
  179 + message: '删除成功',
  180 + type: 'success'
  181 + })
  182 + this.getList()
  183 + })
  184 + })
  185 + },
  186 + // 批量删除
  187 + handleBatchRemoveDel() {
  188 + if (this.selectedIds.length === 0) {
  189 + this.$message({
  190 + message: '请选择要删除的数据',
  191 + type: 'warning'
  192 + })
  193 + return
  194 + }
  195 + this.$confirm('确定要删除选中的拓客活动吗?', '提示', {
  196 + confirmButtonText: '确定',
  197 + cancelButtonText: '取消',
  198 + type: 'warning'
  199 + }).then(() => {
  200 + batchDeleteLqEvent(this.selectedIds).then(() => {
  201 + this.$message({
  202 + message: '删除成功',
  203 + type: 'success'
  204 + })
  205 + this.getList()
  206 + })
  207 + })
  208 + },
  209 + // 多选
  210 + handleSelectionChange(selection) {
  211 + this.selectedIds = selection.map(item => item.id)
  212 + },
  213 + // 导出
  214 + exportData() {
  215 + this.exportVisible = true
  216 + this.$nextTick(() => {
  217 + this.$refs.ExportBox.init()
  218 + })
  219 + },
  220 + // 查看成员
  221 + viewMembers(row) {
  222 + this.membersVisible = true
  223 + this.membersLoading = true
  224 + this.currentMembers = row.members || []
  225 + this.membersLoading = false
  226 + }
  227 + }
  228 +}
  229 +</script>
  230 +
  231 +<style scoped>
  232 +.NCC-common-layout {
  233 + height: 100%;
  234 +}
  235 +</style>
... ...
antis-ncc-admin/src/views/lqEvent/test.html 0 → 100644
  1 +<!DOCTYPE html>
  2 +<html lang="zh-CN">
  3 +<head>
  4 + <meta charset="UTF-8">
  5 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6 + <title>拓客活动页面测试</title>
  7 + <style>
  8 + body {
  9 + font-family: Arial, sans-serif;
  10 + margin: 20px;
  11 + background-color: #f5f5f5;
  12 + }
  13 + .container {
  14 + max-width: 1200px;
  15 + margin: 0 auto;
  16 + background: white;
  17 + padding: 20px;
  18 + border-radius: 8px;
  19 + box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  20 + }
  21 + .header {
  22 + border-bottom: 1px solid #eee;
  23 + padding-bottom: 20px;
  24 + margin-bottom: 20px;
  25 + }
  26 + .feature-list {
  27 + list-style: none;
  28 + padding: 0;
  29 + }
  30 + .feature-list li {
  31 + padding: 10px 0;
  32 + border-bottom: 1px solid #f0f0f0;
  33 + }
  34 + .feature-list li:before {
  35 + content: "✓";
  36 + color: #67C23A;
  37 + font-weight: bold;
  38 + margin-right: 10px;
  39 + }
  40 + .api-info {
  41 + background: #f8f9fa;
  42 + padding: 15px;
  43 + border-radius: 5px;
  44 + margin: 20px 0;
  45 + }
  46 + .code-block {
  47 + background: #2d3748;
  48 + color: #e2e8f0;
  49 + padding: 15px;
  50 + border-radius: 5px;
  51 + font-family: 'Courier New', monospace;
  52 + overflow-x: auto;
  53 + margin: 10px 0;
  54 + }
  55 + </style>
  56 +</head>
  57 +<body>
  58 + <div class="container">
  59 + <div class="header">
  60 + <h1>🎯 拓客活动页面 - 功能测试</h1>
  61 + <p>基于Vue 2.6 + Element UI开发的拓客活动管理页面</p>
  62 + </div>
  63 +
  64 + <h2>📋 已实现功能</h2>
  65 + <ul class="feature-list">
  66 + <li>拓客活动列表展示(支持分页)</li>
  67 + <li>活动搜索(按活动名称、编号、负责人)</li>
  68 + <li>新增/编辑拓客活动</li>
  69 + <li>删除活动(单个/批量)</li>
  70 + <li>活动成员管理</li>
  71 + <li>数据导出(Excel/CSV)</li>
  72 + <li>响应式布局设计</li>
  73 + <li>表单验证</li>
  74 + </ul>
  75 +
  76 + <h2>🔧 API接口配置</h2>
  77 + <div class="api-info">
  78 + <h3>接口地址:<code>/api/Extend/lqevent</code></h3>
  79 + <p><strong>请求方法:</strong>GET, POST, PUT, DELETE</p>
  80 + <p><strong>参数格式:</strong></p>
  81 + <div class="code-block">
  82 +{
  83 + "eventName": "string",
  84 + "startTime": "2025-09-17T09:12:11.607Z",
  85 + "endTime": "2025-09-17T09:12:11.607Z",
  86 + "eventCoordinator": "string",
  87 + "eventNumber": "string",
  88 + "members": [
  89 + {
  90 + "id": "string",
  91 + "eventId": "string",
  92 + "userId": "string",
  93 + "depId": "string",
  94 + "teamName": "string"
  95 + }
  96 + ]
  97 +}
  98 + </div>
  99 + </div>
  100 +
  101 + <h2>📁 文件结构</h2>
  102 + <div class="code-block">
  103 +lqEvent/
  104 +├── index.vue # 主页面组件
  105 +├── Form.vue # 表单组件
  106 +├── ExportBox.vue # 导出组件
  107 +└── test.html # 测试页面
  108 + </div>
  109 +
  110 + <h2>🚀 使用方法</h2>
  111 + <ol>
  112 + <li>确保后端API接口 <code>/api/Extend/lqevent</code> 已实现</li>
  113 + <li>启动前端项目:<code>npm run dev</code></li>
  114 + <li>访问页面:<code>http://localhost:3000/#/lqEvent</code></li>
  115 + <li>测试各项功能:增删改查、导出、成员管理</li>
  116 + </ol>
  117 +
  118 + <h2>✨ 特色功能</h2>
  119 + <ul class="feature-list">
  120 + <li>动态成员管理:支持添加/删除活动成员</li>
  121 + <li>时间验证:确保结束时间大于开始时间</li>
  122 + <li>批量操作:支持批量删除和导出</li>
  123 + <li>数据验证:完整的表单验证机制</li>
  124 + <li>用户体验:友好的操作提示和确认</li>
  125 + </ul>
  126 +
  127 + <div style="text-align: center; margin-top: 30px; color: #666;">
  128 + <p>🎉 拓客活动页面开发完成!</p>
  129 + <p>基于项目规范,遵循Vue 2.6 + Element UI最佳实践</p>
  130 + </div>
  131 + </div>
  132 +</body>
  133 +</html>
... ...
antis-ncc-admin/src/views/lqXmzl/Form copy.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="!dataForm.id ? '新建' : isDetail ? '详情':'编辑'" :close-on-click-modal="false" :visible.sync="visible" class="NCC-dialog NCC-dialog_center" lock-scroll width="600px">
  3 + <el-row :gutter="15" class="" >
  4 + <el-form ref="elForm" :model="dataForm" size="small" label-width="100px" label-position="right" :disabled="!!isDetail" :rules="rules">
  5 + <el-col :span="24" v-if="false" >
  6 + <el-form-item label="主键" prop="id">
  7 + <el-input v-model="dataForm.id" placeholder="请输入" clearable :style='{"width":"100%"}' >
  8 + </el-input>
  9 + </el-form-item>
  10 + </el-col>
  11 + <el-col :span="24">
  12 + <el-form-item label="项目编号" prop="xmbh">
  13 + <el-input v-model="dataForm.xmbh" placeholder="请输入" clearable :style='{"width":"100%"}' >
  14 + </el-input>
  15 + </el-form-item>
  16 + </el-col>
  17 + <el-col :span="24">
  18 + <el-form-item label="项目名称" prop="xmmc">
  19 + <el-input v-model="dataForm.xmmc" placeholder="请输入" clearable :style='{"width":"100%"}' >
  20 + </el-input>
  21 + </el-form-item>
  22 + </el-col>
  23 + <el-col :span="24">
  24 + <el-form-item label="标准价格" prop="bzjg">
  25 + <el-input v-model="dataForm.bzjg" placeholder="请输入" clearable :style='{"width":"100%"}' >
  26 + </el-input>
  27 + </el-form-item>
  28 + </el-col>
  29 + <el-col :span="24">
  30 + <el-form-item label="时长(分)" prop="xmsc">
  31 + <el-input v-model="dataForm.xmsc" placeholder="请输入" clearable :style='{"width":"100%"}' >
  32 + </el-input>
  33 + </el-form-item>
  34 + </el-col>
  35 + <el-col :span="24">
  36 + <el-form-item label="基础服务提成" prop="jcfwtc">
  37 + <el-input v-model="dataForm.jcfwtc" placeholder="请输入" clearable :style='{"width":"100%"}' >
  38 + </el-input>
  39 + </el-form-item>
  40 + </el-col>
  41 + <el-col :span="24">
  42 + <el-form-item label="分类1汇总表" prop="fl1">
  43 + <el-input v-model="dataForm.fl1" placeholder="请输入" clearable :style='{"width":"100%"}' >
  44 + </el-input>
  45 + </el-form-item>
  46 + </el-col>
  47 + <el-col :span="24">
  48 + <el-form-item label="分类2汇总表" prop="fl2">
  49 + <el-input v-model="dataForm.fl2" placeholder="请输入" clearable :style='{"width":"100%"}' >
  50 + </el-input>
  51 + </el-form-item>
  52 + </el-col>
  53 + <el-col :span="24">
  54 + <el-form-item label="分类3工资用" prop="fl3">
  55 + <el-input v-model="dataForm.fl3" placeholder="请输入" clearable :style='{"width":"100%"}' >
  56 + </el-input>
  57 + </el-form-item>
  58 + </el-col>
  59 + <el-col :span="24">
  60 + <el-form-item label="分类4品项用" prop="fl4">
  61 + <el-input v-model="dataForm.fl4" placeholder="请输入" clearable :style='{"width":"100%"}' >
  62 + </el-input>
  63 + </el-form-item>
  64 + </el-col>
  65 + <el-col :span="24">
  66 + <el-form-item label="统计类别" prop="tjlb">
  67 + <el-input v-model="dataForm.tjlb" placeholder="请输入" clearable :style='{"width":"100%"}' >
  68 + </el-input>
  69 + </el-form-item>
  70 + </el-col>
  71 + <el-col :span="24">
  72 + <el-form-item label="折扣类别" prop="zklb">
  73 + <el-input v-model="dataForm.zklb" placeholder="请输入" clearable :style='{"width":"100%"}' >
  74 + </el-input>
  75 + </el-form-item>
  76 + </el-col>
  77 + <el-col :span="24">
  78 + <el-form-item label="分类" prop="fl">
  79 + <el-input v-model="dataForm.fl" placeholder="请输入" clearable :style='{"width":"100%"}' >
  80 + </el-input>
  81 + </el-form-item>
  82 + </el-col>
  83 + <el-col :span="24">
  84 + <el-form-item label="其它1" prop="qt1">
  85 + <el-input v-model="dataForm.qt1" placeholder="请输入" clearable :style='{"width":"100%"}' >
  86 + </el-input>
  87 + </el-form-item>
  88 + </el-col>
  89 + <el-col :span="24">
  90 + <el-form-item label="其它2" prop="qt2">
  91 + <el-input v-model="dataForm.qt2" placeholder="请输入" clearable :style='{"width":"100%"}' >
  92 + </el-input>
  93 + </el-form-item>
  94 + </el-col>
  95 + </el-form>
  96 + </el-row>
  97 + <span slot="footer" class="dialog-footer">
  98 + <el-button @click="visible = false">取 消</el-button>
  99 + <el-button type="primary" @click="dataFormSubmit()" v-if="!isDetail">确 定</el-button>
  100 + </span>
  101 + </el-dialog>
  102 +</template>
  103 +<script>
  104 + import request from '@/utils/request'
  105 + import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
  106 + import { previewDataInterface } from '@/api/systemData/dataInterface'
  107 + export default {
  108 + components: {},
  109 + props: [],
  110 + data() {
  111 + return {
  112 + loading: false,
  113 + visible: false,
  114 + isDetail: false,
  115 + dataForm: {
  116 + id:'',
  117 + id:undefined,
  118 + xmbh:undefined,
  119 + xmmc:undefined,
  120 + bzjg:undefined,
  121 + xmsc:undefined,
  122 + jcfwtc:undefined,
  123 + fl1:undefined,
  124 + fl2:undefined,
  125 + fl3:undefined,
  126 + fl4:undefined,
  127 + tjlb:undefined,
  128 + zklb:undefined,
  129 + fl:undefined,
  130 + qt1:undefined,
  131 + qt2:undefined,
  132 + },
  133 + rules: {
  134 + },
  135 + }
  136 + },
  137 + computed: {},
  138 + watch: {},
  139 + created() {
  140 + },
  141 + mounted() {
  142 + },
  143 + methods: {
  144 + goBack() {
  145 + this.$emit('refresh')
  146 + },
  147 + init(id, isDetail) {
  148 + this.dataForm.id = id || 0;
  149 + this.visible = true;
  150 + this.isDetail = isDetail || false;
  151 + this.$nextTick(() => {
  152 + this.$refs['elForm'].resetFields();
  153 + if (this.dataForm.id) {
  154 + request({
  155 + url: '/api/Extend/LqXmzl/' + this.dataForm.id,
  156 + method: 'get'
  157 + }).then(res =>{
  158 + this.dataForm = res.data;
  159 + })
  160 + }
  161 + })
  162 + },
  163 + dataFormSubmit() {
  164 + this.$refs['elForm'].validate((valid) => {
  165 + if (valid) {
  166 + if (!this.dataForm.id) {
  167 + request({
  168 + url: `/api/Extend/LqXmzl`,
  169 + method: 'post',
  170 + data: this.dataForm,
  171 + }).then((res) => {
  172 + this.$message({
  173 + message: res.msg,
  174 + type: 'success',
  175 + duration: 1000,
  176 + onClose: () => {
  177 + this.visible = false,
  178 + this.$emit('refresh', true)
  179 + }
  180 + })
  181 + })
  182 + } else {
  183 + request({
  184 + url: '/api/Extend/LqXmzl/' + this.dataForm.id,
  185 + method: 'PUT',
  186 + data: this.dataForm
  187 + }).then((res) => {
  188 + this.$message({
  189 + message: res.msg,
  190 + type: 'success',
  191 + duration: 1000,
  192 + onClose: () => {
  193 + this.visible = false
  194 + this.$emit('refresh', true)
  195 + }
  196 + })
  197 + })
  198 + }
  199 + }
  200 + })
  201 + },
  202 + }
  203 + }
  204 +</script>
... ...
antis-ncc-admin/src/views/lqXmzl/Form.vue
... ... @@ -27,17 +27,23 @@
27 27 </el-form-item>
28 28 </el-col>
29 29 <el-col :span="24">
  30 + <el-form-item label="手工费" prop="sgf">
  31 + <el-input v-model="dataForm.sgf" placeholder="请输入" clearable :style='{"width":"100%"}' >
  32 + </el-input>
  33 + </el-form-item>
  34 + </el-col>
  35 + <el-col :span="24">
30 36 <el-form-item label="时长(分)" prop="xmsc">
31 37 <el-input v-model="dataForm.xmsc" placeholder="请输入" clearable :style='{"width":"100%"}' >
32 38 </el-input>
33 39 </el-form-item>
34 40 </el-col>
35   - <el-col :span="24">
  41 + <!-- <el-col :span="24">
36 42 <el-form-item label="基础服务提成" prop="jcfwtc">
37 43 <el-input v-model="dataForm.jcfwtc" placeholder="请输入" clearable :style='{"width":"100%"}' >
38 44 </el-input>
39 45 </el-form-item>
40   - </el-col>
  46 + </el-col> -->
41 47 <el-col :span="24">
42 48 <el-form-item label="分类1汇总表" prop="fl1">
43 49 <el-input v-model="dataForm.fl1" placeholder="请输入" clearable :style='{"width":"100%"}' >
... ... @@ -114,6 +120,7 @@
114 120 isDetail: false,
115 121 dataForm: {
116 122 id:'',
  123 + sgf:undefined,
117 124 id:undefined,
118 125 xmbh:undefined,
119 126 xmmc:undefined,
... ...
antis-ncc-admin/src/views/lqXmzl/index.vue
... ... @@ -109,8 +109,9 @@
109 109 <el-table-column prop="xmbh" label="项目编号" align="left" />
110 110 <el-table-column prop="xmmc" label="项目名称" align="left" />
111 111 <el-table-column prop="bzjg" label="标准价格" align="left" />
  112 + <el-table-column prop="sgf" label="手工费" align="left" />
112 113 <el-table-column prop="xmsc" label="时长(分)" align="left" />
113   - <el-table-column prop="jcfwtc" label="基础服务提成" align="left" />
  114 + <!-- <el-table-column prop="jcfwtc" label="基础服务提成" align="left" /> -->
114 115 <el-table-column prop="fl1" label="分类1汇总表" align="left" />
115 116 <el-table-column prop="fl2" label="分类2汇总表" align="left" />
116 117 <el-table-column prop="fl3" label="分类3工资用" align="left" />
... ...