【商城实战(75)】数据分析指标体系搭建:从0到1的技术指南

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想深入钻研技术细节,还是探寻商城运营之道,本专栏都能提供从 0 到 1 的系统讲解,助力你打造独具竞争力的电商平台,开启电商实战之旅。

目录

  • 一、核心数据分析指标定义与实现
    • 1.1 GMV 指标
    • 1.2 转化率指标
    • 1.3 用户留存率指标
  • 二、构建指标计算模型
    • 2.1 指标计算方法
    • 2.2 数据来源确定
    • 2.3 实现源码展示
  • 三、建立指标监控体系
    • 3.1 实时跟踪方案
    • 3.2 趋势展示实现
    • 3.3 异常预警机制


一、核心数据分析指标定义与实现

1.1 GMV 指标

GMV(Gross Merchandise Volume)即总销售额,是衡量商城业务规模的重要指标。它反映了在一定时期内商城通过销售商品所获得的总收入,包含了所有已完成订单的商品总价,无论这些订单是否最终发生退货或退款。通过分析 GMV,我们可以直观地了解商城的销售表现,评估业务增长趋势,进而为制定营销策略、规划库存等提供数据支持。

在后端,利用 Spring Boot 和 MyBatis-Plus 实现计算 GMV 的接口。假设我们的订单表名为order,其中包含订单金额字段order_amount,可以通过以下代码实现:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> {public Double calculateGMV() {QueryWrapper<Order> wrapper = new QueryWrapper<>();// 假设order_amount是订单金额字段wrapper.select("SUM(order_amount) as gmv");return baseMapper.selectMaps(wrapper).stream().findFirst().map(map -> (Double) map.get("gmv")).orElse(0.0);}
}

对应的 Controller 层代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class OrderController {@Autowiredprivate OrderServiceImpl orderService;@GetMapping("/gmv")public Double getGMV() {return orderService.calculateGMV();}
}

在前端,使用 uniapp 时,可以通过以下代码调用该接口展示 GMV 数据:

<template><view><text>GMV: {{ gmv }}</text></view>
</template><script>
export default {data() {return {gmv: 0};},onLoad() {this.fetchGMV();},methods: {fetchGMV() {uni.request({url: 'http://your-server-url/gmv',success: (res) => {this.gmv = res.data;},fail: (error) => {console.log(error);}});}}
};
</script>

使用 Element plus 时,假设在一个 Vue 组件中:

<template><el-card><div slot="header">GMV统计</div><p>GMV: {{ gmv }}</p></el-card>
</template><script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';const gmv = ref(0);onMounted(() => {axios.get('http://your-server-url/gmv').then(response => {gmv.value = response.data;}).catch(error => {console.log(error);});
});
</script>

1.2 转化率指标

转化率在商城中通常指购买转化率,即完成购买行为的用户数量与访问商城或特定商品页面的用户数量之比。它体现了商城引导用户完成购买的能力,是衡量商城运营效果和用户体验的关键指标。较高的转化率意味着商城在商品展示、用户引导、购物流程等方面表现良好,能够有效地将流量转化为实际销售;反之,则需要深入分析原因,进行针对性优化。

后端实现计算转化率的接口,假设我们有用户访问记录表user_visit和订单表order,user_visit表记录了用户的访问信息,order表记录了订单信息。可以通过以下代码计算购买转化率:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;@Service
public class ConversionRateServiceImpl extends ServiceImpl<ConversionRateMapper, ConversionRate> {public Double calculateConversionRate() {// 计算访问用户数QueryWrapper<UserVisit> visitWrapper = new QueryWrapper<>();Long visitCount = baseMapper.selectCount(visitWrapper);// 计算下单用户数QueryWrapper<Order> orderWrapper = new QueryWrapper<>();orderWrapper.select("DISTINCT user_id");Long orderUserCount = baseMapper.selectMaps(orderWrapper).size();if (visitCount == 0) {return 0.0;}return (double) orderUserCount / visitCount;}
}

对应的 Controller 层代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ConversionRateController {@Autowiredprivate ConversionRateServiceImpl conversionRateService;@GetMapping("/conversion-rate")public Double getConversionRate() {return conversionRateService.calculateConversionRate();}
}

前端 uniapp 调用示例:

<template><view><text>购买转化率: {{ conversionRate }}</text></view>
</template><script>
export default {data() {return {conversionRate: 0};},onLoad() {this.fetchConversionRate();},methods: {fetchConversionRate() {uni.request({url: 'http://your-server-url/conversion-rate',success: (res) => {this.conversionRate = res.data;},fail: (error) => {console.log(error);}});}}
};
</script>

Element plus 前端调用示例:

<template><el-card><div slot="header">转化率统计</div><p>购买转化率: {{ conversionRate }}</p></el-card>
</template><script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';const conversionRate = ref(0);onMounted(() => {axios.get('http://your-server-url/conversion-rate').then(response => {conversionRate.value = response.data;}).catch(error => {console.log(error);});
});
</script>

1.3 用户留存率指标

用户留存率是指在某一时间段内新注册或首次访问的用户,在经过一段时间后仍然继续使用商城的比例。它反映了商城对用户的粘性和吸引力,是衡量商城长期运营健康程度的重要指标。高留存率意味着用户对商城的产品和服务满意,愿意持续使用;低留存率则可能暗示存在用户流失问题,需要分析原因,采取措施提高用户留存。

后端使用 Spring Boot 和 MyBatis-Plus 编写查询用户留存数据的代码,假设我们有用户表user和用户登录记录表user_login,user_login表记录了用户的登录时间等信息。通过以下代码计算不同时间段的用户留存率,这里以次日留存率为例:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;import java.util.Date;@Service
public class UserRetentionServiceImpl extends ServiceImpl<UserRetentionMapper, UserRetention> {public Double calculateNextDayRetentionRate() {// 获取前一天的日期Date yesterday = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000);// 计算前一天新注册用户数QueryWrapper<User> newUserWrapper = new QueryWrapper<>();newUserWrapper.ge("register_time", yesterday);Long newUserCount = baseMapper.selectCount(newUserWrapper);// 计算前一天新注册且在次日登录的用户数QueryWrapper<UserLogin> loginWrapper = new QueryWrapper<>();loginWrapper.select("DISTINCT user_id");loginWrapper.ge("login_time", new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000)).inSql("user_id", "SELECT id FROM user WHERE register_time >= " + yesterday.getTime());Long retainedUserCount = baseMapper.selectMaps(loginWrapper).size();if (newUserCount == 0) {return 0.0;}return (double) retainedUserCount / newUserCount;}
}

对应的 Controller 层代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserRetentionController {@Autowiredprivate UserRetentionServiceImpl userRetentionService;@GetMapping("/next-day-retention-rate")public Double getNextDayRetentionRate() {return userRetentionService.calculateNextDayRetentionRate();}
}

uniapp 前端展示留存率数据示例:

<template><view><text>次日留存率: {{ nextDayRetentionRate }}</text></view>
</template><script>
export default {data() {return {nextDayRetentionRate: 0};},onLoad() {this.fetchNextDayRetentionRate();},methods: {fetchNextDayRetentionRate() {uni.request({url: 'http://your-server-url/next-day-retention-rate',success: (res) => {this.nextDayRetentionRate = res.data;},fail: (error) => {console.log(error);}});}}
};
</script>

Element plus 前端展示留存率数据示例:

<template><el-card><div slot="header">用户留存率统计</div><p>次日留存率: {{ nextDayRetentionRate }}</p></el-card>
</template><script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';const nextDayRetentionRate = ref(0);onMounted(() => {axios.get('http://your-server-url/next-day-retention-rate').then(response => {nextDayRetentionRate.value = response.data;}).catch(error => {console.log(error);});
});
</script>

二、构建指标计算模型

2.1 指标计算方法

  1. GMV 计算方法:GMV 的计算是将所有订单的金额进行累加。在数据库中,订单表order的order_amount字段记录了每个订单的金额,通过 SQL 的SUM函数可以实现对所有订单金额的求和操作。例如:
SELECT SUM(order_amount) as gmv FROM order;

用流程图表示如下:

st=>start: 开始
op1=>operation: 从订单表获取所有订单记录
op2=>operation: 提取每条订单记录的order_amount字段
op3=>operation: 对所有提取的order_amount字段进行求和
e=>end: 返回GMV结果
st->op1->op2->op3->e
  1. 转化率计算方法:购买转化率是下单用户数与访问用户数的比值。需要从用户访问记录表user_visit中统计访问用户数,从订单表order中统计下单用户数。具体步骤如下:
    • 统计访问用户数
SELECT COUNT(*) as visit_count FROM user_visit;
    • 统计下单用户数
SELECT COUNT(DISTINCT user_id) as order_user_count FROM order;
    • 计算转化率:转化率 = 下单用户数 / 访问用户数 。

用伪代码表示计算过程:

visitCount = selectCountFromUserVisit()
orderUserCount = selectDistinctUserIdCountFromOrder()
conversionRate = orderUserCount / visitCount if visitCount != 0 else 0
  1. 用户留存率计算方法:以次日留存率为例,先获取前一天新注册的用户数,再统计这些新注册用户中在次日登录的用户数,最后计算两者的比值。假设用户表user的register_time字段记录了用户注册时间,用户登录记录表user_login的login_time字段记录了用户登录时间,计算步骤如下:
    • 获取前一天的日期
Date yesterday = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000);
    • 统计前一天新注册用户数
SELECT COUNT(*) as new_user_count FROM user WHERE register_time >= {yesterday};
    • 统计前一天新注册且在次日登录的用户数
SELECT COUNT(DISTINCT user_id) as retained_user_count FROM user_login 
WHERE login_time >= {tomorrow} AND user_id IN (SELECT id FROM user WHERE register_time >= {yesterday});
    • 计算次日留存率:次日留存率 = 前一天新注册且在次日登录的用户数 / 前一天新注册用户数 。

用流程图表示如下:

st2=>start: 开始
op4=>operation: 计算前一天日期
op5=>operation: 从用户表统计前一天新注册用户数
op6=>operation: 从用户登录表统计前一天新注册且次日登录用户数
op7=>operation: 计算次日留存率
e2=>end: 返回次日留存率结果
st2->op4->op5->op6->op7->e2

2.2 数据来源确定

  1. 订单表:在指标计算中起着关键作用。对于 GMV 计算,order表的order_amount字段提供了订单金额数据;对于转化率计算,order表的user_id字段用于统计下单用户数。订单表结构设计如下:
CREATE TABLE order (id BIGINT AUTO_INCREMENT PRIMARY KEY,order_no VARCHAR(50) NOT NULL,user_id BIGINT NOT NULL,order_amount DECIMAL(10, 2) NOT NULL,order_status INT DEFAULT 0,create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

字段说明:

  • id:订单唯一标识。
  • order_no:订单编号。
  • user_id:下单用户 ID。
  • order_amount:订单金额。
  • order_status:订单状态。
  • create_time:订单创建时间。
  1. 用户表:对于用户留存率计算,user表的register_time字段用于确定新注册用户。用户表结构设计如下:
CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,password VARCHAR(100) NOT NULL,register_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

字段说明:

  • id:用户唯一标识。
  • username:用户名。
  • password:用户密码。
  • register_time:用户注册时间。
  1. 用户访问记录表:在转化率计算中,user_visit表的记录用于统计访问用户数。用户访问记录表结构设计如下:
CREATE TABLE user_visit (id BIGINT AUTO_INCREMENT PRIMARY KEY,user_id BIGINT NOT NULL,visit_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,visit_page VARCHAR(100)
);

字段说明:

  • id:访问记录唯一标识。
  • user_id:访问用户 ID。
  • visit_time:访问时间。
  • visit_page:访问页面。

通过 MyBatis-Plus 从这些表中获取数据时,利用其强大的查询构造器QueryWrapper,可以方便地构建复杂的查询条件,确保数据获取的准确性和高效性。例如,在获取 GMV 时,使用QueryWrapper构建求和查询:

QueryWrapper<Order> wrapper = new QueryWrapper<>();
wrapper.select("SUM(order_amount) as gmv");
baseMapper.selectMaps(wrapper);

2.3 实现源码展示

  1. Service 层代码:以计算 GMV 为例,在 Spring Boot 的 Service 层实现计算 GMV 的逻辑。
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> {public Double calculateGMV() {// 使用MyBatis - Plus的QueryWrapper构建查询条件QueryWrapper<Order> wrapper = new QueryWrapper<>();wrapper.select("SUM(order_amount) as gmv");// 执行查询并获取结果return baseMapper.selectMaps(wrapper).stream().findFirst().map(map -> (Double) map.get("gmv")).orElse(0.0);}
}

这段代码中,首先创建了一个QueryWrapper对象,通过select方法指定要查询的字段为SUM(order_amount) as gmv,即对order_amount字段求和并别名为gmv。然后通过baseMapper.selectMaps(wrapper)执行查询,返回一个包含查询结果的List<Map<String, Object>>。最后通过流操作获取第一个结果,并提取其中的gmv值,若结果为空则返回 0.0。

  1. Mapper 层代码:由于使用了 MyBatis-Plus,无需手写 Mapper 文件,BaseMapper已经提供了基本的数据库操作方法。在上述 Service 层代码中,baseMapper即为继承自BaseMapper的OrderMapper,它会根据QueryWrapper构建的查询条件自动生成 SQL 语句并执行数据库操作,充分体现了 MyBatis - Plus 无需手写 Mapper 文件的优势 ,大大提高了开发效率,减少了重复代码的编写。例如在计算 GMV 时,baseMapper.selectMaps(wrapper)这一行代码就完成了复杂的数据库查询操作,开发者无需关心具体的 SQL 实现细节。

三、建立指标监控体系

3.1 实时跟踪方案

为了实现对 GMV、转化率、用户留存率等指标的实时跟踪,我们可以采用多种技术方案。其中,Spring Boot 的定时任务注解@Scheduled是一种简单有效的方式。通过在后端服务中使用该注解,可以定时执行指标计算方法,确保数据的实时更新。例如,对于 GMV 指标的定时计算:

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
public class GMVMonitor {private final OrderServiceImpl orderService;public GMVMonitor(OrderServiceImpl orderService) {this.orderService = orderService;}// 每小时计算一次GMV@Scheduled(fixedRate = 60 * 60 * 1000)public void calculateGMVPeriodically() {Double gmv = orderService.calculateGMV();// 可以将计算出的GMV保存到缓存或数据库中,以便前端获取// 例如:redisTemplate.opsForValue().set("currentGMV", gmv);}
}

上述代码中,@Scheduled(fixedRate = 60 * 60 * 1000)表示该方法每小时执行一次,通过调用orderService.calculateGMV()计算 GMV,并可将结果进行后续处理,如保存到缓存中。

另外,集成消息队列如 RabbitMQ 也是一种不错的选择。当订单状态更新、用户访问等事件发生时,发送消息到消息队列,消费者端接收到消息后实时计算相关指标。例如,在订单服务中,当订单创建成功时,发送一条消息到 RabbitMQ:

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderService {@Autowiredprivate RabbitTemplate rabbitTemplate;public void createOrder(Order order) {// 保存订单到数据库等操作//...// 发送订单创建消息到RabbitMQrabbitTemplate.convertAndSend("order-exchange", "order.create", order);}
}

在消费者端,监听该消息并更新 GMV 指标:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;@Service
public class GMVUpdateService extends ServiceImpl<OrderMapper, Order> {@RabbitListener(queues = "order-queue")public void updateGMVOnOrderCreate(Order order) {// 根据新订单更新GMVQueryWrapper<Order> wrapper = new QueryWrapper<>();wrapper.select("SUM(order_amount) as gmv");Double newGMV = baseMapper.selectMaps(wrapper).stream().findFirst().map(map -> (Double) map.get("gmv")).orElse(0.0);// 保存新的GMV等操作//...}
}

通过这种方式,利用消息队列的异步特性,能够及时响应业务事件,保证指标数据的实时性和监控的稳定性。

3.2 趋势展示实现

在 uniapp 和 Element plus 前端,我们可以使用 Echarts 可视化库来展示指标变化趋势。以 GMV 随时间变化的折线图为例,首先在 uniapp 中:

安装 Echarts:npm install echarts --save

在页面中引入并使用 Echarts:

<template><view><view id="gmv-chart" style="width: 100%; height: 400px;"></view></view>
</template><script>
import echarts from 'echarts';export default {data() {return {gmvData: []};},onLoad() {this.fetchGMVData();},methods: {fetchGMVData() {uni.request({url: 'http://your-server-url/gmv-history',success: (res) => {this.gmvData = res.data;this.renderGMVChart();},fail: (error) => {console.log(error);}});},renderGMVChart() {const chart = echarts.init(document.getElementById('gmv-chart'));const option = {title: {text: 'GMV变化趋势'},tooltip: {trigger: 'axis'},xAxis: {type: 'category',data: this.gmvData.map(item => item.time)},yAxis: {type: 'value'},series: [{name: 'GMV',type: 'line',data: this.gmvData.map(item => item.gmv)}]};chart.setOption(option);}}
};
</script>

在 Element plus 中,假设在一个 Vue 组件中:

<template><el-card><div slot="header">GMV变化趋势</div><div id="gmv-chart" style="width: 100%; height: 400px;"></div></el-card>
</template><script setup>
import { onMounted } from 'vue';
import echarts from 'echarts';
import axios from 'axios';const fetchGMVData = async () => {try {const response = await axios.get('http://your-server-url/gmv-history');const gmvData = response.data;const chart = echarts.init(document.getElementById('gmv-chart'));const option = {title: {text: 'GMV变化趋势'},tooltip: {trigger: 'axis'},xAxis: {type: 'category',data: gmvData.map(item => item.time)},yAxis: {type: 'value'},series: [{name: 'GMV',type: 'line',data: gmvData.map(item => item.gmv)}]};chart.setOption(option);} catch (error) {console.log(error);}
};onMounted(() => {fetchGMVData();
});
</script>

上述代码中,通过uni.request(uniapp)或axios(Element plus)从后端获取 GMV 历史数据,然后使用 Echarts 配置折线图,展示 GMV 随时间的变化情况。同样的方式也可用于展示转化率、用户留存率等指标的变化趋势,只需调整数据请求和图表配置即可。

3.3 异常预警机制

当指标超出正常范围时,需要及时通知相关人员。在后端,通过代码判断指标数据,当异常时发送邮件或短信通知。以 GMV 异常预警为例,假设设定 GMV 的正常范围为前一周 GMV 平均值的 ±20%:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class GMVAlarmService extends ServiceImpl<OrderMapper, Order> {@Autowiredprivate JavaMailSender javaMailSender;public void checkGMVAlarm() {// 获取前一周GMV平均值QueryWrapper<Order> wrapper = new QueryWrapper<>();wrapper.select("AVG(order_amount) as avg_gmv");// 假设这里有逻辑计算前一周的时间范围并添加到查询条件中//...Double avgGMV = baseMapper.selectMaps(wrapper).stream().findFirst().map(map -> (Double) map.get("avg_gmv")).orElse(0.0);// 获取当前GMVDouble currentGMV = this.baseMapper.selectMaps(new QueryWrapper<Order>().select("SUM(order_amount) as gmv")).stream().findFirst().map(map -> (Double) map.get("gmv")).orElse(0.0);// 判断是否超出正常范围if (currentGMV < avgGMV * 0.8 || currentGMV > avgGMV * 1.2) {sendGMVAlarmEmail(currentGMV, avgGMV);}}private void sendGMVAlarmEmail(Double currentGMV, Double avgGMV) {SimpleMailMessage message = new SimpleMailMessage();message.setTo("recipient@example.com");message.setSubject("GMV异常预警");message.setText("当前GMV为:" + currentGMV + ",超出正常范围(前一周平均值:" + avgGMV + ")");javaMailSender.send(message);}
}

上述代码中,checkGMVAlarm方法首先计算前一周 GMV 平均值和当前 GMV,然后判断当前 GMV 是否超出正常范围,若超出则调用sendGMVAlarmEmail方法发送邮件通知。

若要使用短信接口集成,以阿里云短信服务为例,首先添加依赖:

<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>最新版本号</version>
</dependency>

配置短信服务参数,在application.properties中:

sms.accessKeyId=your-access-key-id
sms.accessKeySecret=your-access-key-secret
sms.signName=你的短信签名
sms.templateCode=你的短信模板编码

编写短信发送代码:

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;@Service
public class SmsService {@Value("${sms.accessKeyId}")private String accessKeyId;@Value("${sms.accessKeySecret}")private String accessKeySecret;@Value("${sms.signName}")private String signName;@Value("${sms.templateCode}")private String templateCode;public boolean sendSms(String phoneNumber, String message) {DefaultProfile profile = DefaultProfile.getProfile("default", accessKeyId, accessKeySecret);IAcsClient client = new DefaultAcsClient(profile);SendSmsRequest request = new SendSmsRequest();request.setPhoneNumbers(phoneNumber);request.setSignName(signName);request.setTemplateCode(templateCode);request.setTemplateParam("{\"message\":\"" + message + "\"}");try {SendSmsResponse response = client.getAcsResponse(request);return response.getCode().equals("OK");} catch (ClientException e) {e.printStackTrace();}return false;}
}

在GMVAlarmService中调用短信发送服务:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class GMVAlarmService extends ServiceImpl<OrderMapper, Order> {@Autowiredprivate SmsService smsService;public void checkGMVAlarm() {// 计算GMV和判断异常逻辑...if (currentGMV < avgGMV * 0.8 || currentGMV > avgGMV * 1.2) {String message = "当前GMV为:" + currentGMV + ",超出正常范围(前一周平均值:" + avgGMV + ")";smsService.sendSms("13800138000", message);}}
}

这样,当 GMV 指标异常时,就可以通过邮件或短信及时通知相关人员,以便采取相应措施。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/74759.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

seatunnel配置mysql2hive

SeaTunnel安装教程 # 执行流程 # 下载&#xff0c;解压 # https://mirrors.aliyun.com/apache/seatunnel/2.3.8/?spma2c6h.25603864.0.0.2e2d3f665eBj1E # https://blog.csdn.net/taogumo/article/details/143608532 tar -zxvf apache-seatunnel-2.3.8-bin.tar.gz -C /opt/mo…

SSH项目负载均衡中的Session一致性解决方案‌

SSH项目负载均衡中的Session一致性解决方案‌ 1. 粘性会话&#xff08;Session Sticky&#xff09;‌2. Session复制&#xff08;集群同步&#xff09;‌3. 集中式Session存储‌4. 客户端存储&#xff08;Cookie加密&#xff09;‌方案选型建议‌注意事项‌ 1. 粘性会话&#x…

MySQL 表连接(内连接与外连接)

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 1、表连接的核心概念 1.1 为什么需要表连接&#xff1f; 2、内连接&a…

解锁Spring Boot异步编程:让你的应用“飞“起来!

引言&#xff1a;从点餐说起 &#x1f354; 想象你在快餐店点餐&#xff1a; 同步模式&#xff1a;排队等餐&#xff0c;队伍越来越长&#xff08;就像卡死的服务器&#xff09;异步模式&#xff1a;拿号后去旁边坐着等&#xff08;服务员喊号通知你&#xff09; 今天我们就…

做一个有天有地的css及html画的旋转阴阳鱼

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>天地阴阳</title><style>/* 重置默认样…

ngx_http_core_main_conf_t

定义在 src\http\ngx_http_core_module.h typedef struct {ngx_array_t servers; /* ngx_http_core_srv_conf_t */ngx_http_phase_engine_t phase_engine;ngx_hash_t headers_in_hash;ngx_hash_t variables_hash;…

计算机二级(C语言)考试高频考点总汇(二)—— 控制流、函数、数组和指针

目录 六、控制流 七、函数 八、数组和指针 六、控制流 76. if 语句可以&#xff08;嵌套&#xff09;&#xff0c; if 语句可以嵌套在另一个 if 语句内部&#xff0c;形成&#xff08;嵌套的条件判断结构&#xff09;&#xff0c;用于处理更复杂的条件判断逻辑。 77. els…

WebRTC协议全面教程:原理、应用与优化指南

一、WebRTC协议概述 **WebRTC&#xff08;Web Real-Time Communication&#xff09;**是一种开源的实时通信协议&#xff0c;支持浏览器和移动应用直接进行音频、视频及数据传输&#xff0c;无需插件或第三方软件。其核心特性包括&#xff1a; P2P传输&#xff1a;点对点直连…

使用 WSL + Ubuntu + Go + GoLand(VSCode) 开发环境配置指南

1. 安装和配置 WSL 与 Ubuntu 启用 WSL 功能(以管理员身份运行 PowerShell): wsl --install 或手动启用: dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachi…

element-plus中,Tour 漫游式引导组件的使用

目录 一.Tour 漫游式引导组件的简单介绍 1.作用 2.基本使用 3.展示效果 二.实战1&#xff1a;介绍患者病历表单 1.要求 2.实现步骤 3.展示效果 结语 一.Tour 漫游式引导组件的简单介绍 1.作用 快速了解一个功能/产品。 2.基本使用 从官网复制如下代码&#xff1a; &…

39-Ajax工作原理

1. 简明定义开场 “AJAX(Asynchronous JavaScript and XML)是一种允许网页在不重新加载整个页面的情况下&#xff0c;与服务器交换数据并更新部分网页内容的技术。它通过JavaScript的XMLHttpRequest对象或现代的Fetch API实现异步通信。” 2. 核心工作原理 "AJAX的工作…

Python 爬虫案例

以下是一些常见的 Python 爬虫案例&#xff0c;涵盖了不同的应用场景和技术点&#xff1a; 1. 简单网页内容爬取 案例&#xff1a;爬取网页标题和简介 import requests from bs4 import BeautifulSoup url "https://www.runoob.com/" response requests.get(url) …

【C++进阶】函数:深度解析 C++ 函数的 12 大进化特性

目录 一、函数基础 1.1 函数定义与声明 1.2 函数调用 1.3 引用参数 二、函数重载&#xff1a;同名函数的「多态魔法」&#xff08;C 特有&#xff09; 2.1 基础实现 2.2 重载决议流程图 2.3 与 C 语言的本质区别 2.4 实战陷阱 三、默认参数&#xff1a;接口的「弹性设…

Redis的基础,经典,高级问题解答篇

目录 一&#xff0c;基础 二&#xff0c;经典 缓存雪崩&#xff1a; 1. Redis事务的原子性 2. 与MySQL事务的区别 1. 主从复制原理 2. 哨兵模式故障转移流程 3. 客户端感知故障转移 三&#xff0c;高级 一&#xff0c;基础 Redis的5种基础数据类型及使用场景&#xf…

【蓝桥杯】好数

好数 问题描述代码解释代码 好数 问题描述 一个整数如果按从低位到高位的顺序&#xff0c;奇数位 (个位、百位、万位 ⋯ ) 上的数字是奇数&#xff0c;偶数位 (十位、千位、十万位 ⋯ ) 上的数字是偶数&#xff0c;我们就称之为 “好数”。 给定一个正整数 N&#xff0c;请计算…

利用 Patroni + etcd + HAProxy 搭建高可用 PostgreSQL 集群

在生产环境中&#xff0c;数据库的高可用性是系统稳定运行的关键。本文将详细讲解如何利用 Docker 部署一个由 etcd、Patroni 和 HAProxy 组成的 PostgreSQL 高可用集群&#xff0c;实现自动故障转移和负载均衡。 架构概述 本架构主要包括三部分&#xff1a; etcd 集群 etcd …

bash 和 pip 是两种完全不同用途的命令,分别用于[系统终端操作]和[Python 包管理]

bash 和 pip 是两种完全不同用途的命令&#xff0c;分别用于 系统终端操作 和 Python 包管理。以下是它们的核心区别、用法及常见场景对比&#xff1a; 1. 本质区别 特性bashpip类型Shell 命令解释器&#xff08;一种脚本语言&#xff09;Python 包管理工具作用执行系统命令、…

分布式系统的CAP理论、事务和锁实现

分布式系统核心概念 1. CAP理论 CAP理论指出&#xff0c;分布式系统最多同时满足以下三项中的两项&#xff1a; 一致性&#xff08;CC&#xff09;&#xff1a;所有节点访问同一份最新数据。可用性&#xff08;AA&#xff09;&#xff1a;每个请求都能在合理时间内获得非错误…

鸿蒙UI开发

鸿蒙UI开发 本文旨在分享一些鸿蒙UI布局开发上的一些建议&#xff0c;特别是对屏幕宽高比发生变化时的应对思路和好的实践。 折叠屏适配 一般情况&#xff08;自适应布局/响应式布局&#xff09; 1.自适应布局 1.1自适应拉伸 左右组件定宽 TypeScript //左右定宽 Row() { …

FreeRTOS 五种内存管理算法深度对比分析

FreeRTOS 提供了五种动态内存管理算法&#xff08;heap_1 至 heap_5&#xff09;&#xff0c;针对不同应用场景在实时性、内存效率、碎片控制等方面进行了差异化设计。以下从实现原理、性能指标及适用场景进行全面对比&#xff1a; 一、Heap_1&#xff1a;静态分配优先 ​核心…