当前位置: 首页 > news >正文

每天40分玩转Django:实操在线商城

实操在线商城

一、今日学习内容概述

模块重要程度主要内容
商品模型⭐⭐⭐⭐⭐商品信息、分类管理
购物车系统⭐⭐⭐⭐⭐购物车功能实现
订单系统⭐⭐⭐⭐⭐订单处理、支付集成
用户中心⭐⭐⭐⭐订单管理、个人信息

二、模型设计

# models.py
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator
from decimal import Decimalclass Category(models.Model):name = models.CharField('分类名称', max_length=100)slug = models.SlugField('URL', unique=True)description = models.TextField('描述', blank=True)image = models.ImageField('分类图片', upload_to='categories/', blank=True)class Meta:verbose_name = '商品分类'verbose_name_plural = verbose_namedef __str__(self):return self.nameclass Product(models.Model):category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')name = models.CharField('商品名称', max_length=200)slug = models.SlugField('URL', unique=True)description = models.TextField('商品描述')price = models.DecimalField('价格', max_digits=10, decimal_places=2)stock = models.PositiveIntegerField('库存')available = models.BooleanField('是否可用', default=True)created = models.DateTimeField('创建时间', auto_now_add=True)updated = models.DateTimeField('更新时间', auto_now=True)image = models.ImageField('商品图片', upload_to='products/')class Meta:verbose_name = '商品'verbose_name_plural = verbose_nameordering = ['-created']def __str__(self):return self.nameclass Cart(models.Model):user = models.OneToOneField(User, on_delete=models.CASCADE)created = models.DateTimeField('创建时间', auto_now_add=True)updated = models.DateTimeField('更新时间', auto_now=True)class Meta:verbose_name = '购物车'verbose_name_plural = verbose_namedef get_total_price(self):return sum(item.get_cost() for item in self.items.all())class CartItem(models.Model):cart = models.ForeignKey(Cart, related_name='items', on_delete=models.CASCADE)product = models.ForeignKey(Product, on_delete=models.CASCADE)quantity = models.PositiveIntegerField('数量', default=1)class Meta:verbose_name = '购物车项目'verbose_name_plural = verbose_namedef get_cost(self):return self.product.price * self.quantityclass Order(models.Model):STATUS_CHOICES = [('pending', '待支付'),('paid', '已支付'),('shipped', '已发货'),('completed', '已完成'),('cancelled', '已取消'),]user = models.ForeignKey(User, on_delete=models.CASCADE)address = models.TextField('收货地址')phone = models.CharField('联系电话', max_length=20)total_amount = models.DecimalField('总金额', max_digits=10, decimal_places=2)status = models.CharField('订单状态', max_length=10, choices=STATUS_CHOICES, default='pending')created = models.DateTimeField('创建时间', auto_now_add=True)updated = models.DateTimeField('更新时间', auto_now=True)class Meta:verbose_name = '订单'verbose_name_plural = verbose_nameordering = ['-created']def __str__(self):return f'Order {self.id}'class OrderItem(models.Model):order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)product = models.ForeignKey(Product, on_delete=models.CASCADE)price = models.DecimalField('价格', max_digits=10, decimal_places=2)quantity = models.PositiveIntegerField('数量', default=1)class Meta:verbose_name = '订单项目'verbose_name_plural = verbose_namedef get_cost(self):return self.price * self.quantity

三、视图实现

# views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import Product, Cart, CartItem, Order, OrderItemdef product_list(request, category_slug=None):category = Nonecategories = Category.objects.all()products = Product.objects.filter(available=True)if category_slug:category = get_object_or_404(Category, slug=category_slug)products = products.filter(category=category)return render(request, 'shop/product_list.html', {'category': category,'categories': categories,'products': products})@login_required
def add_to_cart(request, product_id):product = get_object_or_404(Product, id=product_id)cart, created = Cart.objects.get_or_create(user=request.user)cart_item, item_created = CartItem.objects.get_or_create(cart=cart,product=product)if not item_created:cart_item.quantity += 1cart_item.save()messages.success(request, f'{product.name} 已添加到购物车')return redirect('cart_detail')@login_required
def cart_detail(request):cart, created = Cart.objects.get_or_create(user=request.user)return render(request, 'shop/cart_detail.html', {'cart': cart})@login_required
def checkout(request):cart = get_object_or_404(Cart, user=request.user)if request.method == 'POST':# 创建订单order = Order.objects.create(user=request.user,address=request.POST.get('address'),phone=request.POST.get('phone'),total_amount=cart.get_total_price())# 创建订单项目for item in cart.items.all():OrderItem.objects.create(order=order,product=item.product,price=item.product.price,quantity=item.quantity)# 清空购物车cart.items.all().delete()messages.success(request, '订单创建成功!')return redirect('order_detail', order_id=order.id)return render(request, 'shop/checkout.html', {'cart': cart})

四、购物车流程图

在这里插入图片描述

五、模板实现

<!-- templates/shop/product_list.html -->
{% extends "base.html" %}{% block content %}
<div class="container mt-4"><div class="row"><!-- 分类侧边栏 --><div class="col-md-3"><div class="list-group"><a href="{% url 'product_list' %}" class="list-group-item list-group-item-action">所有商品</a>{% for c in categories %}<a href="{{ c.get_absolute_url }}" class="list-group-item list-group-item-action">{{ c.name }}</a>{% endfor %}</div></div><!-- 商品列表 --><div class="col-md-9"><div class="row">{% for product in products %}<div class="col-md-4 mb-4"><div class="card"><img src="{{ product.image.url }}" class="card-img-top" alt="{{ product.name }}"><div class="card-body"><h5 class="card-title">{{ product.name }}</h5><p class="card-text">价格: ¥{{ product.price }}</p><form action="{% url 'add_to_cart' product.id %}" method="post">{% csrf_token %}<button type="submit" class="btn btn-primary">加入购物车</button></form></div></div></div>{% endfor %}</div></div></div>
</div>
{% endblock %}<!-- templates/shop/cart_detail.html -->
{% extends "base.html" %}{% block content %}
<div class="container mt-4"><h2>购物车</h2>{% if cart.items.all %}<table class="table"><thead><tr><th>商品</th><th>单价</th><th>数量</th><th>小计</th><th>操作</th></tr></thead><tbody>{% for item in cart.items.all %}<tr><td>{{ item.product.name }}</td><td>¥{{ item.product.price }}</td><td>{{ item.quantity }}</td><td>¥{{ item.get_cost }}</td><td><form action="{% url 'remove_from_cart' item.id %}" method="post">{% csrf_token %}<button type="submit" class="btn btn-danger btn-sm">删除</button></form></td></tr>{% endfor %}</tbody><tfoot><tr><td colspan="3"><strong>总计</strong></td><td><strong>¥{{ cart.get_total_price }}</strong></td><td></td></tr></tfoot></table><a href="{% url 'checkout' %}" class="btn btn-primary">去结算</a>{% else %}<p>购物车是空的。</p>{% endif %}
</div>
{% endblock %}

六、URL配置

# urls.py
from django.urls import path
from . import viewsurlpatterns = [path('', views.product_list, name='product_list'),path('category/<slug:category_slug>/', views.product_list, name='product_list_by_category'),path('product/<int:id>/<slug:slug>/', views.product_detail, name='product_detail'),path('cart/', views.cart_detail, name='cart_detail'),path('add/<int:product_id>/',views.add_to_cart,name='add_to_cart'),path('remove/<int:item_id>/',views.remove_from_cart,name='remove_from_cart'),path('checkout/',views.checkout,name='checkout'),path('orders/',views.order_list,name='order_list'),path('order/<int:order_id>/',views.order_detail,name='order_detail'),
]

七、订单处理

# services.py
from django.db import transaction
from .models import Order, OrderItem, Cartclass OrderService:@staticmethod@transaction.atomicdef create_order(user, address, phone):"""创建订单"""cart = Cart.objects.get(user=user)# 检查库存for item in cart.items.all():if item.quantity > item.product.stock:raise ValueError(f'{item.product.name} 库存不足')# 创建订单order = Order.objects.create(user=user,address=address,phone=phone,total_amount=cart.get_total_price())# 创建订单项目并更新库存for item in cart.items.all():OrderItem.objects.create(order=order,product=item.product,price=item.product.price,quantity=item.quantity)item.product.stock -= item.quantityitem.product.save()# 清空购物车cart.items.all().delete()return order

八、测试代码

# tests.py
from django.test import TestCase
from django.contrib.auth.models import User
from .models import Product, Cart, CartItem
from decimal import Decimalclass ShopTest(TestCase):def setUp(self):self.user = User.objects.create_user(username='testuser',password='testpass123')self.product = Product.objects.create(name='Test Product',price=Decimal('99.99'),stock=10)def test_add_to_cart(self):self.client.login(username='testuser', password='testpass123')response = self.client.post(f'/add/{self.product.id}/')self.assertEqual(response.status_code, 302)cart = Cart.objects.get(user=self.user)self.assertEqual(cart.items.count(), 1)# tests.py def test_checkout(self):self.client.login(username='testuser', password='testpass123')# 添加商品到购物车cart = Cart.objects.create(user=self.user)CartItem.objects.create(cart=cart,product=self.product,quantity=2)# 提交订单response = self.client.post('/checkout/', {'address': 'Test Address','phone': '1234567890'})self.assertEqual(response.status_code, 302)self.assertEqual(cart.items.count(), 0)  # 购物车已清空# 检查订单是否创建成功order = Order.objects.filter(user=self.user).first()self.assertIsNotNone(order)self.assertEqual(order.total_amount, Decimal('199.98'))def test_stock_management(self):"""测试库存管理"""self.client.login(username='testuser', password='testpass123')# 添加超出库存数量的商品cart = Cart.objects.create(user=self.user)CartItem.objects.create(cart=cart,product=self.product,quantity=15  # 大于库存)# 尝试结算response = self.client.post('/checkout/', {'address': 'Test Address','phone': '1234567890'})# 应该返回错误self.assertEqual(response.status_code, 400)self.assertIn('库存不足', response.content.decode())

九、支付集成

# payment.py
from decimal import Decimal
import stripe
from django.conf import settingsstripe.api_key = settings.STRIPE_SECRET_KEYclass PaymentService:@staticmethoddef create_payment_intent(order):"""创建支付意图"""try:intent = stripe.PaymentIntent.create(amount=int(order.total_amount * 100),  # 转换为分currency='cny',metadata={'order_id': order.id})return intent.client_secretexcept stripe.error.StripeError as e:raise ValueError(f"支付创建失败: {str(e)}")@staticmethoddef confirm_payment(payment_intent_id):"""确认支付"""try:intent = stripe.PaymentIntent.retrieve(payment_intent_id)return intent.status == 'succeeded'except stripe.error.StripeError as e:raise ValueError(f"支付确认失败: {str(e)}")# views.py 添加支付相关视图
@login_required
def payment_process(request, order_id):order = get_object_or_404(Order, id=order_id, user=request.user)if request.method == 'POST':# 创建支付意图try:client_secret = PaymentService.create_payment_intent(order)return render(request, 'shop/payment.html', {'client_secret': client_secret,'order': order,'STRIPE_PUBLIC_KEY': settings.STRIPE_PUBLIC_KEY})except ValueError as e:messages.error(request, str(e))return redirect('order_detail', order_id=order.id)return render(request, 'shop/payment.html', {'order': order})

十、异步任务处理

# tasks.py
from celery import shared_task
from django.core.mail import send_mail
from .models import Order@shared_task
def send_order_confirmation(order_id):"""发送订单确认邮件"""order = Order.objects.get(id=order_id)subject = f'订单确认 #{order.id}'message = f'''亲爱的 {order.user.username}:您的订单 #{order.id} 已确认。订单总金额:¥{order.total_amount}感谢您的购买!'''send_mail(subject,message,'noreply@example.com',[order.user.email],fail_silently=False,)@shared_task
def check_order_timeout():"""检查超时未支付订单"""from django.utils import timezonefrom datetime import timedeltatimeout = timezone.now() - timedelta(hours=24)orders = Order.objects.filter(status='pending',created__lt=timeout)for order in orders:order.status = 'cancelled'order.save()

十一、性能优化建议

  1. 查询优化

    • 使用select_related和prefetch_related
    • 添加适当的索引
    • 缓存热门商品
  2. 缓存策略

    • 缓存商品列表
    • 缓存分类信息
    • 使用页面缓存
  3. 异步处理

    • 邮件发送
    • 订单状态更新
    • 库存检查
  4. 前端优化

    • 图片懒加载
    • 静态资源压缩
    • AJAX局部刷新

十二、扩展功能建议

  1. 商品功能

    • 商品评价系统
    • 商品收藏
    • 商品推荐
  2. 订单功能

    • 订单跟踪
    • 订单导出
    • 退换货处理
  3. 用户功能

    • 会员等级
    • 积分系统
    • 优惠券
  4. 统计分析

    • 销售报表
    • 用户行为分析
    • 库存预警

怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

相关文章:

每天40分玩转Django:实操在线商城

实操在线商城 一、今日学习内容概述 模块重要程度主要内容商品模型⭐⭐⭐⭐⭐商品信息、分类管理购物车系统⭐⭐⭐⭐⭐购物车功能实现订单系统⭐⭐⭐⭐⭐订单处理、支付集成用户中心⭐⭐⭐⭐订单管理、个人信息 二、模型设计 # models.py from django.db import models fro…...

Bug解决!ImportError: cannot import name MutableMapping from collections

省流&#xff1a;python版本更新 而一些生态库的变量命名没更新变化导致的问题 起因是在win环境下装spark 但是发现这是python底层的问题 于是想写一篇这个错误的博客警戒世人 py实在是太多生态库了 但并不是所有的都维护的很好 大概可以理解成 python原先有个东西叫col…...

【Rust自学】4.5. 切片(Slice)

4.5.0. 写在正文之前 这是第四章的最后一篇文章了&#xff0c;在这里也顺便对这章做一个总结&#xff1a; 所有权、借用和切片的概念确保 Rust 程序在编译时的内存安全。 Rust语言让程序员能够以与其他系统编程语言相同的方式控制内存使用情况&#xff0c;但是当数据所有者超…...

医学图像 三维重建,原图与灰度图叠加,原图与多图叠加显示;多图像融合显示,彩色灰度图像融合

Part1: Summary 我们在做图像分割或融合时&#xff0c;有时需要显示多份数据进行叠加显示&#xff1b;可能需要这种效果&#xff1a; 四视图&#xff1a; 基于这个&#xff0c;我看一下网上的实现总结了一下&#xff1b;实现了以下几种效果&#xff1a; Part2&#xff1a;多种…...

递归实现指数型枚举(递归)

92. 递归实现指数型枚举 - AcWing题库 每个数有选和不选两种情况 我们把每个数看成每层&#xff0c;可以画出一个递归搜索树 叶子节点就是我们的答案 很容易写出每dfs函数 dfs传入一个u表示层数 当层数大于我们n时&#xff0c;去判断每个数字的选择情况&#xff0c;输出被选…...

Unity实现Root Motion动画的Navigation自动导航

Root motion动画可以将角色的根节点&#xff08;通常是角色的骨盆或脚部&#xff09;的运动直接应用到游戏对象上&#xff0c;从而实现角色的自然移动和旋转&#xff0c;避免出现脚底打滑的现象。采用Root motion动画的游戏对象&#xff0c;通常是重载了onAnimatorMove函数&…...

[react]不能将类型“string | undefined”分配给类型“To”。 不能将类型“undefined”分配给类型“To”

场景, 封装组件的时候, 想通过外部传进去一个路由地址, 再用<Link to{}>跳转, 显示这个, 有四种方法解决 第一种 合并运算符 ?? ?? 是 空值合并运算符&#xff08;Nullish Coalescing Operator&#xff09;&#xff0c;它是 JavaScript 和 TypeScript 中的一种逻辑…...

python实现基于RPC协议的接口自动化测试

01 什么是RPC RPC&#xff08;Remote Procedure Call&#xff09;远程过程调用协议是一个用于建立适当框架的协议。从本质上讲&#xff0c;它使一台机器上的程序能够调用另一台机器上的子程序&#xff0c;而不会意识到它是远程的。 RPC 是一种软件通信协议&#xff0c;一个程…...

如何使用PSQL Tool还原pg数据库(sql格式)

新建一个数据库用来还原&#xff1b;选择新建的数据库&#xff0c;右键选择【PSQL Tool】&#xff0c;打开PSQL Tool命令行界面&#xff1b;赋予pg库对sql文件的执行权限&#xff0c;否则会报“Permission denied”的错误&#xff0c;命令如下&#xff1a; chmod urwx D://NoS…...

uni-app商品搜索页面

目录 一:功能概述 二:功能实现 一:功能概述 商品搜索页面,可以根据商品品牌,商品分类,商品价格等信息实现商品搜索和列表展示。 二:功能实现 1:商品搜索数据 <view class="search-map padding-main bg-base"> <view class…...

【深度学习】零基础介绍循环神经网络(RNN)

RNN介绍 零基础介绍语言处理技术基本介绍分词算法词法分析工具文本分类与聚类情感分析 自然语言处理词向量词向量学习模型1. 神经网络语言模型2. CBOW 和 skip-gram3. 层次化softmax方法4. 负采样方法 RNN介绍RNN的变种&#xff1a;LSTM1. Forget Gate2. Input Gate3. Update M…...

青少年编程与数学 02-004 Go语言Web编程 13课题、模板引擎

青少年编程与数学 02-004 Go语言Web编程 13课题、模板引擎 一、模板引擎模板引擎的主要特点包括&#xff1a;模板引擎的应用场景&#xff1a;Go语言中的模板引擎&#xff1a;示例&#xff1a;使用Go的html/template包 二、工作流程1. 创建模板文件2. 准备数据3. 加载模板4. 渲染…...

如何优雅的关闭GoWeb服务器

以下内容均为Let’s Go Further内容节选以及作者本人理解。 这里创建了一个后台进程用于捕获关闭信号&#xff0c;在后台进程中&#xff0c;主要内容为&#xff1a; 创建一个缓冲通道 quit使用signal.Notify函数监听并捕获关机信号SIGINT,SIGTERM&#xff0c;在捕获关机信号后…...

AI程序员,开源的Devin,OpenHands 如何使用HuggingFace Inference API

我用了一下&#xff0c;界面这样子&#xff1a; Github&#xff1a;https://github.com/All-Hands-AI/OpenHands OpenHands 如何使用HuggingFace Inference API huggingface/meta-llama/Llama-3.3-70B-Instruct 而不是 meta-llama/Llama-3.3-70B-Instruct 不要设置base URL&…...

【动手学运动规划】 5.2 数值优化基础:梯度下降法,牛顿法

朕四季常服, 不过八套. — 大明王朝1566 道长 &#x1f3f0;代码及环境配置&#xff1a;请参考 环境配置和代码运行! 上一节我们介绍了数值优化的基本概念, 让大家对最优化问题有了基本的理解. 那么对于一个具体的问题, 我们应该如何求解呢? 这一节我们将介绍几个基本的求解…...

电子应用设计方案66:智能打印机系统设计

智能打印机系统设计 一、引言 随着科技的不断发展&#xff0c;打印机也在向智能化方向演进。智能打印机不仅能够提供高质量的打印服务&#xff0c;还具备便捷的操作、智能的管理和连接功能。 二、系统概述 1. 系统目标 - 实现高效、高质量的打印输出。 - 支持多种连接方式&am…...

iClient3D for Cesium 实现限高分析

作者&#xff1a;gaogy 1、背景 随着地理信息技术的发展&#xff0c;三维地球技术逐渐成为了许多领域中的核心工具&#xff0c;尤其是在城市规划、环境监测、航空航天以及军事领域。三维地图和场景的应用正在帮助人们更加直观地理解空间数据&#xff0c;提供更高效的决策支持。…...

AI开发:使用支持向量机(SVM)进行文本情感分析训练 - Python

支持向量机是AI开发中最常见的一种算法。之前我们已经一起初步了解了它的概念和应用&#xff0c;今天我们用它来进行一次文本情感分析训练。 一、概念温习 支持向量机&#xff08;SVM&#xff09;是一种监督学习算法&#xff0c;广泛用于分类和回归问题。 它的核心思想是通过…...

torch.unsqueeze:灵活调整张量维度的利器

在深度学习框架PyTorch中&#xff0c;张量&#xff08;Tensor&#xff09;是最基本的数据结构&#xff0c;它类似于NumPy中的数组&#xff0c;但可以在GPU上运行。在日常的深度学习编程中&#xff0c;我们经常需要调整张量的维度以适应不同的操作和层。torch.unsqueeze函数就是…...

【WRF教程第3.1期】预处理系统 WPS 详解:以4.5版本为例

预处理系统 WPS 详解&#xff1a;以4.5版本为例 每个 WPS 程序的功能程序1&#xff1a;geogrid程序2&#xff1a;ungrib程序3&#xff1a;metgrid WPS运行&#xff08;Running the WPS&#xff09;步骤1&#xff1a;Define model domains with geogrid步骤2&#xff1a;Extract…...

Phi-3-mini-4k-instruct-gguf步骤详解:supervisor服务管理与错误日志定位方法

Phi-3-mini-4k-instruct-gguf步骤详解&#xff1a;supervisor服务管理与错误日志定位方法 1. 模型概述 Phi-3-mini-4k-instruct-gguf是微软Phi-3系列中的轻量级文本生成模型GGUF版本&#xff0c;特别适合问答、文本改写、摘要整理和简短创作等场景。这个开箱即用的解决方案已…...

Qwen3.5-4B-Claude模型Java微服务集成指南:SpringBoot实战案例

Qwen3.5-4B-Claude模型Java微服务集成指南&#xff1a;SpringBoot实战案例 1. 引言&#xff1a;当大模型遇上微服务 最近在开发企业知识管理系统时&#xff0c;我们遇到了一个典型需求&#xff1a;如何让传统Java微服务架构与前沿的大语言模型无缝集成。经过多次尝试&#xf…...

DASD-4B-Thinking应用场景:科研人员用Chainlit调用长链思维模型写论文推导

DASD-4B-Thinking应用场景&#xff1a;科研人员用Chainlit调用长链思维模型写论文推导 安全声明&#xff1a;本文仅讨论技术实现与应用&#xff0c;所有内容均符合技术交流规范&#xff0c;不涉及任何敏感或违规内容。 1. 科研写作的新助手&#xff1a;当AI遇到学术研究 作为一…...

HunyuanVideo-Foley成本效益分析:自建服务与使用商用API的对比

HunyuanVideo-Foley成本效益分析&#xff1a;自建服务与使用商用API的对比 1. 引言&#xff1a;音效生成的技术选择困境 在视频制作领域&#xff0c;高质量音效往往能决定作品的最终质感。HunyuanVideo-Foley作为先进的AI音效生成技术&#xff0c;为企业提供了两种主要使用路…...

Qwen3-Reranker-8B开源大模型:支持HuggingFace Transformers原生加载

Qwen3-Reranker-8B开源大模型&#xff1a;支持HuggingFace Transformers原生加载 如果你正在构建一个智能搜索系统、问答机器人或者文档分析工具&#xff0c;那么“重排序”这个环节你一定不陌生。简单来说&#xff0c;它就像一个智能裁判&#xff0c;当你的检索系统从海量文档…...

避开这5个坑,你的YOLO模型训练效率翻倍:从yaml配置到GPU显存优化实战

YOLO模型训练效率翻倍的5个关键避坑指南&#xff1a;从参数调优到显存管理实战 当你第一次用YOLOv10或v11跑通训练流程时&#xff0c;可能会觉得"不过如此"。但真正投入实战后&#xff0c;90%的开发者都会遇到显存爆炸、训练龟速、指标波动三大噩梦。上周有位使用RTX…...

用STM32的定时器输入捕获功能,精准解码433MHz遥控器信号(附完整代码)

STM32定时器输入捕获技术解析&#xff1a;433MHz遥控信号精准解码实战 在智能家居DIY和工业控制领域&#xff0c;433MHz无线通信凭借其穿透性强、成本低廉的优势成为常见选择。但如何稳定可靠地解码这些无线信号&#xff0c;一直是开发者面临的挑战。本文将深入探讨基于STM32硬…...

开箱即用!Qwen-Image-2512-SDNQ Web服务快速体验指南

开箱即用&#xff01;Qwen-Image-2512-SDNQ Web服务快速体验指南 1. 五分钟了解Qwen-Image-2512-SDNQ Web服务 你是否遇到过这样的场景&#xff1a;需要快速生成一张概念图&#xff0c;但打开专业设计软件太麻烦&#xff1f;或者想尝试AI绘画&#xff0c;却被复杂的模型部署步…...

思源宋体CN终极指南:7款免费商用字体一站式解决方案

思源宋体CN终极指南&#xff1a;7款免费商用字体一站式解决方案 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还在为商业项目寻找高质量中文字体而烦恼吗&#xff1f;思源宋体CN字体…...

实体店有没有必要做门店小程序?

在当前消费行为不断向线上延伸的背景下&#xff0c;实体店是否需要搭建门店小程序&#xff0c;已经成为很多经营者在数字化转型过程中必须面对的问题。实体店是否有必要做门店小程序&#xff0c;取决于其是否需要提升获客能力与用户复购效率。一、为什么会出现这个问题在实际经…...