You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
521 lines
19 KiB
521 lines
19 KiB
<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>
|