|
|
<template> <el-card class="card1" style="margin-bottom: 1vh;"> <div class="condition"> <div class="condition-item1"> <el-text size="large">活动名称:</el-text> <el-input v-model="searchForm.activityName" style="width: 10vw" placeholder="请输入活动名称" clearable /> </div> <div class="condition-item1"> <el-text size="large">业绩归属:</el-text> <!-- <el-cascader v-model="searchForm.businessBelong" :options="marketOptions" placeholder="请选择所属地区" clearable style="width: 10vw" /> --> <el-select v-model="searchForm.businessBelong" placeholder="请选择业绩归属" style="width: 10vw" clearable> <el-option label="客户归属地" value="客户归属地" /> <el-option label="活动归属地" value="活动归属地" /> </el-select> </div> <div class="condition-item2"> <el-text size="large">开始时间:</el-text> <el-date-picker v-model="searchForm.startTime" type="datetime" placeholder="请选择开始时间" format="YYYY-MM-DD HH:mm:ss" :default-time="defaultStartTime" clearable /> </div> <div class="condition-item2"> <el-text size="large">结束时间:</el-text> <el-date-picker v-model="searchForm.endTime" type="datetime" placeholder="请选择结束时间" format="YYYY-MM-DD HH:mm:ss" :default-time="defaultEndTime" clearable /> </div> <el-button type="primary" @click="getActivity">查询</el-button> <el-button type="success" @click="reset">重置</el-button> </div> </el-card>
<el-card class="card2"> <div class="add-item"> <el-button type="success" @click="showAdd = true">新增活动</el-button> </div> <div> <el-table :data="tableData" style="width: 82vw;height:70vh;" :row-style="{ height: '50px' }"> <el-table-column type="index" label="序号" width="100px" fixed="left"> <template #default="scope"> <span>{{ scope.$index + 1 + (pagination.pageNum - 1) * pagination.pageSize }}</span> </template> </el-table-column> <el-table-column prop="activityName" label="活动名称" width="150px" show-overflow-tooltip /> <el-table-column prop="businessBelong" label="业绩归属地" width="150px" /> <el-table-column prop="areaName" label="归属地" width="150px" /> <el-table-column prop="startTime" label="开始时间" width="200px"> <template #default="scope"> {{ moment(scope.row.startTime).format('YYYY-MM-DD HH:mm:ss') }} </template> </el-table-column> <el-table-column prop="endTime" label="结束时间" width="200px"> <template #default="scope"> {{ moment(scope.row.endTime).format('YYYY-MM-DD HH:mm:ss') }} </template> </el-table-column> <el-table-column prop="status" label="状态" width="150px"> <template #default="scope"> {{ scope.row.status === '0' ? '未开始' : scope.row.status === '1' ? '进行中' : scope.row.status === '2' ? '已结束' : scope.row.status }} </template> </el-table-column> <el-table-column prop="creatorName" label="添加人" width="150px" /> <el-table-column prop="operation" label="操作" width="220px"> <template #default="scope"> <el-button type="primary" text @click="editOpen(scope.row)">编辑</el-button> <!-- <el-button type="danger" text @click="openDel(scope.row)">删除</el-button> --> </template> </el-table-column> </el-table> </div>
<div style="margin-top: 20px;display: flex;"> <el-pagination background v-model:current-page="pagination.pageNum" v-model:page-size="pagination.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" style="margin-top: 1vh;" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> </el-card>
<el-dialog v-model="showAdd" width="20vw" draggable align-center style="background-color: rgb(243,250,254);"> <div class="add-item"> <el-text size="large">活动名称:</el-text> <el-input v-model="addForm.activityName" style="width: 12vw" placeholder="请输入活动名称" maxlength="200" clearable /> </div> <div class="add-item"> <el-text size="large">业绩归属:</el-text> <el-radio-group v-model="addForm.businessBelong" style="width: 12vw"> <el-radio size="large" value="客户归属地">客户归属地</el-radio> <el-radio size="large" value="活动归属地">活动归属地</el-radio> </el-radio-group> </div> <div class="add-item" v-show="addForm.businessBelong === '活动归属地'"> <el-text size="large">所属地区:</el-text> <el-cascader v-model="addForm.area" :options="marketOptions" placeholder="请选择所属地区" clearable style="width: 12vw" /> </div> <div class="add-item"> <el-text size="large">开始时间:</el-text> <el-date-picker v-model="addForm.startTime" type="datetime" placeholder="请选择开始时间" :default-time="defaultStartTime" style="width: 12vw" /> </div> <div class="add-item"> <el-text size="large">结束时间:</el-text> <el-date-picker v-model="addForm.endTime" type="datetime" placeholder="请选择结束时间" :default-time="defaultEndTime" style="width: 12vw" /> </div> <div style="display: flex; justify-content: center; margin-top: 5vh;"> <el-button type="primary" @click="hideAdd">取消</el-button> <el-button type="primary" @click="throttleGetActivity">确定</el-button> </div> </el-dialog>
<el-dialog v-model="showEdit" width="20vw" draggable align-center style="background-color: rgb(243,250,254);"> <div class="edit-item"> <el-text size="large">活动名称:</el-text> <el-input v-model="editForm.activityName" style="width: 12vw" placeholder="请输入活动名称" maxlength="200" clearable /> </div>
<div class="edit-item"> <el-text size="large">业绩归属:</el-text> <el-radio-group v-model="editForm.businessBelong" style="width: 12vw"> <el-radio size="large" value="客户归属地">客户归属地</el-radio> <el-radio size="large" value="活动归属地">活动归属地</el-radio> </el-radio-group> </div> <div class="edit-item" v-show="editForm.businessBelong === '活动归属地'"> <el-text size="large">所属地区:</el-text> <el-cascader v-model="editForm.area" :options="marketOptions" placeholder="请选择所属地区" clearable style="width: 12vw" /> </div> <div class="edit-item"> <el-text size="large">开始时间:</el-text> <el-date-picker v-model="editForm.startTime" type="datetime" placeholder="请选择开始时间" :default-time="defaultStartTime" style="width: 12vw" /> </div> <div class="edit-item"> <el-text size="large">结束时间:</el-text> <el-date-picker v-model="editForm.endTime" type="datetime" placeholder="请选择结束时间" :default-time="defaultEndTime" style="width: 12vw" /> </div> <div style="display: flex; justify-content: center; margin-top: 5vh;"> <el-button type="primary" @click="hideEdit">取消</el-button> <el-button type="primary" @click="handleEdit">确定</el-button> </div> </el-dialog>
<ConfirmDialog v-model="showDel" message="删除该活动数据" @confirm="handleDel()" @cancel="hideDel" @close="hideDel" /></template><script setup>import { ElMessage, ElPagination } from 'element-plus';import { onMounted, ref } from 'vue'import API from "@/util/http.js"import moment from 'moment'import { useAdminStore } from "@/store/index.js"import { storeToRefs } from "pinia"import { permissionMapping, hasMenuPermission } from "@/utils/menuTreePermission.js"const adminStore = useAdminStore();const { adminData, menuTree } = storeToRefs(adminStore)import ConfirmDialog from '@/components/dialogs/ConfirmDialog.vue'import _ from 'lodash'// 活动名称正则表达式
const activityNameReg = /^[\u4e00-\u9fa5a-zA-Z0-9,。!?、;:“”()‘’《》【】{}——~,.!?:;'--()""\[\]_&+=]+$/;// 为什么一定要两个--才能成功?????????
const tableData = ref([])const pagination = ref({ pageNum: 1, pageSize: 10, total: 0})const searchForm = ref({ activityName: ''})const showAdd = ref(false)const showEdit = ref(false)const showDel = ref(false)const currentDelRow = ref(null)const addForm = ref({ activityName: '', area: []})const editForm = ref({ activityName: '', businessBelong: '', area: [], startTime: null, endTime: null, id: ''})const marketOptions = ref([])const getActivity = async function () { const rechargeActivity = { activityName: searchForm.value.activityName, businessBelong: searchForm.value.businessBelong, } if (searchForm.value.startTime && moment(searchForm.value.startTime).isValid()) { rechargeActivity.startTime = moment(searchForm.value.startTime).format('YYYY-MM-DD HH:mm:ss'); }
if (searchForm.value.endTime && moment(searchForm.value.endTime).isValid()) { rechargeActivity.endTime = moment(searchForm.value.endTime).format('YYYY-MM-DD HH:mm:ss'); } const params = { pageNum: pagination.value.pageNum, pageSize: pagination.value.pageSize, rechargeActivity } const res = await API({ url: '/admin/coin/rechargeActivityCenter/queryActivity', data: params }) if (res.code === 200) { tableData.value = res.data.list pagination.value.total = res.data.total }}const handleAdd = async function () { const activityName = addForm.value.activityName if (!validateActivityName(activityName)) return
if (!addForm.value.businessBelong) { ElMessage.error('请选择业绩归属') return } if (addForm.value.businessBelong === '活动归属地' && addForm.value.area.length === 0) { ElMessage.error('请选择所属地区') return } if (!addForm.value.startTime) { ElMessage.error('请选择开始时间') return } if (!addForm.value.endTime) { ElMessage.error('请选择结束时间') return } if (addForm.value.businessBelong === '客户归属地') { addForm.value.area = [] }
const params = { activityName: addForm.value.activityName, businessBelong: addForm.value.businessBelong, area: addForm.value.area.length > 0 ? addForm.value.area.slice(-1)[0] : null, startTime: moment(addForm.value.startTime).format('YYYY-MM-DD HH:mm:ss'), endTime: moment(addForm.value.endTime).format('YYYY-MM-DD HH:mm:ss'), creator: adminData.value.id }
const res = await API({ url: '/admin/coin/rechargeActivityCenter/addActivity', data: params }) if (res.code === 200) { ElMessage.success('添加成功') getActivity() hideAdd() addForm.value = { activityName: '', businessBelong: '', area: [], startTime: null, endTime: null, } } else { ElMessage.error(res.msg || '添加失败') return }}// 新增节流
const throttleGetActivity = _.throttle(handleAdd, 5000, { trailing: false });const handleEdit = async function () { const activityName = editForm.value.activityName if (!validateActivityName(activityName)) return
if (!editForm.value.activityName) { ElMessage.error('请输入活动名称') return } if (!editForm.value.businessBelong) { ElMessage.error('请选择业绩归属') return } if (editForm.value.businessBelong === '活动归属地' && editForm.value.area.length === 0) { ElMessage.error('请选择所属地区') return } if (!editForm.value.startTime) { ElMessage.error('请选择开始时间') return } if (!editForm.value.endTime) { ElMessage.error('请选择结束时间') return }
if(editForm.value.businessBelong === '客户归属地'){ editForm.value.area = [] }
const params = { id: editForm.value.id, activityName: editForm.value.activityName, businessBelong: editForm.value.businessBelong, area: editForm.value.area.length > 0 ? editForm.value.area.slice(-1)[0] : null, startTime: moment(editForm.value.startTime).format('YYYY-MM-DD HH:mm:ss'), endTime: moment(editForm.value.endTime).format('YYYY-MM-DD HH:mm:ss'), creator: adminData.value.id } console.log('看看修改params', params) const res = await API({ url: '/admin/coin/rechargeActivityCenter/updateActivity', data: params }) if (res.code === 200) { ElMessage.success('修改成功') getActivity() hideEdit() }}const handleDel = async function (row) { if (!currentDelRow.value) { ElMessage.error('当前选择无数据') return } const res = await API({ url: '/admin/coin/rechargeActivityCenter/deleteActivity', data: { id: currentDelRow.value.id, } }) if (res.code === 200) { ElMessage.success('删除成功') getActivity() showDel.value = false }}const getmarkets = async function () { try { const result = await API({ url: '/market/selectMarket', }); console.log('请求成功', result) // 递归转换树形结构为级联选择器需要的格式(跳过第一级节点)
const transformTree = (nodes) => { // 直接处理第一级节点的子节点
const allChildren = nodes.flatMap(node => node.children || []); return allChildren.map(child => { const grandchildren = child.children && child.children.length ? transformTree([child]) // 递归处理子节点
: null; return { value: child.id, label: child.name, children: grandchildren } }) } marketOptions.value = transformTree(result.data) console.log('转换后的地区树', marketOptions.value) } catch (error) { console.log('请求失败', error) }}const defaultStartTime = [ new Date(2000, 1, 1, 0, 0, 0)]const defaultEndTime = [ new Date(2000, 2, 1, 23, 59, 59)]const hideEdit = () => { showEdit.value = false editForm.value = { activityName: '', businessBelong: '', area: [], startTime: null, endTime: null, id: '' }}const editOpen = (row) => { editForm.value = { id: row.id, activityName: row.activityName, businessBelong: row.businessBelong, area: row.area ? [...row.area] : [] }
if (row.startTime) { editForm.value.startTime = moment(row.startTime).toDate() } if (row.endTime) { editForm.value.endTime = moment(row.endTime).toDate() } console.log('看看editForm', editForm.value) showEdit.value = true}const openDel = (row) => { currentDelRow.value = row showDel.value = true}const hideDel = () => { showDel.value = false currentDelRow.value = null}const reset = () => { searchForm.value = { activityName: '', businessBelong: '', startTime: null, endTime: null } getActivity()}const hideAdd = () => { showAdd.value = false addForm.value = { activityName: '', area: [], startTime: null, endTime: null }}const validateActivityName = (name) => { // 非空校验
if (!name.trim()) { ElMessage.error('活动名称不能为空'); return false; } // 长度校验(限制100字符)
if (name.length > 100) { ElMessage.error('活动名称长度不能超过100字符'); return false; } // 字符格式校验
if (!activityNameReg.test(name)) { ElMessage.error('活动名称仅支持汉字、英文字母、数字及常见标点,中文字符,。!?、;:“ ” ‘ ’ ()《》【】——~,英文字符, . ! ? : ; " ( ) [ ] - _ & + =/') return false; } return true;};const handleSizeChange = function (val) { pagination.pageSize = val getActivity()}const handleCurrentChange = function (val) { pagination.pageNum = val getActivity()}onMounted(() => { getActivity() getmarkets() console.log('看看adminData', adminData.value)})</script><style scoped lang="scss">// 搜索的卡片样式
.card1 { background: #F3FAFE;}
// 表单的卡片样式
.card2 { background: #E7F4FD;}
// 表头背景等
:deep(.el-table__header-wrapper),:deep(.el-table__body-wrapper),:deep(.el-table__cell),/* 表格 */:deep(.el-table__body td) { background-color: #F3FAFE !important;}
/* 表头 */:deep(.el-table__header th) { background-color: #F3FAFE !important;}
/* 鼠标悬停 */:deep(.el-table__row:hover > .el-table__cell) { background-color: #E5EBFE !important;}
.condition { display: flex; align-items: center;}
.condition-item1 { display: flex; align-items: center; width: 15vw;}
.condition-item2 { display: flex; align-items: center; width: 17vw;}
.add-item { display: flex; align-items: center; width: 17vw; margin-bottom: 1vh;}
.edit-item { display: flex; align-items: center; width: 17vw; margin-bottom: 1vh;}</style>
|