资讯动态

壹度同城v2.0.3小程序源码深度解析与工程化落地指南

发布时间:2026/10/27 19:05:35 来源:尧图企业网站定制
简介本资源为壹度同城新零售v2.0.3小程序源码包面向中小型零售商家、微信生态开发者及PHP小程序全栈学习者提供开箱即用的新零售业务落地解决方案。源码支持商品展示、在线下单、订单管理、物流跟踪等核心功能并新增自定义站点版权与多站点独立Logo配置能力便于品牌化快速部署。压缩包共2000个文件以505个PHP后端逻辑文件、244个JS交互脚本、163个WXSS样式文件、115个JSON配置及112个WXML页面结构为主辅以PNG/JPG图片资源与HTML/SCSS等辅助文件整体体积21.83MB结构完整、模块清晰适合作为二次开发或教学分析样本。目前已有51人学习下载读者可直接获取含Gocon.bat自动化脚本、H-ui与Bootstrap双CSS框架集成、表单配置与动画效果等实用工程实践细节具备较强的学习参考与商用适配价值。1. 壹度同城新零售v2.0.3小程序源码不是“拿来即用”的压缩包而是需拆解重构的业务黑匣子你下载到壹度同城新零售v2.0.3小程序源码下载.zip解压后看到project.config.json、app.js、pages/和一堆.wxml/.wxss/.js文件——这确实是一套完整可编译的微信小程序工程但它绝非开箱即用的成品系统。真实情况是这套 v2.0.3 源码承载着典型区域型同城零售的复杂逻辑——多门店库存协同、骑手调度状态机、用户LBS动态定价、微信支付余额优惠券三重核销路径以及最关键的「微信小程序登录获取手机号」强依赖链。它不是 demo而是上一轮交付给某地级市商超联盟的真实生产版本注意不是2048-小程序.zip那种教学玩具。新手直接npm install 构建会卡在wx.login()后无法拉取手机号熟手则要立刻判断它的cloudfunctions是否已绑定你自己的云开发环境miniprogram_npm里axios是不是被魔改过以绕过微信域名校验更现实的问题是——它没文档没接口清单没数据库 ER 图只有代码。适合两类人一是正接手该系统二次开发的外包工程师需要快速厘清边界、避开历史坑二是想学习“如何把一个真实新零售小程序从源码读懂到可控”的技术负责人。本文不讲“怎么安装开发者工具”只讲怎么把这坨 v2.0.3 源码变成你能改、能测、能上线的活系统。2. 解构 v2.0.3 工程结构从project.config.json到cloudfunctions的三层依赖链壹度同城 v2.0.3 并非纯前端小程序而是典型的「前端 云开发函数 第三方服务」混合架构。它的生命力不在pages/index/index.wxml而在cloudfunctions/目录下那 17 个云函数以及miniprogram/utils/request.js中被深度定制的请求拦截器。理解这三层关系是避免后续所有翻车的前提。2.1 第一层小程序主工程配置与入口逻辑project.config.json与app.jsproject.config.json不只是开发者工具配置它锁定了整个项目的运行时契约{ description: 壹度同城新零售v2.0.3, setting: { urlCheck: true, es6: true, enhance: true, postcss: true, minified: true, newFeature: true, coverView: true, nodeModules: true, autoAudits: false, showShadowRootInWxmlPanel: true, scopeDataCheck: false, uglifyFileName: false, compileHotReLoad: false, useMultiFrameRuntime: true, useApiHook: true }, miniprogramRoot: ./miniprogram/, cloudfunctionRoot: ./cloudfunctions/, extensionConfig: { wechat-miniprogram-plugin: { enable: true } } }关键参数说明useMultiFrameRuntime: true表明此项目已启用微信小程序多线程渲染Worker这意味着pages/order/create.js中的地址选择、商品计算等耗时操作被剥离到 Worker 线程不能直接在 Page 实例中调用wx.getSystemInfoSync()等同步 APInodeModules: true且miniprogram/package.json存在说明项目使用了miniprogram_npm构建流程utils/request.js依赖的axios0.21.4是通过npm install --production安装后构建 npm生成的不是直接引用 CDNcloudfunctionRoot: ./cloudfunctions/是硬编码路径若你本地未初始化云开发环境或路径错位wx.cloud.callFunction必然fail: errCode: -404011。app.js的onLaunch是业务起点它不只做初始化还埋了关键钩子App({ onLaunch() { // 1. 检查基础库版本v2.0.3 要求 2.25.0 const version wx.getSystemInfoSync().SDKVersion; if (this._compareVersion(version, 2.25.0) 0) { wx.showToast({ title: 请升级微信至最新版本, icon: none }); return; } // 2. 初始化云开发必须否则所有云函数调用失败 wx.cloud.init({ env: prod-xxxxx, // 注意此处是环境 ID不是字符串 prod traceUser: true }); // 3. 尝试静默登录但 v2.0.3 的设计是此处只存 openid手机号获取延后到首页触发 this._loginSilent(); }, _loginSilent() { wx.login({ success: res { // 仅将 code 发给 /login/code2session 云函数换 openid不换手机号 wx.cloud.callFunction({ name: login, data: { code: res.code } }).then(r { wx.setStorageSync(openid, r.result.openid); }); } }); } });这段代码揭示了 v2.0.3 的核心设计哲学登录态分两步openid 静默获取手机号显式授权。这是为满足《个人信息保护法》对“最小必要原则”的落地——用户首次进入首页时才弹出button open-typegetPhoneNumber获取手机号而非启动即索取。这也是为什么直接运行会卡在首页空白pages/index/index.js的onLoad里有this._checkPhoneAuth()它检测wx.getStorageSync(phone)为空时会wx.navigateTo({ url: /pages/auth/phone })而/pages/auth/phone页面的bindgetphonenumber事件处理器才是真正的手机号获取入口。2.2 第二层云函数集群cloudfunctions/——业务逻辑的真正心脏cloudfunctions/下共 17 个函数按职责分为三类函数名类型关键作用依赖项loginHTTP 触发code 换 openid session_key无userHTTP 触发用户信息增删改查、手机号绑定login返回的 session_keyorderHTTP 触发创建订单、查询订单、取消订单user、goods、storegoodsHTTP 触发商品上下架、库存扣减、价格计算store、couponstoreHTTP 触发门店信息、LBS 半径内门店筛选geo腾讯位置服务couponHTTP 触发优惠券发放、核销、过期清理user、orderdelivery定时触发每 5 分钟扫描待接单订单推送给骑手order、user骑手角色血泪经验delivery函数是 v2.0.3 最易翻车的点。它依赖wx.cloud.database().collection(orders).where({ status: pending })查询但 v2.0.3 的orders集合 schema 中status字段是字符串而部分旧订单因历史 bug 写入了pendding多一个 d。云函数不会报错但这些订单永远无人接单。修复方法是在delivery/index.js的查询条件中加容错const pendingOrders await db.collection(orders).where( _.or([ { status: pending }, { status: pendding } // 兼容历史脏数据 ]) ).get();所有云函数均采用统一的错误处理模板cloudfunctions/common/error.js// cloudfunctions/common/error.js class BizError extends Error { constructor(code, message, data {}) { super(message); this.code code; // 业务码如 1001库存不足1002地址超配送范围 this.data data; } } module.exports { BizError };这意味着你在小程序端wx.cloud.callFunction({ name: order })的fail回调里拿到的err.errCode是微信云开发错误码如 -404011而err.result才是真正的业务错误对象其code字段来自BizError。新手常误把err.errCode当作业务错误码导致所有库存不足提示都显示“网络错误”。2.3 第三层第三方服务集成utils/third-party.js——微信生态的隐性枷锁v2.0.3 深度耦合微信原生能力utils/third-party.js封装了三处关键集成微信支付调用wx.requestPayment前先调用cloudfunctions/pay/prepay云函数生成package参数。该函数校验order_id合法性、检查库存、锁定库存Redis、生成prepay_id全程在云函数内完成事务避免小程序端篡改金额。微信地图腾讯位置服务utils/map.js封装了wx.getLocationwx.cloud.callFunction({ name: geo, data: { lat, lng } })双重校验。geo函数调用腾讯geocoderAPI 反向解析地址并比对stores集合中各门店的geo_radius字段返回半径内可配送门店列表。注意geo函数的data必须含lat和lng且单位为 WGS84 坐标系微信wx.getLocation返回的是 GCJ-02需调用utils/coord.js转换。微信消息订阅subscribeMessage下单成功后调用wx.requestSubscribeMessage请求用户授权再调用cloudfunctions/message/send推送模板消息。v2.0.3 使用的是TEMPLATE_ID_ORDER_SUCCESS模板其data字段严格匹配pages/order/detail?idxxx的跳转链接若你修改了订单详情页路径模板消息将失效且无任何报错提示。这三层结构不是并列关系而是强依赖链小程序页面 → 云函数 → 第三方 API。任何一层断裂都会导致功能不可用。理解它才能知道该在哪一层 debug。3. 本地调试与真机联调绕过wx.login()和getPhoneNumber的玄学验证v2.0.3 的登录与授权逻辑是调试最大障碍。微信开发者工具的模拟器无法触发getPhoneNumber真机又受限于wx.login()的code有效期5 分钟和getPhoneNumber的encryptedData解密密钥session_key。直接跑通首页需要一套组合拳。3.1 开发者工具内绕过登录注入 mock 数据 修改云函数响应目标让pages/index/index.js的onLoad不再等待this._checkPhoneAuth()直接进入主逻辑。步骤 1Mock 用户数据在miniprogram/app.js的onLaunch结束前插入 mock// app.js onLaunch 末尾添加 if (process.env.NODE_ENV development) { // 开发环境强制注入测试用户 wx.setStorageSync(openid, oABC1234567890abcdef123456789); wx.setStorageSync(phone, 13800138000); wx.setStorageSync(userInfo, { nickName: 测试用户, avatarUrl: https://example.com/avatar.png }); }步骤 2修改云函数user的响应找到cloudfunctions/user/index.js在exports.main的switch (event.action)分支中为getProfile添加开发模式 bypasscase getProfile: if (process.env.NODE_ENV development) { return { code: 0, data: { phone: 13800138000, nickname: 测试用户, avatar: https://example.com/avatar.png, balance: 120.5 } }; } // 原有逻辑...步骤 3禁用getPhoneNumber组件的真机限制在pages/auth/phone.wxml中将button open-typegetPhoneNumber替换为!-- 开发环境用 input 模拟 -- view wx:if{{env dev}} input bindinputonPhoneInput placeholder输入手机号 / button bindtaponConfirmPhone确认/button /view !-- 生产环境保留原 button -- button wx:else open-typegetPhoneNumber bindgetphonenumberonGetPhoneNumber获取手机号/button并在pages/auth/phone.js的onLoad中设置envonLoad() { this.setData({ env: wx.getEnv ? wx.getEnv().ENV_VERSION : release }); }, onConfirmPhone() { wx.setStorageSync(phone, this.data.phoneInput); wx.navigateBack(); // 模拟授权成功 }这样开发者工具内即可跳过所有授权环节直抵业务逻辑层。3.2 真机联调抓包定位getPhoneNumber失败根源当开发者工具跑通真机却卡在getPhoneNumber的fail回调时问题必在encryptedData解密环节。此时需用Charles 抓包微信小程序注意不是抓包浏览器是抓包微信客户端。Charles 配置要点针对 v2.0.3微信客户端需开启「设置 通用 发现页管理 关闭“发现页”」防止干扰手机与电脑在同一局域网手机 Wi-Fi DNS 设为 Charles 代理 IPCharles 的Proxy SSL Proxying Settings中添加*.weixin.qq.com和*.tencent.com微信客户端需手动安装 Charles 根证书访问chls.pro/ssl下载并信任在 Charles 的Structure标签页过滤cloud.weixin.qq.com找到POST /tcb/cloudapi/function/invoke请求查看请求体data字段确认encryptedData和iv是否为空或格式错误常见于用户未点击授权按钮即触发bindgetphonenumber查看响应体若result.code为40001说明session_key已过期需重新wx.login()若result.code为40002说明encryptedData与iv不匹配通常是button组件未正确绑定事件或bindgetphonenumber事件未触发。避坑小程序抓包的三个致命误区误区一用 Fiddler 抓包→ Fiddler 对微信小程序支持极差SSL 握手常失败Charles 是事实标准误区二抓包时未关闭「自动重定向」→ 微信云函数调用会 302 重定向到真实云函数地址Charles 默认跟随导致看不到原始请求体务必在Proxy Recording Settings中取消勾选Follow redirects误区三认为encryptedData是 Base64 编码→ 它是 UTF-8 字节流的 Base64解密时需用Buffer.from(encryptedData, base64)而非atob()否则中文字符乱码。3.3 云开发环境初始化env与region的隐形绑定v2.0.3 的wx.cloud.init中env: prod-xxxxx是硬编码但prod-xxxxx这个环境 ID 必须与你的云开发控制台中创建的环境完全一致且地域region必须匹配。微信云开发分ap-guangzhou广州、ap-shanghai上海、ap-beijing北京三地prod-xxxxx的后缀xxxxx隐含地域信息。验证方法登录 云开发控制台 查看你的环境 ID在控制台右上角确认当前地域是否与project.config.json中cloudfunctionRoot的部署地域一致若不一致wx.cloud.callFunction会返回errCode: -404011环境不存在而非errCode: -404001函数不存在。解决方案方案 A推荐在云开发控制台新建一个与prod-xxxxx同名的环境并确保地域一致方案 B修改app.js中wx.cloud.init的env为你实际的环境 ID同时修改所有云函数config.json中的envId字段方案 C用 CLI 部署时指定地域tcb cloudfunction deploy order --region ap-guangzhou。注意tcbCLI 的--region参数必须与控制台环境地域严格一致否则部署成功但调用失败且错误日志中无明确提示只能靠errCode猜。4. 关键业务模块复现从「微信小程序登录获取手机号」到「订单创建」的端到端链路v2.0.3 的核心价值在于其真实业务闭环。我们以「用户授权手机号 → 加入购物车 → 创建订单」为线索还原代码级实现这不是 API 文档而是可抄作业的链路。4.1 微信小程序登录获取手机号buttoncloudfunctions/user/bindPhone这是合规前提v2.0.3 的实现比官方示例更健壮。前端pages/auth/phone.wxml!-- 必须用 button 组件且 open-typegetPhoneNumber -- button classauth-btn open-typegetPhoneNumber bindgetphonenumberonGetPhoneNumber disabled{{isGetting}} {{ isGetting ? 授权中... : 一键授权手机号 }} /button前端pages/auth/phone.jsonGetPhoneNumber(e) { if (e.detail.code) { this.setData({ isGetting: true }); // 将 code 和 encryptedData 一起发给云函数 wx.cloud.callFunction({ name: user, data: { action: bindPhone, code: e.detail.code, encryptedData: e.detail.encryptedData, iv: e.detail.iv } }).then(res { if (res.result.code 0) { wx.setStorageSync(phone, res.result.data.phone); wx.showToast({ title: 授权成功, icon: success }); setTimeout(() wx.navigateBack(), 1000); } else { throw new Error(res.result.message); } }).catch(err { console.error(bindPhone fail:, err); wx.showToast({ title: 授权失败请重试, icon: none }); this.setData({ isGetting: false }); }); } else { // 用户拒绝授权 wx.showToast({ title: 请允许获取手机号, icon: none }); } }云函数cloudfunctions/user/index.jsconst cloud require(wx-server-sdk); cloud.init(); const db cloud.database(); const crypto require(crypto); exports.main async (event, context) { const { action, code, encryptedData, iv } event; if (action bindPhone) { try { // 1. 用 code 换取 session_key调用微信 auth.code2Session const wxRes await cloud.http.post(https://api.weixin.qq.com/sns/jscode2session, { method: GET, data: { appid: cloud.getWXContext().APPID, secret: YOUR_SECRET_HERE, // 此处应从云开发环境变量读取v2.0.3 硬编码在 config.json js_code: code, grant_type: authorization_code } }); if (wxRes.data.errcode) { throw new BizError(2001, code2Session 失败: wxRes.data.errmsg); } const { session_key } wxRes.data; // 2. 解密 encryptedData const pc new cloud.crypto.PKCS7Encoder(); const decipher crypto.createDecipheriv(aes-128-cbc, session_key, iv); let decoded decipher.update(encryptedData, base64, utf8); decoded decipher.final(utf8); decoded pc.unpad(decoded); const phoneObj JSON.parse(decoded); const { phoneNumber } phoneObj; // 3. 更新用户表假设 user 表以 openid 为主键 const openid cloud.getWXContext().OPENID; await db.collection(users).doc(openid).update({ data: { phone: phoneNumber, updated_at: new Date() } }); return { code: 0, data: { phone: phoneNumber } }; } catch (err) { console.error(bindPhone error:, err); return { code: 2002, message: 手机号绑定失败 }; } } };参数说明与踩坑点secret必须是你小程序的 AppSecretv2.0.3 源码中硬编码在cloudfunctions/user/config.json的secret字段切勿上传到 GitHubcloud.crypto.PKCS7Encoder是微信云开发内置的 PKCS7 填充解码器不能用 Node.js 原生crypto的unpad方法否则解密失败encryptedData是 Base64 字符串crypto.createDecipheriv的update方法第二个参数必须是base64第三个参数必须是utf8顺序错则乱码。4.2 加入购物车miniprogram/pages/cart/index.js的原子操作v2.0.3 的购物车是云数据库实时同步非本地缓存。关键逻辑// pages/cart/index.js addToCart(goodsId, quantity 1) { const cartItem { goods_id: goodsId, quantity: quantity, added_at: new Date() }; // 1. 先查用户购物车是否存在该商品 wx.cloud.database().collection(cart).where({ _openid: wx.getStorageSync(openid), goods_id: goodsId }).get().then(res { if (res.data.length 0) { // 2. 存在则更新 quantity wx.cloud.database().collection(cart).doc(res.data[0]._id).update({ data: { quantity: _.add(res.data[0].quantity, quantity) } }); } else { // 3. 不存在则新增 wx.cloud.database().collection(cart).add({ data: { ...cartItem, _openid: wx.getStorageSync(openid) } }); } }); }避坑云数据库的_openid自动注入陷阱v2.0.3 的cart集合开启了「添加记录时自动注入_openid」但wx.cloud.database().collection(cart).add()时若显式传入_openid会覆盖自动注入值。若你本地测试时wx.getStorageSync(openid)是 mock 值则购物车数据将写入错误用户下。正确做法是移除add时的_openid字段依赖云数据库自动注入。4.3 创建订单cloudfunctions/order/create的分布式事务模拟v2.0.3 用云函数 Redis 实现准事务非 ACID但足够业务可用。云函数cloudfunctions/order/create/index.jsconst cloud require(wx-server-sdk); cloud.init(); const db cloud.database(); const redis require(redis); // v2.0.3 使用了 redis 云函数扩展 exports.main async (event, context) { const { cartItems, address, payType } event; const openid cloud.getWXContext().OPENID; // 1. 生成订单号时间戳随机数 const orderId OD${Date.now()}${Math.floor(Math.random() * 1000)}; // 2. 锁定库存Redis setnx const redisClient redis.createClient(process.env.REDIS_URL); const lockKeys cartItems.map(item stock_lock:${item.goods_id}); const lockResult await redisClient.msetnx(...lockKeys.map(k [k, 1])); if (!lockResult) { throw new BizError(3001, 库存已被抢购请刷新重试); } try { // 3. 扣减库存云数据库事务 const transaction db.transaction(); const goodsCollection transaction.collection(goods); const orderCollection transaction.collection(orders); for (const item of cartItems) { const goods await goodsCollection.doc(item.goods_id).field({ stock: true }).get(); if (goods.data.stock item.quantity) { throw new BizError(3002, 商品 ${item.goods_id} 库存不足); } await goodsCollection.doc(item.goods_id).update({ data: { stock: _.sub(goods.data.stock, item.quantity) } }); } // 4. 创建订单 await orderCollection.add({ data: { _id: orderId, user_openid: openid, items: cartItems, address: address, status: pending, created_at: new Date(), total_amount: calcTotal(cartItems), pay_type: payType } }); await transaction.commit(); // 5. 清除 Redis 锁 await redisClient.del(...lockKeys); return { code: 0, data: { order_id: orderId } }; } catch (err) { // 6. 回滚释放 Redis 锁 await redisClient.del(...lockKeys); throw err; } };关键设计点Redis 锁是第一道防线防止超卖msetnx原子操作保证多个请求同时抢同一商品时只有一个能成功云数据库事务是第二道防线确保扣库存与建订单原子性但微信云开发事务不支持跨集合回滚所以goods和orders更新必须在同一事务内calcTotal函数在cloudfunctions/common/utils.js中它会根据goods集合中的price和coupon集合中的活动规则实时计算不是前端传入的金额防篡改。这条链路跑通意味着你已掌控 v2.0.3 的核心脉搏。5. 避坑指南壹度同城 v2.0.3 源码的 5 个血泪教训v2.0.3 是真实生产环境打磨出来的代码它的坑不是设计缺陷而是业务妥协的痕迹。以下是我接手三个同类项目后总结出的最痛的 5 条。5.1 现象首页wx:for渲染商品列表时白屏Console 无报错原因pages/index/index.js的onLoad中调用了this.getGoodsList()该方法内wx.cloud.database().collection(goods).where({ status: on }).orderBy(sort, asc).get()返回的数据其sort字段为null或undefined而orderBy(sort, asc)在云数据库中遇到null会静默失败返回空数组。解决在云数据库goods集合的索引管理中为status和sort字段创建复合索引并在where条件中排除sort为null的记录.where({ status: on, sort: _.neq(null) }).orderBy(sort, asc)5.2 现象用户修改收货地址后再次下单仍用旧地址原因pages/order/create.js的onLoad中this.getAddress()从云数据库addresses集合查询is_default: true的地址但 v2.0.3 的addresses集合设计允许多个is_default: true导致get返回多个地址[0]取第一个而这个“第一个”不一定是最新设为默认的。解决修改查询逻辑按updated_at倒序取第一个db.collection(addresses).where({ _openid: openid, is_default: true }).orderBy(updated_at, desc).limit(1).get()5.3 现象骑手端pages/delivery/list.js的订单列表不刷新原因onShow中使用的wx.cloud.watch监听orders集合但 v2.0.3 的watch配置中query为{ status: pending }而骑手接单后订单状态变为acceptedwatch不会触发导致列表不更新。解决watch的query应改为监听骑手本人相关的所有状态wx.cloud.watch({ collection: orders, query: { delivery_openid: openid // 骑手 openid 字段 } })5.4 现象小程序wx.downloadFile下载图片失败返回403原因v2.0.3 的商品图片存储在腾讯云 COS但miniprogram/utils/request.js中的downloadImage方法直接拼接了https://bucket-1250000000.cos.ap-guangzhou.myqcloud.com/xxx.jpg而 COS 的 bucket 开启了防盗链Referer头不匹配时拒绝访问。解决所有图片 URL 必须通过cloudfunctions/file/getSignedUrl云函数生成带签名的临时 URLwx.cloud.callFunction({ name: file, data: { action: getSignedUrl, fileKey: goods/123.jpg } }).then(res { wx.downloadFile({ url: res.result.url, ... }) });5.5 现象uniapp 微信小程序打包后wx.getSystemInfoSync().model返回iPhone而非具体型号导致 LBS 定位精度异常原因v2.0.3 的utils/location.js中对 iOS 设备做了特殊处理if (model.includes(iPhone)) { accuracy 100; }但uniapp打包后model字段被uni-appruntime 覆盖为iPhone丢失了iPhone13,3等具体信息。解决放弃依赖model字段改用wx.getSystemInfoSync().platformios/android和wx.getSystemInfoSync().systemiOS 15.4组合判断或直接移除 iOS 精度降级逻辑因为微信基础库 2.25.0 已统一高精度定位。6. 进阶技巧用 Python 脚本自动化检测 v2.0.3 源码的 3 类安全风险源码交付后不能只靠人工 review。我写了一个v2.0.3-security-scan.py脚本5 分钟内扫出硬编码密钥、HTTP 明文请求、云函数权限漏洞。它不替代专业渗透测试但能拦住 80% 的低级错误。6.1 扫描硬编码敏感信息AppSecret、Redis 密码、COS SecretId脚本遍历cloudfunctions/下所有.js文件用正则匹配import re import os def scan_secrets(root_dir): patterns [ (r(appid|app_id|APPID|APP_ID)\s*[:]\s*[\]([a-zA-Z0-9]{16,})[\], AppID), (r(secret|app_secret|SECRET|APP_SECRET)\s*[:]\s*[\]([a-zA-Z0-9]{24,})[\], AppSecret), (r(redis_url|REDIS_URL)\s*[:]\s*[\]redis://:[^][^]:\d[\], Redis URL with password), (r(cos_secretid|COS_SECRETID)\s*[:]\s*[\]([A-Za-z0-9/]{32,})[\], COS SecretId) ] results [] for dirpath, _, filenames in os.walk(root_dir): for filename in filenames: if filename.endswith(.js): p a hrefhttps://download.csdn.net/download/m0_72763148/90649595 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑