news 2026/4/6 13:10:39

外卖系统开发实战:订单与配送系统详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
外卖系统开发实战:订单与配送系统详解

本文将从实践角度出发,通过具体的代码示例,深入讲解外卖平台核心功能的实现。光合同城作为专业的外卖系统开发商,将分享在实际项目中的技术实践和经验总结。

一:外卖系统开发环境搭建

1.1 技术栈选择

光合同城推荐以下技术栈用于外卖系统开发:

后端技术栈

  • MySQL + Redis + Elasticsearch

  • RabbitMQ消息队列

  • Nginx网关

  • Docker容器化

前端技术栈

  • 用户端:Uni-app跨平台框架

  • 商家/骑手端:Vue.js + Element UI

  • 管理后台:React + Ant Design

移动端

  • Android:Kotlin + Jetpack

  • iOS:Swift + SwiftUI

1.2 服务项目结构

food-delivery-platform/
├── food-delivery-gateway/ # API网关
├── food-delivery-auth/ # 认证授权中心
├── food-delivery-user/ # 用户服务
├── food-delivery-merchant/ # 商家服务
├── food-delivery-product/ # 商品服务
├── food-delivery-order/ # 订单服务
├── food-delivery-payment/ # 支付服务
├── food-delivery-delivery/ # 配送服务
├── food-delivery-message/ # 消息服务
└── food-delivery-monitor/ # 监控服务

二:订单系统的核心实现

2.1 订单状态机设计

订单状态流转是外卖系统的核心逻辑。光合同城设计的状态机确保订单状态变更的准确性和一致性。

订单状态枚举

public enum OrderStatus {
// 待支付(用户提交订单后)
WAITING_PAYMENT(1, "待支付"),

// 已支付(用户支付成功后)
PAID(2, "已支付"),

// 商家已接单
MERCHANT_CONFIRMED(3, "商家已接单"),

// 商家拒单
MERCHANT_REJECTED(4, "商家拒单"),

// 制作中
PREPARING(5, "制作中"),

// 制作完成
PREPARED(6, "制作完成"),

// 骑手已接单
RIDER_ACCEPTED(7, "骑手已接单"),

// 骑手已取餐
PICKED_UP(8, "骑手已取餐"),

// 配送中
DELIVERING(9, "配送中"),

// 已送达
DELIVERED(10, "已送达"),

// 已完成(用户确认收货)
COMPLETED(11, "已完成"),

// 已取消
CANCELLED(12, "已取消"),

// 售后中
AFTER_SALE(13, "售后中"),

// 已退款
REFUNDED(14, "已退款");

private final int code;
private final String description;

OrderStatus(int code, String description) {
this.code = code;
this.description = description;
}

// 状态流转校验
public boolean canTransferTo(OrderStatus targetStatus) {
Map<OrderStatus, List<OrderStatus>> allowedTransfers = Map.of(
WAITING_PAYMENT, Arrays.asList(PAID, CANCELLED),
PAID, Arrays.asList(MERCHANT_CONFIRMED, MERCHANT_REJECTED, REFUNDED),
MERCHANT_CONFIRMED, Arrays.asList(PREPARING, CANCELLED),
PREPARING, Arrays.asList(PREPARED, CANCELLED),
PREPARED, Arrays.asList(RIDER_ACCEPTED, CANCELLED),
RIDER_ACCEPTED, Arrays.asList(PICKED_UP, CANCELLED),
PICKED_UP, Arrays.asList(DELIVERING, CANCELLED),
DELIVERING, Arrays.asList(DELIVERED),
DELIVERED, Arrays.asList(COMPLETED, AFTER_SALE),
AFTER_SALE, Arrays.asList(REFUNDED, COMPLETED)
);

return allowedTransfers.getOrDefault(this, Collections.emptyList())
.contains(targetStatus);
}
}

2.2 订单创建服务实现

订单创建涉及多个服务的协同工作,需要保证数据一致性。光合同城采用分布式事务解决方案。

订单创建核心代码示例

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

@Autowired
private ProductService productService;

@Autowired
private InventoryService inventoryService;

@Autowired
private PaymentService paymentService;

@Autowired
private MessageService messageService;

@Autowired
private RocketMQTemplate rocketMQTemplate;

@Override
@Transactional(rollbackFor = Exception.class)
public OrderCreateResponse createOrder(OrderCreateRequest request) {
// 1. 参数校验
validateOrderRequest(request);

// 2. 验证商品和库存
List<ProductDTO> products = validateProductsAndInventory(request.getItems());

// 3. 计算订单金额
OrderAmountDTO amount = calculateOrderAmount(request, products);

// 4. 创建订单记录(初始状态为待支付)
OrderDTO order = saveOrder(request, products, amount);

try {
// 5. 预扣库存(防止超卖)
inventoryService.preDeductInventory(request.getItems());

// 6. 发送订单创建消息到MQ
OrderCreatedEvent event = new OrderCreatedEvent();
event.setOrderId(order.getOrderId());
event.setUserId(order.getUserId());
event.setAmount(order.getTotalAmount());
rocketMQTemplate.send("order-topic",
MessageBuilder.withPayload(event).build());

// 7. 创建支付预订单
PaymentPreOrderDTO paymentOrder = paymentService.createPreOrder(
order.getOrderId(),
order.getTotalAmount(),
"外卖订单支付"
);

// 8. 返回结果
return OrderCreateResponse.builder()
.orderId(order.getOrderId())
.orderNo(order.getOrderNo())
.status(order.getStatus())
.payAmount(order.getTotalAmount())
.paymentInfo(paymentOrder)
.expireTime(LocalDateTime.now().plusMinutes(15))
.build();

} catch (Exception e) {
log.error("创建订单失败", e);
// 发送订单创建失败消息,触发补偿操作
rocketMQTemplate.send("order-compensate-topic",
MessageBuilder.withPayload(order.getOrderId()).build());
throw new BusinessException("订单创建失败,请重试");
}
}

/**
* 计算订单金额
*/
private OrderAmountDTO calculateOrderAmount(OrderCreateRequest request,
List<ProductDTO> products) {
BigDecimal productAmount = BigDecimal.ZERO;
Map<Long, ProductDTO> productMap = products.stream()
.collect(Collectors.toMap(ProductDTO::getProductId, p -> p));

// 计算商品总价
for (OrderItemRequest item : request.getItems()) {
ProductDTO product = productMap.get(item.getProductId());
BigDecimal itemTotal = product.getPrice()
.multiply(new BigDecimal(item.getQuantity()));
productAmount = productAmount.add(itemTotal);
}

// 配送费计算
BigDecimal deliveryFee = calculateDeliveryFee(
request.getDeliveryAddress(),
request.getMerchantId()
);

// 包装费
BigDecimal packageFee = calculatePackageFee(request.getItems());

// 优惠券抵扣
BigDecimal couponDiscount = calculateCouponDiscount(
request.getCouponId(),
productAmount
);

// 会员折扣
BigDecimal memberDiscount = calculateMemberDiscount(
request.getUserId(),
productAmount
);

// 订单总金额
BigDecimal totalAmount = productAmount
.add(deliveryFee)
.add(packageFee)
.subtract(couponDiscount)
.subtract(memberDiscount);

// 确保金额不小于0
totalAmount = totalAmount.max(BigDecimal.ZERO);

return OrderAmountDTO.builder()
.productAmount(productAmount)
.deliveryFee(deliveryFee)
.packageFee(packageFee)
.couponDiscount(couponDiscount)
.memberDiscount(memberDiscount)
.totalAmount(totalAmount)
.build();
}

/**
* 保存订单到数据库
*/
private OrderDTO saveOrder(OrderCreateRequest request,
List<ProductDTO> products,
OrderAmountDTO amount) {
Order order = new Order();
order.setOrderNo(generateOrderNo());
order.setUserId(request.getUserId());
order.setMerchantId(request.getMerchantId());
order.setStatus(OrderStatus.WAITING_PAYMENT.getCode());
order.setProductAmount(amount.getProductAmount());
order.setDeliveryFee(amount.getDeliveryFee());
order.setPackageFee(amount.getPackageFee());
order.setDiscountAmount(amount.getCouponDiscount()
.add(amount.getMemberDiscount()));
order.setTotalAmount(amount.getTotalAmount());
order.setDeliveryAddress(request.getDeliveryAddress());
order.setExpectDeliveryTime(request.getExpectDeliveryTime());
order.setRemark(request.getRemark());

// 保存订单主表
orderMapper.insert(order);

// 保存订单商品明细
List<OrderItem> orderItems = new ArrayList<>();
Map<Long, ProductDTO> productMap = products.stream()
.collect(Collectors.toMap(ProductDTO::getProductId, p -> p));

for (OrderItemRequest itemRequest : request.getItems()) {
ProductDTO product = productMap.get(itemRequest.getProductId());
OrderItem orderItem = new OrderItem();
orderItem.setOrderId(order.getId());
orderItem.setProductId(itemRequest.getProductId());
orderItem.setProductName(product.getName());
orderItem.setProductImage(product.getMainImage());
orderItem.setQuantity(itemRequest.getQuantity());
orderItem.setPrice(product.getPrice());
orderItem.setTotalPrice(product.getPrice()
.multiply(new BigDecimal(itemRequest.getQuantity())));
orderItems.add(orderItem);
}

orderItemMapper.batchInsert(orderItems);

// 记录订单状态变更日志
OrderStatusLog statusLog = new OrderStatusLog();
statusLog.setOrderId(order.getId());
statusLog.setFromStatus(0);
statusLog.setToStatus(order.getStatus());
statusLog.setRemark("订单创建");
orderStatusLogMapper.insert(statusLog);

return convertToDTO(order, orderItems);
}

// 其他辅助方法省略...
}

三:智能配送系统实现

3.1 骑手调度算法

智能调度是提高配送效率的关键。光合同城开发的调度算法综合考虑多种因素。

骑手匹配算法代码示例

class RiderDispatchSystem:
def __init__(self):
self.rider_pool = RiderPool()
self.order_queue = OrderQueue()
self.map_service = MapService()

def dispatch_order(self, order):
"""
智能分配骑手
"""
# 获取可用骑手列表
available_riders = self.rider_pool.get_available_riders(
order.merchant_location,
order.expected_delivery_time
)

if not available_riders:
return self.handle_no_rider_available(order)

# 为每个骑手计算匹配分数
rider_scores = []
for rider in available_riders:
score = self.calculate_rider_score(rider, order)
rider_scores.append((rider, score))

# 按分数排序,选择最优骑手
rider_scores.sort(key=lambda x: x[1], reverse=True)
best_rider = rider_scores[0][0]

# 分配订单给骑手
assignment_result = self.assign_order_to_rider(best_rider, order)

# 更新骑手状态
self.update_rider_status(best_rider, order)

# 发送推送通知
self.send_notification(best_rider, order)

return assignment_result

def calculate_rider_score(self, rider, order):
"""
计算骑手匹配分数
分数越高表示匹配度越好
"""
score = 100.0 # 基础分数

# 1. 距离因素(40%权重)
distance = self.map_service.calculate_distance(
rider.current_location,
order.merchant_location
)
distance_score = self.calculate_distance_score(distance)
score += distance_score * 0.4

# 2. 骑手评级(20%权重)
rating_score = rider.rating * 20 # rating是0-5的评分
score += rating_score * 0.2

# 3. 骑手负载(15%权重)
load_score = self.calculate_load_score(rider.current_load)
score += load_score * 0.15

# 4. 历史表现(15%权重)
performance_score = self.calculate_performance_score(rider)
score += performance_score * 0.15

# 5. 特殊技能(10%权重)
# 如:熟悉某区域、能处理特殊订单等
skill_score = self.calculate_skill_score(rider, order)
score += skill_score * 0.1

# 惩罚项
penalties = self.calculate_penalties(rider, order)
score -= penalties

return max(score, 0) # 确保分数不为负

def calculate_distance_score(self, distance_km):
"""
根据距离计算分数,距离越近分数越高
"""
if distance_km <= 1:
return 100
elif distance_km <= 3:
return 80
elif distance_km <= 5:
return 60
elif distance_km <= 8:
return 40
elif distance_km <= 10:
return 20
else:
return 0

def calculate_load_score(self, current_load):
"""
计算骑手负载分数
当前订单数越少,分数越高
"""
if current_load == 0:
return 100
elif current_load == 1:
return 80
elif current_load == 2:
return 60
elif current_load == 3:
return 40
elif current_load == 4:
return 20
else:
return 0 # 超过4单不再分配新订单

def calculate_performance_score(self, rider):
"""
计算骑手历史表现分数
基于准时率、投诉率等指标
"""
performance_score = 0

# 准时率(0-100分)
if rider.on_time_rate >= 0.98:
performance_score += 40
elif rider.on_time_rate >= 0.95:
performance_score += 30
elif rider.on_time_rate >= 0.90:
performance_score += 20
elif rider.on_time_rate >= 0.85:
performance_score += 10

# 投诉率(负向指标)
complaint_rate = rider.complaint_count / max(rider.total_orders, 1)
if complaint_rate <= 0.01:
performance_score += 30
elif complaint_rate <= 0.03:
performance_score += 20
elif complaint_rate <= 0.05:
performance_score += 10

# 平均评分
performance_score += rider.avg_rating * 10

return min(performance_score, 100)

def calculate_skill_score(self, rider, order):
"""
计算骑手技能匹配分数
"""
skill_score = 0

# 区域熟悉度
if order.delivery_area in rider.familiar_areas:
skill_score += 30

# 订单类型匹配
if order.order_type == "large" and "can_handle_large_order" in rider.skills:
skill_score += 20

# 特殊时段
if order.is_peak_hour and "peak_hour_experience" in rider.skills:
skill_score += 20

# 天气适应性
if order.bad_weather and "bad_weather_delivery" in rider.skills:
skill_score += 30

return min(skill_score, 100)

def calculate_penalties(self, rider, order):
"""
计算惩罚项
"""
penalties = 0

# 近期拒单惩罚
penalties += rider.recent_rejection_count * 10

# 超时取餐历史
if rider.avg_pickup_delay_minutes > 10:
penalties += 20
elif rider.avg_pickup_delay_minutes > 5:
penalties += 10

# 当前位置到商户的预估时间
eta_to_merchant = self.map_service.estimate_eta(
rider.current_location,
order.merchant_location
)

# 如果预计到达时间超过15分钟,增加惩罚
if eta_to_merchant > 15:
penalties += (eta_to_merchant - 15) * 2

return penalties

def batch_dispatch_optimization(self, orders, riders):
"""
批量订单分配优化
使用匈牙利算法解决指派问题
"""
n = len(orders)
m = len(riders)

# 构建成本矩阵
cost_matrix = np.zeros((n, m))
for i, order in enumerate(orders):
for j, rider in enumerate(riders):
score = self.calculate_rider_score(rider, order)
# 将分数转换为成本(分数越高,成本越低)
cost_matrix[i][j] = 1000 - score

# 使用匈牙利算法找到最小成本分配
row_ind, col_ind = linear_sum_assignment(cost_matrix)

# 构建分配结果
assignments = []
total_cost = 0

for i, j in zip(row_ind, col_ind):
if i < n and j < m:
assignment = {
'order_id': orders[i].order_id,
'rider_id': riders[j].rider_id,
'cost': cost_matrix[i][j],
'score': 1000 - cost_matrix[i][j]
}
assignments.append(assignment)
total_cost += cost_matrix[i][j]

# 过滤掉分数过低的分配
valid_assignments = [
a for a in assignments
if a['score'] >= self.min_dispatch_score
]

return {
'assignments': valid_assignments,
'total_cost': total_cost,
'assignment_rate': len(valid_assignments) / len(orders) * 100
}

def real_time_reassignment(self, rider_id, reason):
"""
实时重新分配订单
当骑手出现意外情况时调用
"""
# 获取骑手的当前订单
current_orders = self.rider_pool.get_rider_orders(rider_id)

reassignment_results = []
for order in current_orders:
# 如果订单还没有取餐,可以重新分配
if order.status in ['waiting_rider', 'rider_assigned']:
# 取消原有分配
self.cancel_assignment(order.order_id, rider_id, reason)

# 重新分配
result = self.dispatch_order(order)
reassignment_results.append({
'order_id': order.order_id,
'original_rider': rider_id,
'new_rider': result['rider_id'] if result else None,
'success': result is not None
})

return reassignment_results

3.2 实时路径规划与ETA计算

光合同城的路径规划系统不仅考虑最短路径,还综合考虑实时路况、交通规则、天气等因素。

@Service
public class RoutePlanningService {

@Autowired
private MapService mapService;

@Autowired
private TrafficService trafficService;

@Autowired
private WeatherService weatherService;

/**
* 计算最优配送路径
*/
public RoutePlan calculateOptimalRoute(RouteRequest request) {
List<DeliveryPoint> deliveryPoints = request.getDeliveryPoints();
Point startPoint = request.getStartPoint();

// 获取实时路况
TrafficInfo trafficInfo = trafficService.getRealTimeTraffic(
startPoint, deliveryPoints);

// 获取天气信息
WeatherInfo weatherInfo = weatherService.getCurrentWeather(
request.getCityCode());

// 构建路径规划图
RouteGraph graph = buildRouteGraph(deliveryPoints, trafficInfo);

// 使用改进的Dijkstra算法计算最优路径
RoutePlan optimalRoute = findOptimalRoute(graph, startPoint);

// 考虑天气因素调整ETA
adjustETAForWeather(optimalRoute, weatherInfo);

// 考虑骑手习惯和能力调整
adjustForRiderPreference(optimalRoute, request.getRiderId());

return optimalRoute;
}

/**
* 多目标优化路径规划
* 考虑:距离最短、时间最少、成本最低等多个目标
*/
public List<RoutePlan> multiObjectiveRoutePlanning(
RouteRequest request,
OptimizationCriteria criteria) {

// 生成多个候选路径
List<RoutePlan> candidateRoutes = generateCandidateRoutes(request);

// 多目标评分
Map<RoutePlan, MultiObjectiveScore> scores = new HashMap<>();
for (RoutePlan route : candidateRoutes) {
MultiObjectiveScore score = evaluateRoute(route, criteria);
scores.put(route, score);
}

// Pareto最优解筛选
List<RoutePlan> paretoOptimal = findParetoOptimal(scores);

// 根据偏好选择最终路径
return selectFinalRoute(paretoOptimal, request.getPreference());
}
}

四:系统性能优化实践

4.1 数据库查询优化

索引优化策略

-- 订单表复合索引设计
CREATE INDEX idx_order_user_status ON orders(user_id, status, create_time);
CREATE INDEX idx_order_merchant_time ON orders(merchant_id, create_time);
CREATE INDEX idx_order_rider_status ON orders(rider_id, status);

-- 使用覆盖索引减少回表
CREATE INDEX idx_order_query ON orders(
user_id,
status,
create_time DESC
) INCLUDE (total_amount, merchant_id, rider_id);

4.2 缓存策略实现

@Service
@Slf4j
public class OrderCacheService {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

private static final String ORDER_CACHE_PREFIX = "order:";
private static final String USER_ORDERS_PREFIX = "user_orders:";
private static final long ORDER_CACHE_TTL = 30 * 60; // 30分钟

/**
* 多级缓存获取订单信息
*/
public OrderDTO getOrderWithCache(String orderId) {
// 1. 先查本地缓存(Caffeine)
OrderDTO order = localCache.getIfPresent(orderId);
if (order != null) {
return order;
}

// 2. 查Redis分布式缓存
String cacheKey = ORDER_CACHE_PREFIX + orderId;
order = (OrderDTO) redisTemplate.opsForValue().get(cacheKey);
if (order != null) {
// 回填本地缓存
localCache.put(orderId, order);
return order;
}

// 3. 查数据库
order = orderMapper.selectById(orderId);
if (order != null) {
// 异步更新缓存
CompletableFuture.runAsync(() -> {
updateOrderCache(order);
});
}

return order;
}

/**
* 用户订单列表缓存
*/
public List<OrderDTO> getUserOrdersWithCache(Long userId,
OrderStatus status,
int page,
int size) {
String cacheKey = String.format("%s:%d:%s:%d:%d",
USER_ORDERS_PREFIX, userId, status, page, size);

// 尝试从缓存获取
List<OrderDTO> orders = (List<OrderDTO>)
redisTemplate.opsForValue().get(cacheKey);

if (orders == null) {
// 缓存未命中,查询数据库
orders = orderMapper.selectUserOrders(userId, status, page, size);

// 异步更新缓存(设置较短TTL,因为订单状态可能变化)
CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(
cacheKey,
orders,
5,
TimeUnit.MINUTES
);
});
}

return orders;
}
}

五:安全与监控

5.1 支付安全实现

@Component
public class PaymentSecurityService {

/**
* 支付参数签名验证
*/
public boolean verifyPaymentSignature(PaymentRequest request) {
String sign = request.getSign();
Map<String, String> params = new TreeMap<>();

// 获取所有待签名参数
params.put("order_id", request.getOrderId());
params.put("amount", request.getAmount().toString());
params.put("timestamp", request.getTimestamp());
params.put("nonce_str", request.getNonceStr());

// 生成签名字符串
StringBuilder signStr = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
signStr.append(entry.getKey()).append("=")
.append(entry.getValue()).append("&");
}
signStr.append("key=").append(apiKey);

// 计算签名
String calculatedSign = DigestUtils.md5Hex(signStr.toString())
.toUpperCase();

return calculatedSign.equals(sign);
}

/**
* 防重放攻击
*/
public boolean checkReplayAttack(String timestamp, String nonceStr) {
// 检查时间戳是否在合理范围内
long requestTime = Long.parseLong(timestamp);
long currentTime = System.currentTimeMillis() / 1000;

if (Math.abs(currentTime - requestTime) > 300) { // 5分钟
return false;
}

// 检查nonce是否已使用过
String nonceKey = "payment_nonce:" + nonceStr;
Boolean used = redisTemplate.opsForValue()
.get(nonceKey) != null;

if (used) {
return false;
}

// 记录已使用的nonce,有效期10分钟
redisTemplate.opsForValue()
.set(nonceKey, "1", 10, TimeUnit.MINUTES);

return true;
}
}

结语:

外卖系统的开发不仅是技术实现,更是对业务理解的深度考验。光合同城通过多年的项目实践,总结出一套成熟的外卖平台解决方案。未来,随着5G、物联网、人工智能等技术的发展,外卖系统将更加智能化、个性化。开发者需要持续学习新技术,深入理解业务需求,才能在竞争激烈的市场中脱颖而出。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/28 6:03:58

基于51单片机智能扫地吸尘小车红外避障机器人风扇吸尘设计+蓝牙app控制设计(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

18-718、STM32恒温电烙铁设计-热电偶-LCD1602-RELAY-KEY(设计源文件万字报告讲解)&#xff08;支持资料、图片参考_相关定制&#xff09;_文章底部可以扫码产品功能描述&#xff1a; 本设计由STM32F103C8T6单片机核心板电路热电偶模块电路LCD1602液晶显示电路按键电路继电器电路…

作者头像 李华
网站建设 2026/4/2 18:55:28

视频超分辨率如何提升跨视角行人识别?让监控画面“看清”每一个人

在城市的天空与地面之间&#xff0c;无数摄像头正默默记录着行人的轨迹。但你是否想过&#xff0c;当一个模糊的身影从无人机画面中掠过&#xff0c;我们如何在地面监控中准确找到同一个人&#xff1f;这正是跨视角行人重识别技术的核心挑战。最近&#xff0c;一项名为S3-CLIP的…

作者头像 李华
网站建设 2026/4/1 6:04:53

实用指南:构建工业AI原生企业的关键步骤与成功案例

制造业正站在一个新的十字路口。当我们谈论工业AI原生企业时&#xff0c;实际上是在讨论一种全新的生产范式。它不再局限于传统的单点智能应用&#xff0c;而是将AI深度嵌入企业价值链的每个环节&#xff0c;形成一个自我进化、持续优化的智能生态系统。从技术工具到运营基础设…

作者头像 李华
网站建设 2026/3/31 13:46:49

小程序计算机毕设之基于nodejs+微信小程序的垃圾分类助手系统垃圾分类和回收系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/3/17 6:07:13

护士资格考试照片怎么压缩?报名照片尺寸及要求

护士资格考试报名时&#xff0c;不少人会卡在照片上传这一关&#xff1a;要么照片太大超出系统限制&#xff0c;要么尺寸、格式不符合要求&#xff0c;试了好几种方法要么压缩后模糊&#xff0c;要么还是通不过审核&#xff0c;选工具又怕麻烦还担心收费。根据官方要求&#xf…

作者头像 李华
网站建设 2026/3/25 12:23:20

【53页PPT】一网通办大数据平台设计方案:总体架构、数据架构、功能架构、权限架构、核心子系统与功能、实施与运营

这是一个市级政务大数据平台设计方案&#xff0c;旨在构建“聚、管、通、用、安”五位一体的数据能力体系。通过统一数据湖与数据库归集治理多源政务数据&#xff0c;建设数据资产管理、共享开放、安全管控与专题应用等子系统&#xff0c;打破部门壁垒&#xff0c;赋能城市精准…

作者头像 李华