kpi 统计
This commit is contained in:
@@ -0,0 +1,109 @@
|
|||||||
|
import request from '@/utils/http'
|
||||||
|
|
||||||
|
export class kpiService {
|
||||||
|
// 月度-业绩 列表
|
||||||
|
static getmonthlylist(params: Api.Common.PaginatingParams) {
|
||||||
|
return request.get<Api.Common.CommonListData>({
|
||||||
|
url: '/admin/targets/monthly/list',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 月度-业绩 添加
|
||||||
|
static addmonthly(params: any) {
|
||||||
|
return request.post<Api.Common.AddResponse>({
|
||||||
|
url: '/admin/targets/monthly/store',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 月度-业绩 删除
|
||||||
|
static deletemonthly(params: any) {
|
||||||
|
return request.post<Api.Common.AddResponse>({
|
||||||
|
url: '/admin/targets/monthly/destroy',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 月度-业绩 修改
|
||||||
|
static updatemonthly(params: any) {
|
||||||
|
return request.post<Api.Common.AddResponse>({
|
||||||
|
url: '/admin/targets/monthly/update',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 月度-业绩 详情
|
||||||
|
static detailmonthly(params: any) {
|
||||||
|
return request.get<any>({
|
||||||
|
url: '/admin/targets/monthly/show',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//年度-业绩 列表
|
||||||
|
static getyearlylist(params: Api.Common.PaginatingParams) {
|
||||||
|
return request.get<Api.Common.CommonListData>({
|
||||||
|
url: '/admin/targets/annual/list',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 年度-业绩 添加
|
||||||
|
static addyearly(params: any) {
|
||||||
|
return request.post<Api.Common.AddResponse>({
|
||||||
|
url: '/admin/targets/annual/store',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 年度-业绩 删除
|
||||||
|
static deleteyearly(params: any) {
|
||||||
|
return request.post<Api.Common.AddResponse>({
|
||||||
|
url: '/admin/targets/annual/destroy',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 年度-业绩 详情
|
||||||
|
static detailyearly(params: any) {
|
||||||
|
return request.get<any>({
|
||||||
|
url: '/admin/targets/annual/show',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 年度-业绩 修改
|
||||||
|
static updateyearly(params: any) {
|
||||||
|
return request.post<Api.Common.AddResponse>({
|
||||||
|
url: '/admin/targets/annual/update',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//年度-公司目标完成率
|
||||||
|
static statisticstotal(params: any) {
|
||||||
|
return request.get<any>({
|
||||||
|
url: '/admin/targets/statistics/total',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//年度-个人销售数量排名
|
||||||
|
static statisticsranking(params: any) {
|
||||||
|
return request.get<any>({
|
||||||
|
url: '/admin/targets/statistics/ranking',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//年度-业务KPI分月完成数量表
|
||||||
|
static statisticsmonthly(params: any) {
|
||||||
|
return request.get<any>({
|
||||||
|
url: '/admin/targets/statistics/user/month',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//年度-个人年度目标完成度(百分比)
|
||||||
|
static statisticspercentage(params: any) {
|
||||||
|
return request.get<any>({
|
||||||
|
url: '/admin/targets/statistics/user/progressh',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//年度-个人累积完成数量(辆)
|
||||||
|
static statisticscumulative(params: any) {
|
||||||
|
return request.get<any>({
|
||||||
|
url: '/admin/targets/statistics/user/achieved',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,345 @@
|
|||||||
|
<template>
|
||||||
|
<div class="color-page">
|
||||||
|
<div class="color-toolbar boxshadow">
|
||||||
|
<div class="color-search-group">
|
||||||
|
<el-form-item label="关键字:" label-width="70px">
|
||||||
|
<el-input
|
||||||
|
style="min-width: 120px"
|
||||||
|
v-model="keyword"
|
||||||
|
placeholder="请输入关键字"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="getannualList"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="getannualList" v-ripple>搜索</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="boxshadow">
|
||||||
|
<ElRow>
|
||||||
|
<div style="width: 12px"></div>
|
||||||
|
<ElCol :xs="24" :sm="12" :lg="6" class="el-col2">
|
||||||
|
<ElButton
|
||||||
|
@click="showDialog('add')"
|
||||||
|
v-ripple
|
||||||
|
v-if="hasAuth('kpi_annual@add')"
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
新增
|
||||||
|
</ElButton>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
<ArtTable
|
||||||
|
ref="tableRef"
|
||||||
|
row-key="id"
|
||||||
|
:loading="loading"
|
||||||
|
:data="tableData"
|
||||||
|
:currentPage="pagination.currentPage"
|
||||||
|
:pageSize="pagination.pageSize"
|
||||||
|
:total="pagination.total"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
>
|
||||||
|
<template #default>
|
||||||
|
<ElTableColumn label="公司" prop="corp_id">
|
||||||
|
<template #default="scope">
|
||||||
|
<p> {{ scope.row.corp_name ? scope.row.corp_name : '' }}</p>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
<ElTableColumn label="年份" prop="year" />
|
||||||
|
<ElTableColumn label="业务员" prop="user_name" />
|
||||||
|
<ElTableColumn label="年度目标数" prop="annual_target" />
|
||||||
|
<ElTableColumn label="创建时间" prop="created_at" />
|
||||||
|
<ElTableColumn fixed="right" label="操作" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<ElRow>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
@click="showDialog('edit', scope.row)"
|
||||||
|
v-if="hasAuth('kpi_annual@update')"
|
||||||
|
>编辑</el-button
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
link
|
||||||
|
@click="deleteColor(scope.row)"
|
||||||
|
v-if="hasAuth('kpi_annual@destroy')"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</ElRow>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
</template>
|
||||||
|
</ArtTable>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 新增/编辑对话框 -->
|
||||||
|
<ElDialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="dialogType === 'add' ? '新增' : '编辑'"
|
||||||
|
align-center
|
||||||
|
width="600px"
|
||||||
|
>
|
||||||
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="100px" class="form">
|
||||||
|
<ElFormItem label="公司" prop="corp_id">
|
||||||
|
<ElSelect v-model="form.corp_id" placeholder="请选择公司">
|
||||||
|
<ElOption
|
||||||
|
v-for="item in companyList"
|
||||||
|
:key="item.id"
|
||||||
|
:value="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
></ElOption>
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem label="年份" prop="year">
|
||||||
|
<ElInputNumber v-model="form.year" :min="1970" :max="2999" style="width: 100%" />
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem label="业务员" prop="user_id">
|
||||||
|
<ElSelect v-model="form.user_id" filterable placeholder="请选择业务员">
|
||||||
|
<el-option
|
||||||
|
v-for="item in companyUserList"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem label="年度目标数" prop="annual_target">
|
||||||
|
<ElInputNumber v-model="form.annual_target" :min="0" :max="999" style="width: 100%" />
|
||||||
|
</ElFormItem>
|
||||||
|
</ElForm>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<ElButton @click="dialogVisible = false">取消</ElButton>
|
||||||
|
<ElButton type="primary" @click="handleSubmit(formRef)">提交</ElButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ElDialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
|
import { kpiService } from '@/api/admin/kpi'
|
||||||
|
import { useAuth } from '@/composables/useAuth'
|
||||||
|
import { UserService } from '@/api/usersApi'
|
||||||
|
import { manageService } from '@/api/adminApi'
|
||||||
|
|
||||||
|
const { hasAuth } = useAuth()
|
||||||
|
defineOptions({ name: 'AdminKpiAnnual' })
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const loading = ref(false)
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const dialogType = ref('add')
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const keyword = ref<string>('')
|
||||||
|
// 获取公司列表
|
||||||
|
const companyList = ref<any>()
|
||||||
|
const getCompanyList = async () => {
|
||||||
|
const response = await UserService.getCompanyList()
|
||||||
|
companyList.value = response || []
|
||||||
|
}
|
||||||
|
const companyUserList = ref<any>()
|
||||||
|
// 获取用户列表
|
||||||
|
const getCompanyUserList = async () => {
|
||||||
|
const response = await manageService.presetusers()
|
||||||
|
companyUserList.value = response || []
|
||||||
|
}
|
||||||
|
// 表单数据
|
||||||
|
const form = reactive<any>({
|
||||||
|
id: '',
|
||||||
|
corp_id: '',
|
||||||
|
year: '',
|
||||||
|
user_id: '',
|
||||||
|
annual_target: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = reactive<FormRules>({
|
||||||
|
corp_id: [{ required: true, message: '请选择公司', trigger: 'blur' }],
|
||||||
|
year: [{ required: true, message: '请输入年份', trigger: 'blur' }],
|
||||||
|
user_id: [{ required: true, message: '请选择业务员', trigger: 'blur' }],
|
||||||
|
annual_target: [{ required: true, message: '请输入年度目标数', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
|
||||||
|
// 分页数据
|
||||||
|
const pagination = reactive({
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const tableData = ref<any[]>([])
|
||||||
|
const tableRef = ref()
|
||||||
|
|
||||||
|
// 生命周期
|
||||||
|
onMounted(() => {
|
||||||
|
getannualList()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听搜索条件变化
|
||||||
|
watch([keyword], () => {
|
||||||
|
pagination.currentPage = 1
|
||||||
|
getannualList()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取颜色列表
|
||||||
|
const getannualList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const { currentPage, pageSize } = pagination
|
||||||
|
const params = {
|
||||||
|
current: currentPage,
|
||||||
|
size: pageSize,
|
||||||
|
keyword: keyword.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const { records, current, size, total } = await kpiService.getyearlylist(params)
|
||||||
|
tableData.value = records || []
|
||||||
|
Object.assign(pagination, { currentPage: current, pageSize: size, total })
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取颜色列表失败:', error)
|
||||||
|
ElMessage.error('获取颜色列表失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理分页变化
|
||||||
|
const handleSizeChange = (newPageSize: number) => {
|
||||||
|
pagination.pageSize = newPageSize
|
||||||
|
getannualList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (newCurrentPage: number) => {
|
||||||
|
pagination.currentPage = newCurrentPage
|
||||||
|
getannualList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示对话框
|
||||||
|
const showDialog = (type: string, row?: any) => {
|
||||||
|
getCompanyList()
|
||||||
|
getCompanyUserList()
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogType.value = type
|
||||||
|
if (type === 'edit' && row) {
|
||||||
|
// 编辑模式
|
||||||
|
Object.assign(form, {
|
||||||
|
id: row.id,
|
||||||
|
corp_id: row.corp_id,
|
||||||
|
year: row.year,
|
||||||
|
user_id: row.user_id,
|
||||||
|
annual_target: row.annual_target
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 新增模式
|
||||||
|
Object.assign(form, {
|
||||||
|
id: '',
|
||||||
|
corp_id: '',
|
||||||
|
year: '',
|
||||||
|
user_id: '',
|
||||||
|
annual_target: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除年度目标
|
||||||
|
const deleteColor = (row: any) => {
|
||||||
|
ElMessageBox.confirm('确定删除该年度目标吗?', '删除确认', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'error'
|
||||||
|
}).then(async () => {
|
||||||
|
try {
|
||||||
|
const { message } = await kpiService.deleteyearly({ id: row.id })
|
||||||
|
ElMessage.success(message)
|
||||||
|
getannualList()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败:', error)
|
||||||
|
ElMessage.error('删除失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return
|
||||||
|
await formEl.validate(async (valid) => {
|
||||||
|
if (!valid) return
|
||||||
|
try {
|
||||||
|
if (dialogType.value === 'add') {
|
||||||
|
// 新增
|
||||||
|
const { message } = await kpiService.addyearly({
|
||||||
|
corp_id: form.corp_id,
|
||||||
|
year: form.year,
|
||||||
|
user_id: form.user_id,
|
||||||
|
annual_target: form.annual_target
|
||||||
|
})
|
||||||
|
ElMessage.success(message)
|
||||||
|
} else {
|
||||||
|
// 编辑
|
||||||
|
const { message } = await kpiService.updateyearly({
|
||||||
|
id: form.id,
|
||||||
|
corp_id: form.corp_id,
|
||||||
|
year: form.year,
|
||||||
|
user_id: form.user_id,
|
||||||
|
annual_target: form.annual_target
|
||||||
|
})
|
||||||
|
ElMessage.success(message)
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
getannualList()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('操作失败:', error)
|
||||||
|
ElMessage.error('操作失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-table__empty-block) {
|
||||||
|
height: 100% !important;
|
||||||
|
min-height: 200px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-page {
|
||||||
|
background: var(--art-main-bg-color);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-toolbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding: 20px 20px;
|
||||||
|
background: var(--art-main-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-search-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-col2 {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,331 @@
|
|||||||
|
<template>
|
||||||
|
<div class="color-page">
|
||||||
|
<div class="color-toolbar boxshadow">
|
||||||
|
<div class="color-search-group">
|
||||||
|
<el-form-item label="关键字:" label-width="70px">
|
||||||
|
<el-input
|
||||||
|
style="min-width: 120px"
|
||||||
|
v-model="keyword"
|
||||||
|
placeholder="请输入关键字"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="getMonthlyList"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="getMonthlyList" v-ripple>搜索</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="boxshadow">
|
||||||
|
<ElRow>
|
||||||
|
<div style="width: 12px"></div>
|
||||||
|
<ElCol :xs="24" :sm="12" :lg="6" class="el-col2">
|
||||||
|
<ElButton
|
||||||
|
@click="showDialog('add')"
|
||||||
|
v-ripple
|
||||||
|
v-if="hasAuth('kpi_monthly@add')"
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
新增
|
||||||
|
</ElButton>
|
||||||
|
</ElCol>
|
||||||
|
</ElRow>
|
||||||
|
<ArtTable
|
||||||
|
ref="tableRef"
|
||||||
|
row-key="id"
|
||||||
|
:loading="loading"
|
||||||
|
:data="tableData"
|
||||||
|
:currentPage="pagination.currentPage"
|
||||||
|
:pageSize="pagination.pageSize"
|
||||||
|
:total="pagination.total"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
>
|
||||||
|
<template #default>
|
||||||
|
<ElTableColumn label="用户" prop="user_name" min-width="120" />
|
||||||
|
<ElTableColumn label="年份" prop="year" min-width="120" />
|
||||||
|
<ElTableColumn label="月份" prop="month" min-width="120" />
|
||||||
|
<ElTableColumn label="本月销售数" prop="achieved" min-width="140" />
|
||||||
|
<ElTableColumn fixed="right" label="操作" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<ElRow>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
@click="showDialog('edit', scope.row)"
|
||||||
|
v-if="hasAuth('kpi_monthly@update')"
|
||||||
|
>编辑</el-button
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
link
|
||||||
|
@click="deleteMonthly(scope.row)"
|
||||||
|
v-if="hasAuth('kpi_monthly@destroy')"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</ElRow>
|
||||||
|
</template>
|
||||||
|
</ElTableColumn>
|
||||||
|
</template>
|
||||||
|
</ArtTable>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 新增/编辑对话框 -->
|
||||||
|
<ElDialog
|
||||||
|
v-model="dialogVisible"
|
||||||
|
:title="dialogType === 'add' ? '新增月度-业绩' : '编辑月度-业绩'"
|
||||||
|
align-center
|
||||||
|
width="600px"
|
||||||
|
>
|
||||||
|
<ElForm ref="formRef" :model="form" :rules="rules" label-width="100px" class="form">
|
||||||
|
<ElFormItem label="用户ID" prop="user_id">
|
||||||
|
<ElSelect v-model="form.user_id" filterable placeholder="请选择用户">
|
||||||
|
<ElOption
|
||||||
|
v-for="item in companyUserList"
|
||||||
|
:key="item.id"
|
||||||
|
:value="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
/>
|
||||||
|
</ElSelect>
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem label="年份" prop="year">
|
||||||
|
<ElInputNumber v-model="form.year" :min="1970" :max="2999" style="width: 100%" />
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem label="月份" prop="month">
|
||||||
|
<ElInputNumber v-model="form.month" :min="1" :max="12" style="width: 100%" />
|
||||||
|
</ElFormItem>
|
||||||
|
<ElFormItem label="本月销售数" prop="achieved">
|
||||||
|
<ElInputNumber v-model="form.achieved" :min="0" :max="999999" style="width: 100%" />
|
||||||
|
</ElFormItem>
|
||||||
|
<!-- 预留字段:目标数,不显示,仅占位保存 -->
|
||||||
|
<input type="hidden" v-model="form.target" />
|
||||||
|
</ElForm>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<ElButton @click="dialogVisible = false">取消</ElButton>
|
||||||
|
<ElButton type="primary" @click="handleSubmit(formRef)">提交</ElButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ElDialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
|
import { kpiService } from '@/api/admin/kpi'
|
||||||
|
import { useAuth } from '@/composables/useAuth'
|
||||||
|
import { manageService } from '@/api/adminApi'
|
||||||
|
|
||||||
|
const { hasAuth } = useAuth()
|
||||||
|
defineOptions({ name: 'AdminKpiMonthly' })
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const loading = ref(false)
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const dialogType = ref('add')
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const keyword = ref<string>('')
|
||||||
|
const companyUserList = ref<any>()
|
||||||
|
// 获取用户列表
|
||||||
|
const getCompanyUserList = async () => {
|
||||||
|
const response = await manageService.presetusers()
|
||||||
|
companyUserList.value = response || []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const form = reactive<any>({
|
||||||
|
id: '',
|
||||||
|
user_id: '',
|
||||||
|
year: new Date().getFullYear(),
|
||||||
|
month: new Date().getMonth() + 1,
|
||||||
|
achieved: 0,
|
||||||
|
target: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = reactive<FormRules>({
|
||||||
|
user_id: [{ required: true, message: '请输入用户ID', trigger: 'blur' }],
|
||||||
|
year: [{ required: true, message: '请输入年份', trigger: 'change' }],
|
||||||
|
month: [{ required: true, message: '请输入月份', trigger: 'change' }],
|
||||||
|
achieved: [{ required: true, message: '请输入本月销售数', trigger: 'change' }]
|
||||||
|
})
|
||||||
|
|
||||||
|
// 分页数据
|
||||||
|
const pagination = reactive({
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const tableData = ref<any[]>([])
|
||||||
|
const tableRef = ref()
|
||||||
|
|
||||||
|
// 生命周期
|
||||||
|
onMounted(() => {
|
||||||
|
getMonthlyList()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听搜索条件变化
|
||||||
|
watch([keyword], () => {
|
||||||
|
pagination.currentPage = 1
|
||||||
|
getMonthlyList()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取月度业绩列表
|
||||||
|
const getMonthlyList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const { currentPage, pageSize } = pagination
|
||||||
|
const params = {
|
||||||
|
current: currentPage,
|
||||||
|
size: pageSize,
|
||||||
|
keyword: keyword.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const { records, current, size, total } = await kpiService.getmonthlylist(params)
|
||||||
|
tableData.value = records || []
|
||||||
|
Object.assign(pagination, { currentPage: current, pageSize: size, total })
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取列表失败:', error)
|
||||||
|
ElMessage.error('获取列表失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理分页变化
|
||||||
|
const handleSizeChange = (newPageSize: number) => {
|
||||||
|
pagination.pageSize = newPageSize
|
||||||
|
getMonthlyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCurrentChange = (newCurrentPage: number) => {
|
||||||
|
pagination.currentPage = newCurrentPage
|
||||||
|
getMonthlyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示对话框
|
||||||
|
const showDialog = (type: string, row?: any) => {
|
||||||
|
getCompanyUserList()
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogType.value = type
|
||||||
|
if (type === 'edit' && row) {
|
||||||
|
// 编辑模式
|
||||||
|
Object.assign(form, {
|
||||||
|
id: row.id,
|
||||||
|
user_id: row.user_id,
|
||||||
|
year: row.year,
|
||||||
|
month: row.month,
|
||||||
|
achieved: row.achieved,
|
||||||
|
target: row.target
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 新增模式
|
||||||
|
Object.assign(form, {
|
||||||
|
id: '',
|
||||||
|
user_id: '',
|
||||||
|
year: new Date().getFullYear(),
|
||||||
|
month: new Date().getMonth() + 1,
|
||||||
|
achieved: 0,
|
||||||
|
target: undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除月度业绩
|
||||||
|
const deleteMonthly = (row: any) => {
|
||||||
|
ElMessageBox.confirm('确定删除该记录吗?', '删除确认', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'error'
|
||||||
|
}).then(async () => {
|
||||||
|
try {
|
||||||
|
const { message } = await kpiService.deletemonthly({ id: row.id })
|
||||||
|
ElMessage.success(message)
|
||||||
|
getMonthlyList()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('删除失败:', error)
|
||||||
|
ElMessage.error('删除失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return
|
||||||
|
await formEl.validate(async (valid) => {
|
||||||
|
if (!valid) return
|
||||||
|
try {
|
||||||
|
if (dialogType.value === 'add') {
|
||||||
|
// 新增
|
||||||
|
const { message } = await kpiService.addmonthly({
|
||||||
|
user_id: form.user_id,
|
||||||
|
year: form.year,
|
||||||
|
month: form.month,
|
||||||
|
achieved: form.achieved
|
||||||
|
})
|
||||||
|
ElMessage.success(message)
|
||||||
|
} else {
|
||||||
|
// 编辑
|
||||||
|
const { message } = await kpiService.updatemonthly({
|
||||||
|
id: form.id,
|
||||||
|
user_id: form.user_id,
|
||||||
|
year: form.year,
|
||||||
|
month: form.month,
|
||||||
|
achieved: form.achieved
|
||||||
|
})
|
||||||
|
ElMessage.success(message)
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
getMonthlyList()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('操作失败:', error)
|
||||||
|
ElMessage.error('操作失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-table__empty-block) {
|
||||||
|
height: 100% !important;
|
||||||
|
min-height: 200px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-page {
|
||||||
|
background: var(--art-main-bg-color);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-toolbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding: 20px 20px;
|
||||||
|
background: var(--art-main-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-search-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-col2 {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user