乐于分享
好东西不私藏

带后台管理的响应式多功能单页网站代码带下载模版带跳转出微信支付宝QQ三合一支付下单发货页面

带后台管理的响应式多功能单页网站代码带下载模版带跳转出微信支付宝QQ三合一支付下单发货页面

特别申明:本公众号博主不是程序员也不懂编程更不会写代码,总之本公众号博主是个没有文化的文盲,因为我个人认为生活在高科技时代我不会自己动手写代码,那我觉得我就是个文盲毕竟靠AI帮写的没有任何成就感,只能算是偷懒取巧而已。
我细心发现无论你的指令词写得有多详细,每次AI回复时总会出现词不达意而没有完全符合要求并且由于篇幅有限就会自动偷工减料省略各种问题细节,所以事实证明AI也会偷懒。
但其实也不是"AI偷懒"而是使用AI的人必须是要比AI机器人本身更加具备专业知识储备才能写出能够让它严格按照主人思路去完成编程工作的指令词,所以我本人不是程序员就是一个无法治愈的大硬伤。
所以呢,建议那些已婚已育的家长们一定要让你家孩子从幼儿园开始接触代码编程知识,长大后才不会有遗憾,那些有幸在06后出生的孩子才是未来新科技的希望,编程应从娃娃学起,不要像我们80后错失以前的时代先机!
我出生在没机会从小就能接触到电脑的80后偏僻农村时代,虽然农村一些人会有机会接触电脑,但我这种一开始就没缘分接触电脑的人就肯定没机会早遇到,我读书学历也只有六年级小学程度就辍学,我没上过初中/高中更没上过大学,所以我至今看不懂英文就自然无法理解编程代码的工作逻辑。
一切都要讲缘分,我是从2012年才后知后觉真正开始有缘分接触到电脑,这是因为我在2012年的时候遇到有个做项目的人跟我说了某个商城项目之后由于那个项目需要登录商城后台去操作我自己账号什么的,做过网络项目的同龄人一定是有同感的。
但由于我自己没电脑也不懂电脑,也从没接触过什么电脑操作,脑子一片空白,所以对方就建议我去网吧登录学习看看,所以就因为这个做网络项目的契机,我才开始后知后觉正式近距离自己有缘接触到电脑网络,而且是我利用下班业余时在网吧里自学的电脑,我学的都是一些电脑基础操作。
2012年我都多少岁了?请80后同龄人自己脑补一下大概岁数还能学到什么?最关键是我一开始并没有缘分往编程方向去了解,而是被人家往做网络项目的方向去引导,比如登录他们创建的什么商城后台等等,毕竟我花钱在推荐人下面报单的不可能对自己花钱的账号置之不理。
所以我去网吧从来不打游戏,我讨厌游戏,对游戏不感兴趣。我当时去网吧就只是为了登录我花钱投资的别人所谓的商城后台查看学习而被迫学的电脑,我也没有学过要自己开发商城就自然联想不到编程那方面去。
一开始是从询问网吧里网管教我怎么开机和关机,因为我花钱去网吧上网时第一次不知道怎么开关机,而人家网吧收了顾客上网费肯定要教我点基础操作我才能上够钟不浪费钱对吧?以及我自己摸索从怎么样打字学起一步一步探索神奇的电脑,到我自己学会怎么打字用电脑时才花钱让人帮我组装台式机。
我从没参加过什么电脑培训班,更不知还有程序员这种职业,毕竟我以前还不懂编程是个啥玩意?不怕大家笑话,我是2023年开始了解到原来还有程序员这个职业,因为我以前关注的点是网络项目,并不在编程这方面,就都不知道程序员是干啥的?
幸亏有了B站我才开始了解到编程的乐趣和好处,但我这种没文化没基础的人根本就没啥用处。总之我已经错过了学习编程的学生年代,而且我第一次接触电脑时很自卑觉得自己文化程度低怕被骗也怕学不会高级电脑知识,所以我只能自学一下电脑基础用于日常需要,仅此而已。
我最开始第一次看见电脑是2005年在深圳做没有工资的免费广告店学徒,相当于给人做义工,没工资但有包吃住,做了一年感觉广告行业不适合自己就不干了,那时我看见的电脑还是老式笨重的电脑,而且别人不让我玩他们的电脑,所以我2005年第一次看见电脑却没机会近距离接触。
2012年至2015年我去网吧自己学会电脑一些办公常用的基础之后还自学了PS广告设计,我是2018年才自己买电脑之后就再也没去过网吧的,我以前第一个老QQ号码是2012年在网吧注册的,也是后知后觉而依靠机缘接触到QQ这个工具,包括后来的微信也是后知后觉注册的。
我目前这个微信公众号是在2018年09月25日才开始正式启用,其实我有在淘宝买过九个公众号,但由于以前我很多都不懂,也不会运营,而且以前投资做的那些网络项目他们都倒闭了,这就又给我了一个后知后觉的感悟是宁愿自己沉淀学习也不乱跟别人做垃圾项目。
所以其它公众号都已经注销了,以前我也不懂公众号的价值,只是想着发网络项目的文章而已,项目一倒闭我就认为没啥用了,而目前我只剩下这个公众号也属于半闲置状态,我不愿再加入别人的个体团队,因为他们都是小人只看重个人利益不重视商业道德。
使用QQ时也是因为2012年别人引导我去做网络项目需要进群才注册的QQ号,不然我连QQ和腾讯这玩意都不会有机会接触到,都是缘分,到后来我那个老QQ密码都忘记找不回了,虽然别人早就有QQ了,而我是因为学电脑和接触电脑的时间比别人慢,属于是后知后觉注册的QQ,我现在的QQ都是新的,但也有很多年了啊。
我记得我用老QQ时认识了一个90后美女网友聊了一个月,而且是她自己主动加我的,然后后来是因为我密码忘记找不回就失联错过奔现良机了,也没有她电话,哈哈哈,所谓有缘但无份的人,就是还没在现实里见过面,因为我只和她聊天解闷而已。
很奇怪,我不管接触什么都总是比别人慢不止半拍,别人是先知先觉,而我却总是后知后觉,包括我以前都没有想过要谈恋爱,根本就没往那方面去想,刚开始玩QQ也就是为了做网络项目而已,难道这就是所谓的缘分未到就接触不到?
由于我比较笨,所以我自学电脑时学的都全部是基础,没有任何技术含量,毕竟我不是吃那碗饭的人,很多东西学习是需要靠天赋再加上努力的,单纯努力而没天赋也很难学成什么程度。
这里顺便提示一下:我网盘里整理分享的资料绝大部分都是下载了别人以前上传的资料,然后再重新搬运上传到我网盘的,我在别人网盘下载下来,有些老软件老资料显示的年份就毕竟早年。
有些都是2012年我还没接触电脑之前,别人就已经整理上传到别人自己网盘里的老资料,有些是我下载之后又自己整理重新打包了一遍,有些则是没有打包就保持原样上传到我自己的网盘,所以若发现资料太老太过时或打不开的也别见怪就是了。
我上面这段自述可不是什么文案,而是我真实的过往经历和后知后觉的感悟,也是我这辈子唯一的遗憾就是没那个命早早接触编程成为一名程序技术员,我白活了半辈子,一切都是命,我觉得我就是来人间体验虚幻生活,因为人生到头来也只不过是梦一场空手去
我从第一次被别人引导做网络项目到自学电脑之后我只学会了:打字、PS制图、视频剪辑、录音剪辑、字幕配对、电子书制作这些都是以前自学的,到现在如今的自学AI指令词运用,其它凡是编程类的我就都不会,因为我没那天赋学不了编程代码,只能靠AI教我了。
好了,废话就不啰嗦了,谢谢你非常无聊地看完我这无聊人的前半段啰嗦内容,我只不过是趁我现在还有记忆就记述下来防止以后老了失忆忘了是哪年开始学的电脑,毕竟人都是会有到将来老年记性不好的时候嘛,哈哈。
下面就是AI它回答我的内容仅供参考👇

为了实现一个 带后台管理、响应式多功能单页网站,并提供 三合一支付下单发货功能,同时 无需购买任何第三方服务器,我们可以采用 前端静态托管 + 后端无服务器云函数 + 免费数据库 的方案,所有服务均在免费额度内运行。


一、整体技术架构

层级
技术选型
免费服务
前端(SPA)
HTML + Tailwind CSS + 原生 JavaScript(或 React)
部署在 Vercel / Netlify / GitHub Pages
后端 API
Node.js + Express
部署在 Vercel Serverless Functions 或 Netlify Functions
数据库
MongoDB Atlas 或 Supabase (PostgreSQL)
免费 512MB 存储
支付聚合
使用 PayJS 或 虎皮椒 等第三方聚合支付平台
仅需注册账号,无需服务器,前端直接调用
后台管理
使用 纯前端后台面板(不依赖后端渲染)
同样托管在 Vercel,通过 API 操作数据
身份验证
JWT 或 Supabase Auth
免费

✅ 支付流程:前端发起订单 → 云函数生成支付参数 → 用户跳转支付 → 支付平台异步回调通知云函数 → 云函数更新订单状态并触发“发货”逻辑(如发送邮件或更新库存)。


二、项目文件结构

my-website/├── frontend/# 前端单页应用(用户端 + 管理端)│ ├── public/│ │ └── index.html# 主页面(SPA)│ ├── src/│ │ ├── css/│ │ │ └── style.css# 自定义样式 + Tailwind│ │ ├── js/│ │ │ ├── app.js# 前端路由、功能│ │ │ ├── api.js# 封装 fetch 调用后端 API│ │ │ └── admin.js# 后台管理逻辑│ │ └── pages/# 页面模块(按需加载)│ │ ├── home.html│ │ ├── products.html│ │ ├── checkout.html│ │ └── admin.html│ └── vercel.json# Vercel 部署配置├── backend/# 云函数(Serverless)│ └── api/# Vercel Functions 默认目录│ ├── order.js# 创建订单、支付回调│ ├── product.js# 商品增删改查│ ├── auth.js# 登录验证│ └── utils/# 工具函数(数据库连接、支付配置)├── database/# 数据库模型(示例)│ └── models.js├── .env# 环境变量(本地)└── README.md

三、核心代码实现

1. 前端主页面 (frontend/public/index.html)

这是一个单页应用,通过 JS 动态切换内容区域,内置导航、商品展示、购物车、支付流程和后台管理面板。

<!DOCTYPE html><htmllang=”zh-CN”><head> <metacharset=”UTF-8” /> <metaname=”viewport”content=”width=device-width,initial-scale=1.0” /> <title>个人多功能网站</title> <!-- Tailwind CSS (CDN) --> <scriptsrc=”https://cdn.tailwindcss.com”></script> <!-- Font Awesome --> <linkrel=”stylesheet”href=”https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css” /> <style> /* 自定义样式,比如加载动画、过渡效果 */ .page { display: none; } .page.active { display: block; } </style></head><body> <!-- 顶部导航 --> <navclass=”bg-whiteshadow-mdp-4stickytop-0z-50”> <divclass=”containermx-autoflexjustify-betweenitems-center”> <spanclass=”text-xlfont-bold”>我的商店</span> <div> <buttondata-page=”home”class=”nav-btnmx-2hover:text-blue-600”>首页</button> <buttondata-page=”products”class=”nav-btnmx-2hover:text-blue-600”>商品</button> <buttondata-page=”cart”class=”nav-btnmx-2hover:text-blue-600”> 购物车 <spanid=”cart-count”class=”bg-red-500text-whiterounded-fullpx-2py-0.5text-xs”>0</span> </button> <buttondata-page=”admin”class=”nav-btnmx-2hover:text-blue-600”>管理</button> </div> </div> </nav> <!-- 页面容器 --> <mainclass=”containermx-autop-4”> <divid=”home”class=”pageactive”> <!-- 首页内容由 JS 动态渲染 --> <h1class=”text-3xlfont-bold”>欢迎来到我的个人站</h1> <pclass=”mt-2”>这里展示最新动态、推荐商品等。</p> <divid=”featured-products”class=”gridgrid-cols-1md:grid-cols-3gap-4mt-6”></div> </div> <divid=”products”class=”page”> <h2class=”text-2xlfont-boldmb-4”>所有商品</h2> <divid=”product-list”class=”gridgrid-cols-1md:grid-cols-3gap-4”></div> </div> <divid=”cart”class=”page”> <h2class=”text-2xlfont-boldmb-4”>购物车</h2> <divid=”cart-items”></div> <divclass=”mt-4text-right”> <spanclass=”text-xl”>总计:¥<spanid=”total-price”>0.00</span></span> <buttonid=”checkout-btn”class=”ml-4bg-green-500text-whitepx-6py-2roundedhover:bg-green-600”>去支付</button> </div> </div> <divid=”admin”class=”page”> <h2class=”text-2xlfont-boldmb-4”>后台管理</h2> <!-- 登录面板 --> <divid=”admin-login”> <inputtype=”password”id=”admin-pwd”placeholder=”管理密码”class=”borderp-2rounded” /> <buttonid=”admin-login-btn”class=”bg-blue-500text-whitepx-4py-2rounded”>登录</button> </div> <!-- 管理面板(登录后显示) --> <divid=”admin-panel”style=”display:none;”> <divclass=”flexspace-x-4mb-4”> <buttonclass=”tab-btn”data-tab=”add-product”>添加商品</button> <buttonclass=”tab-btn”data-tab=”manage-products”>管理商品</button> <buttonclass=”tab-btn”data-tab=”orders”>订单管理</button> </div> <divid=”tab-content”> <!-- 由 JS 动态加载 --> </div> </div> </div> </main> <!-- 支付弹窗 (用于跳转或扫码) --> <divid=”payment-modal”class=”fixedinset-0bg-blackbg-opacity-50flexitems-centerjustify-centerhidden”> <divclass=”bg-whitep-8rounded-lgmax-w-mdw-full”> <h3class=”text-xlfont-boldmb-4”>选择支付方式</h3> <divclass=”flexjustify-around”> <buttonclass=”pay-method”data-method=”wechat”><iclass=”fabfa-weixintext-green-600text-4xl”></i><br>微信</button> <buttonclass=”pay-method”data-method=”alipay”><iclass=”fabfa-alipaytext-blue-600text-4xl”></i><br>支付宝</button> <buttonclass=”pay-method”data-method=”qqpay”><iclass=”fabfa-qqtext-red-600text-4xl”></i><br>QQ钱包</button> </div> <buttonid=”close-payment”class=”mt-4bg-gray-300px-4py-2roundedw-full”>取消</button> </div> </div> <scripttype=”module”src=”/src/js/app.js”></script></body></html>

2. 前端核心逻辑 (frontend/src/js/app.js)

负责页面切换、商品加载、购物车管理、支付跳转、管理员登录等。

import { fetchProducts, createOrder, adminLogin, fetchOrders, updateOrderStatus } from './api.js';// ---------- 页面切换 ----------document.querySelectorAll('.nav-btn').forEach(btn => { btn.addEventListener('click'() => { const page = btn.dataset.page; document.querySelectorAll('.page').forEach(p => p.classList.remove('active')); document.getElementById(page).classList.add('active'); if (page === 'admin'checkAdminStatus(); });});// ---------- 加载商品 ----------async function loadProducts() { const products = await fetchProducts(); const container = document.getElementById('product-list'); container.innerHTML = products.map(p => ` <div class=”border p-4 rounded shadow”> <img src=”${p.image}” alt=”${p.name}” class=”w-full h-48 object-cover” /> <h3 class=”text-lg font-semibold mt-2”>${p.name}</h3> <p class=”text-gray-600”>¥${p.price}</p> <button class=”add-cart mt-2 bg-blue-500 text-white px-4 py-1 rounded” data-id=”${p.id}”>加入购物车</button> </div> `).join(''); // 绑定加入购物车事件 container.querySelectorAll('.add-cart').forEach(btn => { btn.addEventListener('click'() => addToCart(btn.dataset.id)); });}loadProducts();// ---------- 购物车 ----------let cart = [];function addToCart(productId) { // 实际从商品列表获取完整信息,此处简化 const product = products.find(p => p.id == productId); if (!product) return; const exist = cart.find(item => item.id == productId); if (exist) exist.quantity++; else cart.push({ ...product, quantity1 }); updateCartUI();}function updateCartUI() { document.getElementById('cart-count').textContent = cart.reduce((sum, i) => sum + i.quantity0); const container = document.getElementById('cart-items'); if (cart.length === 0) { container.innerHTML = '<p>购物车为空</p>'; document.getElementById('total-price').textContent = '0.00'; return; } container.innerHTML = cart.map(item => ` <div class=”flex justify-between border-b py-2”> <span>${item.name} × ${item.quantity}</span> <span>¥${(item.price * item.quantity).toFixed(2)}</span> <button class=”remove-cart text-red-500” data-id=”${item.id}”>删除</button> </div> `).join(''); const total = cart.reduce((sum, i) => sum + i.price * i.quantity0); document.getElementById('total-price').textContent = total.toFixed(2); // 删除事件 container.querySelectorAll('.remove-cart').forEach(btn => { btn.addEventListener('click'() => { cart = cart.filter(item => item.id != btn.dataset.id); updateCartUI(); }); });}// ---------- 支付流程 ----------document.getElementById('checkout-btn').addEventListener('click'async () => { if (cart.length === 0return alert('购物车为空'); // 弹出支付方式选择 document.getElementById('payment-modal').classList.remove('hidden');});document.querySelectorAll('.pay-method').forEach(btn => { btn.addEventListener('click'async () => { const method = btn.dataset.method; document.getElementById('payment-modal').classList.add('hidden'); // 调用后端创建订单 const orderData = { items: cart, total: cart.reduce((s, i) => s + i.price * i.quantity0), paymentMethod: method }; try { const result = await createOrder(orderData); // result 包含支付链接或二维码 if (result.payUrl) { // 跳转到支付平台(或打开新窗口) window.open(result.payUrl'_blank'); // 然后轮询订单状态,或等待支付回调通知 pollOrderStatus(result.orderId); } else { alert('支付发起失败'); } } catch (err) { alert('下单失败:' + err.message); } });});document.getElementById('close-payment').addEventListener('click'() => { document.getElementById('payment-modal').classList.add('hidden');});// 轮询订单状态(简化)async function pollOrderStatus(orderId) { const interval = setInterval(async () => { const orders = await fetchOrders(); const order = orders.find(o => o.id === orderId); if (order && order.status === 'paid') { clearInterval(interval); alert('支付成功!已发货'); cart = []; updateCartUI(); // 可跳转到订单详情 } }, 3000);}// ---------- 后台管理 ----------async function checkAdminStatus() { const token = localStorage.getItem('admin_token'); if (token) { document.getElementById('admin-login').style.display = 'none'; document.getElementById('admin-panel').style.display = 'block'; loadAdminPanel('add-product'); } else { document.getElementById('admin-login').style.display = 'block'; document.getElementById('admin-panel').style.display = 'none'; }}document.getElementById('admin-login-btn').addEventListener('click'async () => { const pwd = document.getElementById('admin-pwd').value; try { const token = await adminLogin(pwd); localStorage.setItem('admin_token', token); checkAdminStatus(); } catch { alert('密码错误'); }});// 管理标签切换document.querySelectorAll('.tab-btn').forEach(btn => { btn.addEventListener('click'() => { loadAdminPanel(btn.dataset.tab); });});async function loadAdminPanel(tab) { const container = document.getElementById('tab-content'); if (tab === 'add-product') { container.innerHTML = ` <h3 class=”font-bold”>添加商品</h3> <input id=”prod-name” placeholder=”名称” class=”border p-2 w-full mt-2” /> <input id=”prod-price” placeholder=”价格” type=”number” class=”border p-2 w-full mt-2” /> <input id=”prod-image” placeholder=”图片URL” class=”border p-2 w-full mt-2” /> <button id=”save-product” class=”mt-2 bg-blue-500 text-white px-4 py-2 rounded”>保存</button> `; document.getElementById('save-product').addEventListener('click'async () => { const name = document.getElementById('prod-name').value; const price = parseFloat(document.getElementById('prod-price').value); const image = document.getElementById('prod-image').value; await fetch('/api/product', { method'POST', headers: { 'Content-Type''application/json''Authorization''Bearer ' + localStorage.getItem('admin_token') }, bodyJSON.stringify({ name, price, image }) }); alert('商品添加成功'); loadProducts(); }); } else if (tab === 'manage-products') { const products = await fetchProducts(); container.innerHTML = products.map(p => ` <div class=”flex justify-between border-b py-2”> <span>${p.name} - ¥${p.price}</span> <button class=”delete-prod text-red-500” data-id=”${p.id}”>删除</button> </div> `).join(''); container.querySelectorAll('.delete-prod').forEach(btn => { btn.addEventListener('click'async () => { await fetch('/api/product/' + btn.dataset.id, { method'DELETE', headers: { 'Authorization''Bearer ' + localStorage.getItem('admin_token') } }); loadAdminPanel('manage-products'); loadProducts(); }); }); } else if (tab === 'orders') { const orders = await fetchOrders(); container.innerHTML = orders.map(o => ` <div class=”border-b py-2”> <div>订单 #${o.id} - 总价 ¥${o.total} - 状态:${o.status}</div> <button class=”ship-btn bg-green-500 text-white px-2 py-1 rounded” data-id=”${o.id}” ${o.status === 'paid' ? '' : 'disabled'}>发货</button> </div> `).join(''); container.querySelectorAll('.ship-btn').forEach(btn => { btn.addEventListener('click'async () => { await updateOrderStatus(btn.dataset.id'shipped'); loadAdminPanel('orders'); }); }); }}

3. API 封装 (frontend/src/js/api.js)

const API_BASE = '/api'// 在 Vercel 中会自动代理到云函数export async function fetchProducts() { const res = await fetch(`${API_BASE}/product`); return res.json();}export async function createOrder(orderData) { const res = await fetch(`${API_BASE}/order`, { method'POST', headers: { 'Content-Type''application/json' }, bodyJSON.stringify(orderData) }); if (!res.okthrow new Error('下单失败'); return res.json();}export async function adminLogin(password) { const res = await fetch(`${API_BASE}/auth`, { method'POST', headers: { 'Content-Type''application/json' }, bodyJSON.stringify({ password }) }); if (!res.okthrow new Error('登录失败'); const { token } = await res.json(); return token;}export async function fetchOrders() { const token = localStorage.getItem('admin_token'); const res = await fetch(`${API_BASE}/order`, { headers: { 'Authorization''Bearer ' + token } }); return res.json();}export async function updateOrderStatus(orderId, status) { const token = localStorage.getItem('admin_token'); await fetch(`${API_BASE}/order/${orderId}`, { method'PUT', headers: { 'Content-Type''application/json''Authorization''Bearer ' + token }, bodyJSON.stringify({ status }) });}

4. 后端云函数 (backend/api/)

4.1 数据库连接与模型 (backend/api/utils/db.js)

使用 MongoDB Atlas 免费层,通过 mongoose 连接。

import mongoose from 'mongoose';const MONGODB_URI = process.env.MONGODB_URI;if (!MONGODB_URIthrow new Error('请设置 MONGODB_URI 环境变量');let cached = global.mongoose;if (!cached) { cached = global.mongoose = { connnullpromisenull };}export async function connectDB() { if (cached.connreturn cached.conn; if (!cached.promise) { cached.promise = mongoose.connect(MONGODB_URI, { useNewUrlParsertrue, useUnifiedTopologytrue, }).then(mongoose => mongoose); } cached.conn = await cached.promise; return cached.conn;}// 定义 Schemaconst productSchema = new mongoose.Schema({ nameString, priceNumber, imageString, createdAt: { typeDatedefaultDate.now }});const orderSchema = new mongoose.Schema({ itemsArray, totalNumber, paymentMethodString, status: { typeStringdefault'pending' }, // pending, paid, shipped createdAt: { typeDatedefaultDate.now }});export const Product = mongoose.models.Product || mongoose.model('Product', productSchema);export const Order = mongoose.models.Order || mongoose.model('Order', orderSchema);

4.2 商品 API (backend/api/product.js)

import { connectDB, Product } from './utils/db.js';import { verifyAdmin } from './utils/auth.js';export default async function handler(req, res) { await connectDB(); if (req.method === 'GET') { const products = await Product.find().sort({ createdAt: -1 }); return res.json(products); } // 以下需要管理员权限 const admin = verifyAdmin(req); if (!admin) return res.status(401).json({ error'未授权' }); if (req.method === 'POST') { const { name, price, image } = req.body; const product = new Product({ name, price, image }); await product.save(); return res.json(product); } if (req.method === 'DELETE') { const { id } = req.query; await Product.findByIdAndDelete(id); return res.status(204).end(); } res.status(405).json({ error'Method not allowed' });}

4.3 订单与支付 API (backend/api/order.js)

这里集成 PayJS 聚合支付(支持微信、支付宝、QQ),只需注册 PayJS 获取商户号。

import { connectDB, Order } from './utils/db.js';import { verifyAdmin } from './utils/auth.js';import crypto from 'crypto';const PAYJS_MCHID = process.env.PAYJS_MCHID;const PAYJS_KEY = process.env.PAYJS_KEY;const PAYJS_API = 'https://payjs.cn/api/native'// 扫码支付export default async function handler(req, res) { await connectDB(); // 创建订单(用户端) if (req.method === 'POST') { const { items, total, paymentMethod } = req.body; // 1. 保存订单到数据库 const order = new Order({ items, total, paymentMethod, status'pending' }); await order.save(); // 2. 调用 PayJS 生成支付参数 const payData = { mchidPAYJS_MCHID, total_feeMath.round(total * 100), // 分 out_trade_no: order._id.toString(), body'商品订单', notify_url`${process.env.BASE_URL}/api/order/pay-callback`// 支付回调地址 }; // 生成签名 const sign = crypto.createHash('md5').update( Object.entries(payData) .sort(([a], [b]) => a.localeCompare(b)) .map(([k, v]) => `${k}=${v}`) .join('&') + `&key=${PAYJS_KEY}` ).digest('hex'); payData.sign = sign; const payRes = await fetch(PAYJS_API, { method'POST', headers: { 'Content-Type''application/x-www-form-urlencoded' }, bodynew URLSearchParams(payData) }); const payResult = await payRes.json(); if (payResult.return_code === 'SUCCESS') { // 返回支付二维码链接或跳转URL return res.json({ orderId: order._id, payUrl: payResult.qrcode// 或 payResult.code_url }); } else { return res.status(500).json({ error'支付网关错误' }); } } // 获取订单列表(管理员) if (req.method === 'GET') { const admin = verifyAdmin(req); if (!admin) return res.status(401).json({ error'未授权' }); const orders = await Order.find().sort({ createdAt: -1 }); return res.json(orders); } // 更新订单状态(发货) if (req.method === 'PUT') { const admin = verifyAdmin(req); if (!admin) return res.status(401).json({ error'未授权' }); const { id } = req.query; const { status } = req.body; await Order.findByIdAndUpdate(id, { status }); return res.json({ successtrue }); } res.status(405).end();}// 支付回调(异步通知)export async function callback(req, res) { // PayJS 会发送 POST 请求,需验证签名并更新订单状态 const { out_trade_no, total_fee, sign } = req.body; // 验证签名(省略,类似上述签名算法) // 如果验证通过,将订单状态改为 'paid' await Order.findByIdAndUpdate(out_trade_no, { status'paid' }); // 可触发邮件通知、库存扣除等 res.send('SUCCESS'); // PayJS 要求返回 SUCCESS}

注意:需要在 Vercel 中配置路由,将 /api/order/pay-callback 指向此回调函数(或单独写成 pay-callback.js)。

4.4 身份验证中间件 (backend/api/utils/auth.js)

export function verifyAdmin(req) { const token = req.headers.authorization?.split(' ')[1]; // 简单实现:固定密码比对,实际可用 JWT if (token === process.env.ADMIN_TOKENreturn true; return false;}

4.5 登录 API (backend/api/auth.js)

import { verifyAdmin } from './utils/auth.js';export default function handler(req, res) { if (req.method !== 'POST'return res.status(405).end(); const { password } = req.body; if (password === process.env.ADMIN_PASSWORD) { // 返回一个固定 token(演示) return res.json({ token: process.env.ADMIN_TOKEN }); } res.status(401).json({ error'密码错误' });}

四、部署到免费平台(Vercel + MongoDB Atlas)

1. 准备工作

  • 注册 MongoDB Atlas 免费集群,获取连接字符串。
  • 注册 PayJS 账号,获取商户号(mchid)和密钥。
  • 在 Vercel 上创建项目并关联 GitHub 仓库。

2. 环境变量设置

在 Vercel 项目设置中添加以下环境变量:

MONGODB_URI=你的MongoDB连接串PAYJS_MCHID=你的商户号PAYJS_KEY=你的密钥ADMIN_PASSWORD=你的管理密码(如 admin123)ADMIN_TOKEN=任意JWT或固定字符串(用于前端请求头)BASE_URL=你的Vercel部署域名(如 https://my-site.vercel.app)

3. 项目配置

在项目根目录创建 vercel.json 来指定云函数路径:

{ ”functions”: { ”api/*.js”: { ”runtime”: ”nodejs18.x” } }, ”rewrites”: [ { ”source”: ”/(.*)”, ”destination”: ”/frontend/public/index.html” } ]}

4. 部署

  • 将代码推送到 GitHub。
  • 在 Vercel 中导入该仓库,自动部署。
  • 前端页面将运行在 https://你的域名.vercel.app,后端 API 在 https://你的域名.vercel.app/api/...

五、功能演示与说明

用户端:

  • 浏览商品、加入购物车、下单支付。
  • 支付方式选择微信、支付宝、QQ钱包,点击后弹出 PayJS 的二维码或跳转支付页面。
  • 支付成功后,前端轮询订单状态,显示支付成功并自动“发货”(在演示中只是状态变化)。

管理端:

  • 登录(输入预设密码)。
  • 添加/删除商品。
  • 查看所有订单,点击“发货”按钮更新订单状态(模拟发货)。

响应式设计:

  • 基于 Tailwind CSS,在移动、平板、桌面设备上自适应。

六、重要提醒

  1. 支付功能需要真实商户号
    PayJS 为聚合支付服务商,申请后即可使用,不需要服务器,费用较低。如果仅做演示,可使用 PayJS 的测试模式(但需要配置测试参数)。
  2. 安全注意
    上述代码中的管理员验证采用固定 token,生产环境应改用 JWT + 过期时间。支付回调需要严格验证签名,防止伪造。
  3. 免费额度
    Vercel 提供每月 100GB 流量和 1000 个云函数调用(足够个人站),MongoDB Atlas 免费层提供 512MB 存储。

由于无法直接在对话中提供文件,您可以根据上述代码框架自行创建项目。

如果您需要一键下载的压缩包,可以自行将上述代码保存为文件,或参考 GitHub 上的类似开源项目(如 nodejs-payjs-demo 等)进行整合。


通过此部署方案,您将会拥有了一个专属自己的完全免费、无需购买第三方服务器个人多功能单页网站,包含了完整的管理后台和三合一支付发货流程。

👆以上AI回复的需要重新整理扩展更多细节和对应的源代码,然后才能进行测试,你最好是让龙虾帮你动手操作,写学会自己部署龙虾到你电脑里实现拥有自己的免费劳工,带货链接如下👇