外卖点餐连锁店餐饮生鲜奶茶外卖店内扫码点餐源码同城外卖校园外卖源码的扫码逻辑

news2026/5/15 7:48:06
扫码点餐系统 - 完整扫码逻辑 源码示例外卖点餐 | 连锁店 | 餐饮生鲜 | 奶茶 | 店内扫码点餐 | 同城外卖 | 校园外卖 扫码业务场景总览场景扫码后行为核心逻辑️ 店内扫码点餐进入店铺菜单页识别店铺ID → 加载菜单 外卖下单进入外卖店铺页识别店铺位置 → 计算配送费 营销活动领券/红包页识别活动ID → 发放优惠券 员工登录员工管理后台识别员工ID → 权限验证 自取码取餐码页面识别订单ID → 显示取餐码 一、后端扫码逻辑 (Java Spring Boot)1️⃣ 扫码码生成规则java/** * 二维码内容格式: * 店内点餐: CAMPUS://SHOP?id1001tableA05 * 外卖下单: CAMPUS://DELIVERY?shopId1001address宿舍3号楼 * 营销活动: CAMPUS://COUPON?id2001type1 * 取餐码: CAMPUS://PICKUP?orderNoTX20240101001 */ Service public class QRCodeService { Autowired private ShopMapper shopMapper; /** * 生成店内点餐二维码 */ public String generateShopQRCode(Long shopId, String tableNo) { // 格式: CAMPUS://SHOP?id1001tableA05 String content String.format(CAMPUS://SHOP?id%dtable%s, shopId, tableNo); // 使用ZXing生成二维码图片(Base64) return QRCodeUtil.generateBase64(content, 300, 300); } /** * 生成外卖店铺二维码 */ public String generateDeliveryQRCode(Long shopId, String address) { String content String.format(CAMPUS://DELIVERY?shopId%daddress%s, shopId, URLEncoder.encode(address, StandardCharsets.UTF_8)); return QRCodeUtil.generateBase64(content, 300, 300); } /** * 生成营销活动二维码 */ public String generateCouponQRCode(Long activityId, Integer type) { String content String.format(CAMPUS://COUPON?id%dtype%d, activityId, type); return QRCodeUtil.generateBase64(content, 300, 300); } /** * 生成取餐码二维码 */ public String generatePickupQRCode(String orderNo) { String content String.format(CAMPUS://PICKUP?orderNo%s, orderNo); return QRCodeUtil.generateBase64(content, 300, 300); } }2️⃣ 扫码解析Controller ⭐⭐⭐javaRestController RequestMapping(/api/scan) CrossOrigin public class ScanController { Autowired private ShopService shopService; Autowired private CouponService couponService; Autowired private OrderService orderService; /** * 核心扫码后统一入口 * 前端传入: ?codeCAMPUS://SHOP?id1001tableA05 */ GetMapping(/parse) public Result? parseQRCode(RequestParam String code) { log.info(扫码内容: {}, code); // 1. 解析协议头 if (!code.startsWith(CAMPUS://)) { return Result.error(无效的二维码); } String path code.substring(11); // 去掉 CAMPUS:// String[] parts path.split(\\?); String type parts[0]; // SHOP / DELIVERY / COUPON / PICKUP switch (type) { case SHOP: return parseShopQRCode(parts[1]); case DELIVERY: return parseDeliveryQRCode(parts[1]); case COUPON: return parseCouponQRCode(parts[1]); case PICKUP: return parsePickupQRCode(parts[1]); default: return Result.error(未知的二维码类型); } } /** * ️ 店内点餐二维码解析 */ private Result? parseShopQRCode(String params) { MapString, String paramMap parseParams(params); Long shopId Long.parseLong(paramMap.get(id)); String tableNo paramMap.get(table); // 1. 查询店铺信息 Shop shop shopService.getById(shopId); if (shop null) { return Result.error(店铺不存在); } // 2. 查询店铺菜单 ListMenuItem menuList shopService.getMenuByShopId(shopId); // 3. 查询桌台信息(可选) TableInfo table null; if (StringUtils.isNotBlank(tableNo)) { table tableService.getByTableNo(shopId, tableNo); } // 4. 返回前端所需数据 MapString, Object data new HashMap(); data.put(shop, shop); data.put(menu, menuList); data.put(table, table); data.put(scanTime, LocalDateTime.now()); // 记录扫码时间(用于统计) // 5. 记录扫码日志(用于数据分析) scanLogService.save(shopId, tableNo, SHOP); return Result.success(data); } /** * 外卖下单二维码解析 */ private Result? parseDeliveryQRCode(String params) { MapString, String paramMap parseParams(params); Long shopId Long.parseLong(paramMap.get(shopId)); String address paramMap.get(address); Shop shop shopService.getById(shopId); if (shop null) { return Result.error(店铺不存在); } // 计算配送费 BigDecimal deliveryFee calculateDeliveryFee(shopId, address); MapString, Object data new HashMap(); data.put(shop, shop); data.put(deliveryFee, deliveryFee); data.put(address, address); data.put(isDelivery, true); // 标记为外卖模式 return Result.success(data); } /** * 营销活动二维码解析 */ private Result? parseCouponQRCode(String params) { MapString, String paramMap parseParams(params); Long activityId Long.parseLong(paramMap.get(id)); Integer type Integer.parseInt(paramMap.get(type)); CouponActivity activity couponService.getById(activityId); if (activity null || activity.getStatus() ! 1) { return Result.error(活动不存在或已结束); } // 检查是否已领取 boolean alreadyReceived couponService.hasReceived(activityId); MapString, Object data new HashMap(); data.put(activity, activity); data.put(alreadyReceived, alreadyReceived); return Result.success(data); } /** * 取餐码二维码解析 */ private Result? parsePickupQRCode(String params) { MapString, String paramMap parseParams(params); String orderNo paramMap.get(orderNo); Order order orderService.getByOrderNo(orderNo); if (order null) { return Result.error(订单不存在); } // 生成6位取餐码 String pickupCode generatePickupCode(); order.setPickupCode(pickupCode); order.setStatus(3); // 已完成待取餐 orderMapper.updateById(order); MapString, Object data new HashMap(); data.put(order, order); data.put(pickupCode, pickupCode); return Result.success(data); } /** * 工具解析URL参数 */ private MapString, String parseParams(String params) { MapString, String map new HashMap(); String[] pairs params.split(); for (String pair : pairs) { String[] kv pair.split(); if (kv.length 2) { map.put(kv[0], kv[1]); } } return map; } /** * 计算配送费(根据距离) */ private BigDecimal calculateDeliveryFee(Long shopId, String address) { // 简化逻辑3km内5元每超1km加1元 Double distance 2.5; // 实际应调用地图API计算 if (distance 3) { return new BigDecimal(5.00); } else { int extraKm (int) Math.ceil(distance - 3); return new BigDecimal(5.00).add(new BigDecimal(extraKm)); } } /** * 生成6位取餐码 */ private String generatePickupCode() { return String.format(%06d, new Random().nextInt(1000000)); } }3️⃣ 店铺菜单查询ShopService.javajavaService public class ShopServiceImpl implements ShopService { Autowired private ShopMapper shopMapper; Autowired private MenuMapper menuMapper; /** * 根据店铺ID查询菜单(店内点餐用) */ Override public ListMenuItem getMenuByShopId(Long shopId) { LambdaQueryWrapperMenuItem wrapper new LambdaQueryWrapper(); wrapper.eq(MenuItem::getShopId, shopId) .eq(MenuItem::getStatus, 1) // 上架 .orderByAsc(MenuItem::getSort); ListMenuItem list menuMapper.selectList(wrapper); // 按分类分组 MapLong, ListMenuItem grouped list.stream() .collect(Collectors.groupingBy(MenuItem::getCategoryId)); // 转换为前端需要的格式 ListCategoryVO categories grouped.entrySet().stream() .map(entry - { CategoryVO vo new CategoryVO(); vo.setCategoryId(entry.getKey()); vo.setItems(entry.getValue()); return vo; }) .collect(Collectors.toList()); return categories; } } 二、UniApp前端扫码逻辑 ⭐⭐⭐1️⃣pages/scan/scan.vue- 扫码入口页vuetemplate view classscan-page !-- 顶部提示 -- view classheader text classtitle扫码点餐/text text classsubtitle扫描桌上二维码开始点餐/text /view !-- 区域 -- view classscan-area clickstartScan camera v-if!scanResult classcamera device-positionback flashoff erroronCameraError view classscan-frame view classcorner top-left/view view classcorner top-right/view view classcorner bottom-left/view view classcorner bottom-right/view text classscan-tip将二维码放入框内/text /view /camera !-- 扫码成功 -- view v-ifscanResult classresult-card uni-icons typecheckbox-filled size60 color#07c160/uni-icons text classresult-text扫码成功/text button classbtn-confirm clickgoToPage进入点餐/button /view /view !-- 备选方案手动输入 -- view classmanual-input text classdivider或者/text input v-modelmanualCode placeholder输入桌号如A05 classinput confirmmanualSearch / button classbtn-search clickmanualSearch查询/button /view /view /template script export default { data() { return { scanResult: null, manualCode: , shopData: null } }, methods: { // 核心调用微信扫码API startScan() { uni.scanCode({ onlyFromCamera: true, // 只从相机扫码 success: (res) { console.log(扫码结果:, res.result) this.scanResult res.result this.parseQRCode(res.result) }, fail: (err) { console.error(扫码失败:, err) uni.showToast({ title: 扫码失败, icon: none }) } }) }, // 解析二维码内容请求后端 async parseQRCode(code) { uni.showLoading({ title: 解析中... }) try { const res await uni.request({ url: http://localhost:8080/api/scan/parse, method: GET, data: { code } }) if (res.data.code 200) { this.shopData res.data.data // 根据类型跳转不同页面 if (this.shopData.isDelivery) { // 外卖模式 uni.navigateTo({ url: /pages/delivery/delivery?shopId${this.shopData.shop.id} }) } else { // 店内点餐模式 uni.navigateTo({ url: /pages/order/order?shopId${this.shopData.shop.id}table${this.shopData.table?.tableNo || } }) } } else { uni.showToast({ title: res.data.message, icon: none }) } } catch (e) { console.error(e) } finally { uni.hideLoading() } }, // 手动输入桌号查询 async manualSearch() { if (!this.manualCode) { return uni.showToast({ title: 请输入桌号, icon: none }) } uni.showLoading({ title: 查询中... }) try { const res await uni.request({ url: http://localhost:8080/api/shop/getByTable, method: GET, data: { tableNo: this.manualCode } }) if (res.data.code 200) { this.shopData res.data.data uni.navigateTo({ url: /pages/order/order?shopId${this.shopData.shop.id}table${this.manualCode} }) } } catch (e) { console.error(e) } finally { uni.hideLoading() } }, goToPage() { if (this.shopData.isDelivery) { uni.navigateTo({ url: /pages/delivery/delivery?shopId${this.shopData.shop.id} }) } else { uni.navigateTo({ url: /pages/order/order?shopId${this.shopData.shop.id} }) } }, onCameraError(e) { console.error(相机错误:, e) uni.showModal({ title: 提示, content: 无法打开相机请检查权限设置, showCancel: false }) } } } /script style scoped .scan-page { min-height: 100vh; background: #f5f5f5; padding: 40rpx; } .header { text-align: center; margin-bottom: 60rpx; } .title { font-size: 48rpx; font-weight: bold; color: #333; display: block; } .subtitle { font-size: 28rpx; color: #999; margin-top: 16rpx; } .scan-area { width: 100%; height: 600rpx; background: #000; border-radius: 20rpx; overflow: hidden; position: relative; } .camera { width: 100%; height: 100%; } .scan-frame { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 400rpx; height: 400rpx; border: 4rpx solid rgba(255,255,255,0.5); border-radius: 20rpx; } .corner { position: absolute; width: 60rpx; height: 60rpx; border-color: #07c160; border-style: solid; } .top-left { top: 0; left: 0; border-width: 6rpx 0 0 6rpx; border-radius: 10rpx 0 0 0; } .top-right { top: 0; right: 0; border-width: 6rpx 6rpx 0 0; border-radius: 0 10rpx 0 0; } .bottom-left { bottom: 0; left: 0; border-width: 0 0 6rpx 6rpx; border-radius: 0 0 0 10rpx; } .bottom-right { bottom: 0; right: 0; border-width: 0 6rpx 6rpx 0; border-radius: 0 0 10rpx 0; } .scan-tip { position: absolute; bottom: -60rpx; left: 50%; transform: translateX(-50%); color: #fff; font-size: 28rpx; white-space: nowrap; } .result-card { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(255,255,255,0.95); padding: 60rpx; border-radius: 20rpx; text-align: center; } .result-text { display: block; font-size: 32rpx; color: #333; margin: 20rpx 0 40rpx; } .btn-confirm { background: #07c160; color: #fff; border: none; border-radius: 50rpx; padding: 20rpx 80rpx; font-size: 32rpx; } .manual-input { margin-top: 60rpx; text-align: center; } .divider { color: #999; font-size: 28rpx; margin: 0 20rpx; } .input { display: inline-block; width: 300rpx; background: #fff; border-radius: 40rpx; padding: 16rpx 30rpx; font-size: 28rpx; } .btn-search { display: inline-block; margin-left: 20rpx; background: #07c160; color: #fff; border: none; border-radius: 40rpx; padding: 16rpx 40rpx; font-size: 28rpx; } /style2️⃣pages/order/order.vue- 扫码后的点餐页 ⭐vuetemplate view classorder-page !-- 店铺信息 -- view classshop-header image :srcshop.coverImg classshop-cover modeaspectFill/image view classshop-info text classshop-name{{ shop.name }}/text text classtable-info v-iftable桌号: {{ table }}/text text classshop-desc{{ shop.description }}/text /view /view !-- 菜单列表 -- view classmenu-container view v-forcategory in menuList :keycategory.categoryId classcategory-section :idcat- category.categoryId text classcategory-title{{ category.categoryName }}/text view v-foritem in category.items :keyitem.id classmenu-item clickshowItemDetail(item) image :srcitem.image classitem-img modeaspectFill/image view classitem-info text classitem-name{{ item.name }}/text text classitem-desc{{ item.description }}/text view classitem-bottom text classitem-price¥{{ item.price }}/text view classcart-control click.stopaddToCart(item) uni-icons v-ifgetCartCount(item.id) 0 typecheckbox-filled size20 color#07c160/uni-icons text v-ifgetCartCount(item.id) 0 classcount {{ getCartCount(item.id) }} /text uni-icons v-else typeplus-filled size20 color#999/uni-icons /view /view /view /view /view /view !-- 底部购物车栏 -- view classcart-bar v-ifcartList.length 0 view classcart-info clickshowCartPopup true view classcart-icon-wrap uni-icons typecart-filled size32 color#fff/uni-icons text classcart-badge{{ totalCount }}/text /view view classcart-price text classtotal-label合计:/text text classtotal-amount¥{{ totalPrice }}/text /view /view button classbtn-submit clicksubmitOrder去结算/button /view !-- 购物车弹窗 -- uni-popup refcartPopup typebottom view classcart-popup view classpopup-header text classpopup-title购物车/text text classclear-btn clickclearCart清空/text /view scroll-view scroll-y classcart-list view v-foritem in cartList :keyitem.id classcart-item text classcart-item-name{{ item.name }}/text view classcart-item-control view classminus-btn clickremoveFromCart(item.id)-/view text classcart-item-count{{ item.count }}/text view classplus-btn clickaddToCart(item)/view /view text classcart-item-price¥{{ (item.price * item.count).toFixed(2) }}/text /view /scroll-view /view /uni-popup /view /template script export default { data() { return { shopId: null, table: , shop: {}, menuList: [], cartList: [], // { id, name, price, count, image } showCartPopup: false, totalPrice: 0.00, totalCount: 0 } }, onLoad(options) { this.shopId options.shopId this.table options.table || this.loadShopData() }, methods: { async loadShopData() { uni.showLoading({ title: 加载中... }) try { const res await uni.request({ url: http://localhost:8080/api/scan/parse, method: GET, data: { code: CAMPUS://SHOP?id${this.shopId}table${this.table} } }) if (res.data.code 200) { this.shop res.data.data.shop this.menuList res.data.data.menu } } catch (e) { console.error(e) } finally { uni.hideLoading() } }, addToCart(item) { const exist this.cartList.find(c c.id item.id) if (exist) { exist.count } else { this.cartList.push({ id: item.id, name: item.name, price: item.price, count: 1, image: item.image }) } this.calcTotal() }, removeFromCart(id) { const item this.cartList.find(c c.id id) if (item) { item.count-- if (item.count 0) { this.cartList this.cartList.filter(c c.id ! id) } } this.calcTotal() }, getCartCount(id) { const item this.cartList.find(c c.id id) return item ? item.count : 0 }, calcTotal() { this.totalCount this.cartList.reduce((sum, item) sum item.count, 0) this.totalPrice this.cartList.reduce( (sum, item) sum item.price * item.count, 0 ).toFixed(2) }, async submitOrder() { if (this.cartList.length 0) return uni.showLoading({ title: 提交中... }) try { const res await uni.request({ url: http://localhost:8080/api/errand/publish, method: POST, header: { Authorization: Bearer uni.getStorageSync(token) }, data: { shopId: this.shopId, tableNo: this.table, items: this.cartList.map(item ({ menuId: item.id, count: item.count, price: item.price })), totalPrice: this.totalPrice } }) if (res.data.code 200) { uni.showModal({ title: 下单成功, content: 订单号: ${res.data.data.orderNo}, showCancel: false, success: () { uni.redirectTo({ url: /pages/orderDetail/orderDetail?orderNo${res.data.data.orderNo} }) } }) } } catch (e) { console.error(e) } finally { uni.hideLoading() } }, clearCart() { this.cartList [] this.calcTotal() this.showCartPopup false } } } /script style scoped .order-page { padding-bottom: 140rpx; } .shop-header { background: #fff; padding: 30rpx; display: flex; gap: 20rpx; } .shop-cover { width: 160rpx; height: 160rpx; border-radius: 16rpx; } .shop-info { flex: 1; display: flex; flex-direction: column; justify-content: center; } .shop-name { font-size: 34rpx; font-weight: bold; color: #333; } .table-info { font-size: 24rpx; color: #07c160; margin-top: 8rpx; } .shop-desc { font-size: 24rpx; color: #999; margin-top: 8rpx; } .menu-container { background: #fff; margin-top: 20rpx; padding: 0 30rpx; } .category-title { font-size: 30rpx; font-weight: bold; color: #333; padding: 30rpx 0 20rpx; display: block; border-bottom: 1rpx solid #f0f0f0; } .menu-item { display: flex; padding: 24rpx 0; border-bottom: 1rpx solid #f5f5f5; } .item-img { width: 160rpx; height: 160rpx; border-radius: 12rpx; margin-right: 20rpx; } .item-info { flex: 1; display: flex; flex-direction: column; justify-content: space-between; } .item-name { font-size: 28rpx; font-weight: bold; color: #333; } .item-desc { font-size: 24rpx; color: #999; margin-top: 8rpx; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } .item-bottom { display: flex; justify-content: space-between; align-items: center; margin-top: 16rpx; } .item-price { font-size: 32rpx; color: #ff4d4f; font-weight: bold; } .cart-control { display: flex; align-items: center; gap: 16rpx; } .count { font-size: 28rpx; color: #07c160; font-weight: bold; min-width: 40rpx; text-align: center; } .cart-bar { position: fixed; bottom: 0; left: 0; right: 0; height: 120rpx; background: #2d2d2d; display: flex; align-items: center; justify-content: space-between; padding: 0 30rpx; box-shadow: 0 -4rpx 20rpx rgba(0,0,0,0.1); } .cart-info { display: flex; align-items: center; gap: 20rpx; } .cart-icon-wrap { position: relative; width: 80rpx; height: 80rpx; background: #07c160; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-top: -40rpx; } .cart-badge { position: absolute; top: -10rpx; right: -10rpx; background: #ff4d4f; color: #fff; font-size: 20rpx; padding: 4rpx 12rpx; border-radius: 20rpx; } .total-label { font-size: 28rpx; color: #999; } .total-amount { font-size: 36rpx; color: #ff4d4f; font-weight: bold; margin-left: 10rpx; } .btn-submit { background: linear-gradient(135deg, #07c160, #06ad56); color: #fff; border: none; border-radius: 50rpx; padding: 24rpx 60rpx; font-size: 32rpx; font-weight: bold; } .cart-popup { background: #fff; border-radius: 30rpx 30rpx 0 0; padding: 30rpx; max-height: 60vh; } .popup-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20rpx; } .popup-title { font-size: 34rpx; font-weight: bold; color: #333; } .clear-btn { font-size: 28rpx; color: #999; } .cart-item { display: flex; align-items: center; padding: 20rpx 0; border-bottom: 1rpx solid #f0f0f0; } .cart-item-name { flex: 1; font-size: 28rpx; color: #333; } .cart-item-control { display: flex; align-items: center; gap: 24rpx; margin: 0 20rpx; } .minus-btn, .plus-btn { width: 48rpx; height: 48rpx; border-radius: 50%; background: #f5f5f5; display: flex; align-items: center; justify-content: center; font-size: 32rpx; color: #333; } .cart-item-count { font-size: 28rpx; font-weight: bold; min-width: 40rpx; text-align: center; } .cart-item-price { font-size: 28rpx; color: #ff4d4f; font-weight: bold; min-width: 120rpx; text-align: right; } /style️ 三、数据库表设计sql-- 店铺表 CREATE TABLE shop ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL COMMENT 店铺名, cover_img VARCHAR(500) COMMENT 封面图, description TEXT COMMENT 描述, address VARCHAR(200) COMMENT 地址, phone VARCHAR(20) COMMENT 电话, business_hours VARCHAR(50) COMMENT 营业时间, status TINYINT DEFAULT 1 COMMENT 1-营业 0-休业, qrcode_content TEXT COMMENT 二维码内容(JSON), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) COMMENT 店铺表; -- 桌台表 CREATE TABLE table_info ( id BIGINT PRIMARY KEY AUTO_INCREMENT, shop_id BIGINT NOT NULL COMMENT 店铺ID, table_no VARCHAR(20) NOT NULL COMMENT 桌号 A01, qrcode_content VARCHAR(500) COMMENT 桌台二维码内容, status TINYINT DEFAULT 1 COMMENT 1-空闲 0-占用, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_shop_table (shop_id, table_no) ) COMMENT 桌台表; -- 扫码记录表(用于数据分析) CREATE TABLE scan_log ( id BIGINT PRIMARY KEY AUTO_INCREMENT, shop_id BIGINT NOT NULL, table_no VARCHAR(20) COMMENT 桌号, scan_type VARCHAR(20) COMMENT SHOP/DELIVERY/COUPON, user_id BIGINT COMMENT 用户ID(可选), openid VARCHAR(100) COMMENT 微信openid, scan_time DATETIME DEFAULT CURRENT_TIMESTAMP, INDEX idx_shop_time (shop_id, scan_time) ) COMMENT 扫码记录表; 四、扫码流程总结用户扫码 ↓ uni.scanCode() 获取二维码内容 ↓ 请求后端 /api/scan/parse?codexxx ↓ 后端解析协议头 CAMPUS:// ↓ 根据类型(SHOP/DELIVERY/COUPON/PICKUP)分发 ↓ 返回对应数据(店铺菜单/配送费/优惠券/取餐码) ↓ 前端跳转对应页面 关键技术点技术用途✅uni.scanCode()微信扫码API✅ 协议头识别CAMPUS://区分业务类型✅ URL参数解析提取店铺ID、桌号等✅ Redis记录扫码日志数据统计分析✅ 分布式锁防止重复接单✅ JWT认证用户身份验证需要完整的连锁店多店铺管理、奶茶点餐特殊逻辑(规格选择)、同城外卖配送系统代码吗请告诉我

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…