若依常用功能-统计
2026-04-02 11:02:46 144浏览
若依常用功能-统计
sql
DROP TABLE IF EXISTS `jf_tj`; CREATE TABLE `jf_tj` ( `day` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '日期', `regnum` int DEFAULT '0' COMMENT '注册人数', `jobnum` int DEFAULT '0' COMMENT '发布岗位数量', `wantjobnum` int DEFAULT '0' COMMENT '简历投递数量', `resumenum` int DEFAULT '0' COMMENT '发布简历数量', `companynum` int DEFAULT '0' COMMENT '公司注册数量', PRIMARY KEY (`day`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='统计';
package com.ruoyi.system.controller;
import java.util.*;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.service.ISysUserService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.JfTj;
import com.ruoyi.system.service.IJfTjService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
* 统计Controller
*
* @author ruoyi
* @date 2026-04-01
*/
@RestController
@RequestMapping("/system/tj")
public class JfTjController extends BaseController
{
@Autowired
private IJfTjService jfTjService;
@Autowired
private ISysUserService userService;
/**
* 查询统计列表
*/
@PreAuthorize("@ss.hasPermi('system:tj:list')")
@GetMapping("/list")
public TableDataInfo list(JfTj jfTj)
{
startPageOrderBy(" day desc");
List<JfTj> list = jfTjService.selectJfTjList(jfTj);
return getDataTable(list);
}
@PreAuthorize("@ss.hasPermi('system:tj:tjt')")
@GetMapping("/getday30")
public AjaxResult getday30(JfTj jfTj)
{
String day30=DateUtils.getDaysAgo(DateUtils.getDate(),30);
jfTj.setDay30(day30);
List<JfTj> list = jfTjService.selectJfTjList(jfTj);
return success(list);
}
@GetMapping("/tjsex")
public AjaxResult tjsex( )
{
SysUser u=new SysUser();
List<SysUser> uli=userService.selectUserList(u);
int all=uli.size();
u.setSex("0");
List<SysUser> uli2=userService.selectUserList(u);
int nan=uli2.size();
u.setSex("1");
List<SysUser> uli3=userService.selectUserList(u);
int nv=uli3.size();
List<Object> all_li=new ArrayList<>();
Map<String,Object> m=new HashMap<>();
m.put("name","男");
m.put("value",nan);
all_li.add(m);
m=new HashMap<>();
m.put("name","女");
m.put("value",nv);
all_li.add(m);
m=new HashMap<>();
m.put("name","未知");
m.put("value",all-nan-nv);
all_li.add(m);
return success(all_li);
}
/**
* 导出统计列表
*/
@PreAuthorize("@ss.hasPermi('system:tj:export')")
@Log(title = "统计", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, JfTj jfTj)
{
List<JfTj> list = jfTjService.selectJfTjList(jfTj);
ExcelUtil<JfTj> util = new ExcelUtil<JfTj>(JfTj.class);
util.exportExcel(response, list, "统计数据");
}
/**
* 获取统计详细信息
*/
@PreAuthorize("@ss.hasPermi('system:tj:query')")
@GetMapping(value = "/{day}")
public AjaxResult getInfo(@PathVariable("day") String day)
{
return success(jfTjService.selectJfTjByDay(day));
}
/**
* 新增统计
*/
@Log(title = "统计", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody JfTj jfTj)
{
String today=DateUtils.getDate();
List<String> last30Days = DateUtils.getLast30Days(today);
for (String date : last30Days) {
int isadd=0;
JfTj t=jfTjService.selectJfTjByDay(date);
if(t==null){
t=new JfTj();
isadd=1;
}
t.setDay(date);
t.setCompanynum(getrand());
t.setJobnum(getrand());
t.setResumenum(getrand());
t.setRegnum(getrand());
t.setWantjobnum(getrand());
if(isadd==1){
jfTjService.insertJfTj(t);
}else{
jfTjService.updateJfTj(t);
}
}
//根据today计算前30天的日期,并循环这些日期字符串,然后添加30条测试数据
return success();
}
private long getrand(){
// 创建Random对象
Random random = new Random();
// 生成1到100之间的随机整数(包含1和100)
int min = 1;
int max = 1000;
int randomInt = random.nextInt(max - min + 1) + min;
return (long)randomInt;
}
/**
* 修改统计
*/
@PreAuthorize("@ss.hasPermi('system:tj:edit')")
@Log(title = "统计", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody JfTj jfTj)
{
return toAjax(jfTjService.updateJfTj(jfTj));
}
/**
* 删除统计
*/
@PreAuthorize("@ss.hasPermi('system:tj:remove')")
@Log(title = "统计", businessType = BusinessType.DELETE)
@DeleteMapping("/{days}")
public AjaxResult remove(@PathVariable String[] days)
{
return toAjax(jfTjService.deleteJfTjByDays(days));
}
}
工具类
/**
* 根据给定日期获取前30天的日期列表
* @param today 今天的日期字符串,格式为 yyyy-MM-dd
* @return 包含前30天日期的列表,按从近到远排序
*/
public static List<String> getLast30Days(String today) {
List<String> dates = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date currentDate = sdf.parse(today);
Calendar calendar = Calendar.getInstance();
calendar.setTime(currentDate);
// 循环获取前30天的日期
for (int i = 0; i < 30; i++) {
calendar.add(Calendar.DAY_OF_MONTH, -1); // 向前推一天
String dateStr = sdf.format(calendar.getTime());
dates.add(dateStr);
}
} catch (Exception e) {
e.printStackTrace();
}
return dates;
}
public static String getDaysAgo(String dateString, int daysAgo) {
try {
// 定义输入日期的格式
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 解析输入的日期字符串
LocalDate inputDate = LocalDate.parse(dateString, inputFormatter);
// 计算几天前的日期
LocalDate resultDate = inputDate.minusDays(daysAgo);
// 定义输出格式
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
// 返回格式化后的日期字符串
return resultDate.format(outputFormatter);
} catch (DateTimeParseException e) {
return "日期格式错误,请使用 yyyy-MM-dd 格式";
}
}
tjt.vue
<template>
<div class="app-container">
<el-card>
<el-row>
<el-col :span="14"> <div style=" width:100%; height: 400px;margin-top: 20px;" id="reg_tjt"></div> </el-col>
<el-col :span="10"><div style="width:100%; height: 400px;margin-top: 20px;" id="tjsex"></div></el-col>
</el-row>
</el-card>
<el-card>
<div style="width:100%; height: 400px;margin-top: 20px;" id="wantjob_tjt"></div>
</el-card>
<el-card>
<div style=" width:100%; height: 400px;margin-top: 20px;" id="job_tjt"></div>
</el-card>
<el-card>
<div style=" width:100%; height: 400px;margin-top: 20px;" id="company_tjt"></div>
</el-card>
<el-card>
<div style=" width:100%; height: 400px;margin-top: 20px;" id="resume_tjt"></div>
</el-card>
</div>
</template>
<script>
import { getday30,tjsex } from "@/api/system/tj"
import * as echarts from 'echarts'
export default {
name: "Tj",
data() {
return {
}
},
created() {
this.getdata()
this.getshanxing()
},
methods: {
getdata(){
getday30({}).then((res) => {
let li=res.data;
let regnumli=[];
let companynumli=[];
let jobnumli=[];
let wantjobnumli=[];
let resumenumli=[];
let x=[];
for(let i=0;i<li.length;i++){
x.push(li[i].day);
regnumli.push(li[i].regnum);
companynumli.push(li[i].companynum);
jobnumli.push(li[i].jobnum);
wantjobnumli.push(li[i].wantjobnum);
resumenumli.push(li[i].resumenum);
}
this.print_tjt('reg_tjt','最近30天新用户注册量','新用户注册量',x,'line',regnumli)
this.print_tjt('company_tjt','最近30天注册企业量','注册企业量',x,'bar',companynumli)
this.print_tjt('job_tjt','最近30天新岗位量','新岗位量',x,'bar',jobnumli)
this.print_tjt('wantjob_tjt','最近30天投递简历量','投递简历量',x,'line',wantjobnumli)
this.print_tjt('resume_tjt','最近30天发布简历量','发布简历',x,'bar',resumenumli)
})
},
print_tjt(div_id,title,iname,x,type,li){
// 基于准备好的dom,初始化echarts实例
let myChart = echarts.init(document.getElementById(div_id))
// 绘制图表
myChart.setOption({
title: { text:title },
legend:{
data:[iname]
},
tooltip: {},
xAxis: {
data: x
},
yAxis: {},
series: [{
name: iname,
type: type,
data: li
}
]
});
},
getshanxing(){
//扇形图
tjsex({}).then((res) => {
let li=res.data;
// 基于准备好的dom,初始化echarts实例,
const myChart = echarts.init(document.getElementById('tjsex'))
myChart.setOption({
title: { text: '注册用户性别比例' },
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)' // 具体a b c d 代表的属性看下面注释啦
},
series: [
{
name: '比例', // formatter 中的a
type: 'pie',
radius: '33%',
center: ['33%', '33%','33%'],
data: li, // data 中的name为formatter中的 b;data中的value呢就是formatter中c;至于d就是Echarts计算出来的百分比啦;itemStyle:为饼图每个扇形的颜色;label为指示线后面的文字的样式,labelLine为指示线的颜色
label: {
normal: {
show: true,
textStyle: {
fontWeight: 400,
fontSize: 12 // 文字的字体大小
},
formatter: '{b} \n {c}人' // 这里为指示线后面的提示信息,这里的换行要用\n 与上面tooltips中的formatter换行不同滴
}
},
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
})
})
},
}
}
</script>
tj/index.vue
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
<el-form-item label="日期" prop="day">
<el-date-picker
v-model="queryParams.day"
placeholder="日期"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['system:tj:add']"
>新增测试数据</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:tj:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['system:tj:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="tjList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="日期" align="center" prop="day" />
<el-table-column label="注册人数" align="center" prop="regnum" />
<el-table-column label="发布岗位数量" align="center" prop="jobnum" />
<el-table-column label="简历投递数量" align="center" prop="wantjobnum" />
<el-table-column label="发布简历数量" align="center" prop="resumenum" />
<el-table-column label="公司注册数量" align="center" prop="companynum" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:tj:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改统计对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="注册人数" prop="regnum">
<el-input v-model="form.regnum" placeholder="请输入注册人数" />
</el-form-item>
<el-form-item label="发布岗位数量" prop="jobnum">
<el-input v-model="form.jobnum" placeholder="请输入发布岗位数量" />
</el-form-item>
<el-form-item label="简历投递数量" prop="wantjobnum">
<el-input v-model="form.wantjobnum" placeholder="请输入简历投递数量" />
</el-form-item>
<el-form-item label="发布简历数量" prop="resumenum">
<el-input v-model="form.resumenum" placeholder="请输入发布简历数量" />
</el-form-item>
<el-form-item label="公司注册数量" prop="companynum">
<el-input v-model="form.companynum" placeholder="请输入公司注册数量" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listTj, getTj, delTj, addTj, updateTj } from "@/api/system/tj"
export default {
name: "Tj",
data() {
return {
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 统计表格数据
tjList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
day: null,
},
// 表单参数
form: {},
// 表单校验
rules: {
}
}
},
created() {
this.getList()
},
methods: {
/** 查询统计列表 */
getList() {
this.loading = true
listTj(this.queryParams).then(response => {
this.tjList = response.rows
this.total = response.total
this.loading = false
})
},
// 取消按钮
cancel() {
this.open = false
this.reset()
},
// 表单重置
reset() {
this.form = {
day: null,
regnum: null,
jobnum: null,
wantjobnum: null,
resumenum: null,
companynum: null
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.day)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
// this.reset()
// this.open = true
// this.title = "添加统计"
addTj(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const day = row.day || this.ids
getTj(day).then(response => {
this.form = response.data
this.open = true
this.title = "修改统计"
})
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.day != null) {
updateTj(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addTj(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const days = row.day || this.ids
this.$modal.confirm('是否确认删除统计编号为"' + days + '"的数据项?').then(function() {
return delTj(days)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('system/tj/export', {
...this.queryParams
}, `tj_${new Date().getTime()}.xlsx`)
}
}
}
</script>
别忘了添加权限
user的sql
<if test="sex != null and sex != ''">
AND u.sex = #{sex}
</if>
<if test="createTime != null and createTime != ''">
AND DATE_FORMAT(u.create_time, '%Y-%m-%d') LIKE CONCAT('%', DATE_FORMAT(#{createTime}), '%')
</if>
tool
package com.ruoyi.system.tools;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import java.util.Date;
import java.util.List;
public class TjTool {
public void tj_regnum(IJfTjService jfTjService, ISysUserService userService){
String today= DateUtils.getDate();
SysUser c=new SysUser();
c.setCreateTime(new Date());
List<SysUser> li=userService.selectUserList(c);
int regnum=0;
if(li!=null)regnum=li.size();
int add=0;
JfTj ol=jfTjService.selectJfTjByDay(today);
if(ol==null){
ol=new JfTj();
add=1;
}
ol.setDay(today);
ol.setRegnum((long)regnum);
if(add==0)jfTjService.updateJfTj(ol);
else jfTjService.insertJfTj(ol);
}
public void tj_jobnum(IJfTjService jfTjService, IJfJobService jfJobService){
String today= DateUtils.getDate();
JfJob c=new JfJob();
c.setCts(today);
List<JfJob> li=jfJobService.selectJfJobList(c);
int jobnum=0;
if(li!=null)jobnum=li.size();
int add=0;
JfTj ol=jfTjService.selectJfTjByDay(today);
if(ol==null){
ol=new JfTj();
add=1;
}
ol.setDay(today);
ol.setJobnum((long)jobnum);
if(add==0)jfTjService.updateJfTj(ol);
else jfTjService.insertJfTj(ol);
}
public void tj_wantjobnum(IJfTjService jfTjService, IJfWantjobService jfWantjobService){
String today= DateUtils.getDate();
JfWantjob c=new JfWantjob();
c.setCts(today);
List<JfWantjob> li=jfWantjobService.selectJfWantjobList(c);
int wantjobnum=0;
if(li!=null)wantjobnum=li.size();
int add=0;
JfTj ol=jfTjService.selectJfTjByDay(today);
if(ol==null){
ol=new JfTj();
add=1;
}
ol.setDay(today);
ol.setWantjobnum((long)wantjobnum);
if(add==0)jfTjService.updateJfTj(ol);
else jfTjService.insertJfTj(ol);
}
public void tj_resumenum(IJfTjService jfTjService, IJfResumeService jfResumeService){
String today= DateUtils.getDate();
JfResume c=new JfResume();
c.setCts(today);
List<JfResume> li=jfResumeService.selectJfResumeList(c);
int resumenum=0;
if(li!=null)resumenum=li.size();
int add=0;
JfTj ol=jfTjService.selectJfTjByDay(today);
if(ol==null){
ol=new JfTj();
add=1;
}
ol.setDay(today);
ol.setResumenum((long)resumenum);
if(add==0)jfTjService.updateJfTj(ol);
else jfTjService.insertJfTj(ol);
}
public void tj_companynum(IJfTjService jfTjService, IJfCompanyService jfCompanyService){
String today= DateUtils.getDate();
JfCompany c=new JfCompany();
c.setCts(today);
List<JfCompany> li=jfCompanyService.selectJfCompanyList(c);
int companynum=0;
if(li!=null)companynum=li.size();
int add=0;
JfTj ol=jfTjService.selectJfTjByDay(today);
if(ol==null){
ol=new JfTj();
add=1;
}
ol.setDay(today);
ol.setCompanynum((long)companynum);
if(add==0)jfTjService.updateJfTj(ol);
else jfTjService.insertJfTj(ol);
}
}
统计注册用户的在注册vue里调用
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
暂无评论,快来写一下吧
展开评论
您可能感兴趣的博客
他的专栏
他感兴趣的技术


java
vue
springboot
Mysql
ssm
小程序
uniapp
js和jquery