首页 > 编程语言 >uni-app小程序(快手)日志打印坑位记录

uni-app小程序(快手)日志打印坑位记录

时间:2024-08-27 11:17:02浏览次数:8  
标签:refund obj 快手 app id return uni null order

前情

uni-app是我比较喜欢的跨平台框架,它能开发小程序/H5/APP(安卓/iOS),重要的是对前端开发友好,自带的IDE让开发体验也挺棒的,公司项目就是主推uni-app。

坑位

最近在开发一需求,页面上的内容需要根据当前主查询接口返回的某一个字段A是否为null来做接口轮询,直到它获取到非null的真正内容,在开发者工具一切都正常,但在真机快手小程序上测试时并没有触发页面接口轮询,导致页面数据显示异常。

于是我通过小程序控制台查看,发现确实字段A是非null值,但又不是接口文挡上注明的值,我开始怀疑是服务端数据返回问题,把截图甩给服务端说数据返回不太对,服务端向我要了请求参数后,他通过postman模拟请求,说数据是对的,我在小程序开发者工具控制台上看了接口数据确实也是对的,重新测了真机确实是不行的,因为项目我是中间接手的,我怀疑是不是代码请求的封装方法中有什么骚操作,于是仔细review了一遍通用请求封装的方法,除了找到一个可以优化的点外,并没有发现有什么不妥当的地方。

Why?

我猜应该是快手小程序的vConsole在日志打印不知道做了什么操作修改了对象中字段为null的数据,目前发现的是null会被替换为当前传入的整个对象,无限循环下去,导致页面获取不到接口返回的原始数据,导致功能异常。于是我在快手小程序论坛提了贴子,反映了目前遇到的问题,链接:开发小程序日志输出异常 (kuaishou.com)

几小时后官方就给了我回复说,没有重现出来,我于是新建一个最小项目,重现了下问题,最小示例项目很简单就是一个页面,纯打印我项目中接口返回的测试数据日志:

<template>
	<view class="content">
		<view class="text-area">
			首页
		</view>
		<button @click="log">输出日志</button>
	</view>
</template>

<script setup>
let logObj = {
    "status": "success",
    "code": 200,
    "message": "操作成功",
    "data": {
        "order": {
            "id": 21184,
            "platform": 9,
            "order_no": "662955300914989888",
            "order_mode": 1,
            "state": 11,
            "cancel_status": 441,
            "address_id": 685,
            "shop_id": 0,
            "user_id": 464,
            "payment_funder_mark": "YUE_RONG_ZHONG_KE",
            "source_platform": 2,
            "source_order_no": "",
            "capital_order_id": "3252408100001353",
            "product_id": 11211,
            "sku_id": 28081,
            "id_card_name": "泽城",
            "id_phone": "16249235181",
            "id_card_number": "451581199711097777",
            "security_id": 0,
            "exception_type": 0,
            "risk_decision": 0,
            "total_price": "30.00",
            "first_actual_payment_amount": "1.25",
            "first_payment_rent_payable": "1.25",
            "deposit_total_amount": "10.00",
            "deposit_discount_type": 0,
            "deposit_free_amount": "0.00",
            "deposit_recovery_deduction_amount": "0.00",
            "deposit_actual_amount": "0.00",
            "total_rent": "30.00",
            "buy_out_price": "1.00",
            "buy_out": 0,
            "repaid_amount": "10.00",
            "schemes": 3,
            "lease_days": 720,
            "repayment_periods": 24,
            "courier_number": "",
            "esign_sign_flow_id": "",
            "esign_state": 2,
            "esign_face_flow_id": "",
            "esign_face_state": 0,
            "age": 26,
            "state_exception_note": "",
            "note": "",
            "creator": "",
            "created_at": "2024-08-10 17:55:48",
            "updated_at": "2024-08-10 18:14:15",
            "lease_start_time": "2024-08-14 00:00:00",
            "lease_end_time": "2026-08-04 00:00:00",
            "user_bound_at": null,
            "first_shared_at": null,
            "esign_finish_at": null,
            "task_order_at": "2024-08-10 17:55:48",
            "deleted_at": null,
            "serial_number": "",
            "cancellation_reason": null,
            "sn": "202408108001",
            "contract_file": "/contact/12/18/e38154fbb9ac9308b66e336a01e69a23.pdf",
            "overdue_state": 0,
            "order_process": 1,
            "rent_price_model": 2,
            "payment_mode": 4,
            "conversion_method": 1,
            "deposit_switch": 2,
            "deposit_payment_process": 0,
            "risk_result": 0,
            "sync_supply_chain_time": "2024-08-10 17:58:56",
            "complete_sub_status": 0,
            "verify_delivery_address": 0,
            "cancel_express_status": 2,
            "shipping_phone": "13249235081",
            "source_platform_text": "快手",
            "state_text": "已关闭"
        },
        "order_apply_refund_amount": "0.00",
        "order_refund_examine": {
            "id": 2962,
            "order_no": "662955300914989888",
            "order_state": 4,
            "state": 2,
            "refund_type": 2,
            "refund_reason": 0,
            "audit_time": "2024-08-10 18:14:12",
            "user_id": 25,
            "remark": "订单退货退款",
            "reason": "首付太高",
            "deduction_amount": "0.00",
            "deduction_reason": 0,
            "created_at": "2024-08-10 18:11:27",
            "updated_at": "2024-08-10 18:14:16",
            "refund_receive_state": 2,
            "refunded_at": "2024-08-10 18:14:16",
            "examine_no": "SHTH2024081062424559",
            "process": "PASSED",
            "category": 1,
            "mode": 2,
            "force_source_platform": 0,
            "force_out_order_no": "",
            "refund_process": "DEFAULT",
            "refund_return_process": "ALREADY_IN_STOCK",
            "refund_return_courier_number": "SF100862",
            "refund_return_consignee_phone": "13249235081",
            "refund_return_device_expired_time": "2024-08-16 18:12:10",
            "refund_return_device_expired_expend_times": 0,
            "refund_return_express_records": null,
            "refund_return_audit_state": 1,
            "refund_return_audit_time": "2024-08-10 18:12:10",
            "refund_return_reship_consignee_name": "",
            "refund_return_reship_consignee_phone": "",
            "refund_return_reship_consignee_address": "",
            "refund_return_reship_courier_number": "",
            "refund_return_reship_express_records": null,
            "user_remark": "",
            "refund_return_tips": {
                "return_express_tip_info": "请选用顺丰快递(货到付款)",
                "return_address_tip_info": "18098965084 深圳市福田区世界中心2楼201"
            }
        },
        "is_order_refunded": 1,
        "is_order_allow_apply_refund": 0
    },
    "error": {}
};
const log = () => {
	console.log('---- log ----:', logObj.data.order_refund_examine.refund_return_express_records, logObj);
}
</script>

<style>

</style

解决方案

  1. 注释掉日志输出代码(最直接)
  2. 打印日志的时候打印到特定你想知道的key,或者你想知道的KEY的父级对象,测试中发现层级在一二级不会有问题
  3. 打印前通过JSON.stringify转化为字符串输出(对象较大的时候很难找到想要看到的key的值)
  4. 深拷贝后再输出,虽然打印的日志是错的,但是不会影响原始值,至少页面上拿到的是正确的值,在项目主入口main.js中增加如下代码重写console.log方法是可行的,同时还帮处理了生产环境让所有log方法失效
const log = console.log;

/**
 * @description 深度克隆
 * @param {object} obj 需要深度克隆的对象
 * @param cache 缓存
 * @returns {*} 克隆后的对象或者原值(不是对象)
 */
function deepClone(obj, cache = new WeakMap()) {
	if (obj === null || typeof obj !== 'object') return obj;
	if (cache.has(obj)) return cache.get(obj);
	let clone;
	if (obj instanceof Date) {
		clone = new Date(obj.getTime());
	} else if (obj instanceof RegExp) {
		clone = new RegExp(obj);
	} else if (obj instanceof Map) {
		clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)]));
	} else if (obj instanceof Set) {
		clone = new Set(Array.from(obj, value => deepClone(value, cache)));
	} else if (Array.isArray(obj)) {
		clone = obj.map(value => deepClone(value, cache));
	} else if (Object.prototype.toString.call(obj) === '[object Object]') {
		clone = Object.create(Object.getPrototypeOf(obj));
		cache.set(obj, clone);
		for (const [key, value] of Object.entries(obj)) {
			clone[key] = deepClone(value, cache);
		}
	} else {
		clone = Object.assign({}, obj);
	}
	cache.set(obj, clone);
	return clone;
}

// 重写日志输入方法
console.log = (...params) => {
	if (process.env.NODE_ENV  === "development") {
		const paramsTemp = params.map((item) => {
			return deepClone(item);
		})
		log(...paramsTemp);
	}
}
  1. 和服务端沟通,对于值为null的返回为空字符串或者undefined等(不推荐,成本大)

推荐前三种方式,对现有项目没有任何侵入,方式4也是可以的,这种问题是平台级的特有BUG,BUG已提给平台,静待平台尽早修复吧。

思考

小程序开发是依赖第三方小程序平台的,对于一些难定位的问题,自己折腾找不到原因后,可以优化论坛搜一搜,如果没有那就提一个贴子,一般几天内会有回复,最好是能做一个最小复现的demo,以便于官方定位问题,做最小demo的时候也许自己也能发现解决或绕过问题的方法,在开发的时候可以依赖开发者工具完成需求,但遇到开发者工具和小程序上表现不一致的时候应该以真机为准,因为你最后项目是跑在真机上的。当然也希望各小程序平台积极优化,给广大小程序开发者更好的开发体验。

标签:refund,obj,快手,app,id,return,uni,null,order
From: https://www.cnblogs.com/xwwin/p/18382288

相关文章

  • 使用 updateAppConfig 更新 Nuxt 应用配置
    title:使用updateAppConfig更新Nuxt应用配置date:2024/8/27updated:2024/8/27author:cmdragonexcerpt:通过使用updateAppConfig,你可以轻松地在应用运行时更新配置,而无需重新启动应用。这对于需要在运行时调整设置的应用场景非常有用。categories:前端开发ta......
  • uniapp微信小程序获取小程序新版本
    functioncheckUpdate(){//使用该接口,可以获知是否有新版本小程序、新版本是否下载好以及应用新版本的能力。constupdateManager=uni.getUpdateManager()updateManager.onCheckForUpdate(function(res){//请求完新版本信息的回调console.log(res.hasUp......
  • 导购APP佣金模式的设计与系统实现
    导购APP佣金模式的设计与系统实现大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!随着移动互联网的普及,导购APP成为连接用户与商品的桥梁,而佣金模式则是激励用户参与和推广的关键机制。本文将深入探讨导购APP中佣金模式的设计思路以及系统实现......
  • 题解:P10922 Happybob's Numbers (UBC001B)
    主要思路:贪心,构造。思路构造题,首先明确要删的就是小于\(n\)的数,因为若删了大于等于\(n\)的数就无法进行之后的操作了。那这道题就简单了,先从大到小排序,遇到小于当前长度\(k\)的数,就将这个数删掉,这时长度需减\(1\),毕竟顺序可以自己调,将下一个小于当前\(k\)的数,放到下一......
  • vue3uniapps使用富文本mp-html插件
    1.实现效果具体需求:顶部是搜索栏,包括搜索结果个数,目前跳到第几个,包含上一个、下一个按钮。富文本区域关键词高亮黄色,当前关键词为高亮橙色。如图2.版本号用到vue3和uniapp,mp-html插件版本是v2.5.0,插件地址:https://ext.dcloud.net.cn/plugin?id=805用npm方式打包放到......
  • 使用 UniApp 实现摄像头视频流的接入并在页面上显示视频流
    UniApp是一个使用Vue.js开发所有前端应用的框架,它支持一次开发,多端部署(包括H5、小程序和APP)。下面我将展示如何使用UniApp实现摄像头视频流的接入,并在页面上显示视频流。我还会提供一些使用场景以及代码优化建议。使用场景直播应用:用户可以实时分享自己的画面。在线......
  • AppDomain.CurrentDomain.BaseDirectory是什么
    以下为ai解释,用到的知识点都在此记录下AppDomain.CurrentDomain.BaseDirectory是一个属性,它返回当前应用程序域的基目录,即包含应用程序的目录的路径。这个路径通常是安装应用程序的目录,并且通常以反斜杠(\或者\)结尾。如果你想获取这个路径,你可以直接调用这个属性。解决方案1:s......
  • C++码表之Unicode
    今日诗词:折花逢驿使,寄与陇头人。江南无所有,聊赠一枝春。                     ——《赠范晔诗》【南北朝】陆凯引言:上一期我们说到了ASCII码表,这是一种现如今不是那么通用的机制,随着计算机的普及,越来越多的人开始学习计算机,深......
  • A review of ssm and their applications in connectedand automated vehicles safety
    ABSTRACTSurrogateSafetyMeasures(SSM)areimportantforsafetyperformanceevaluation,since crashesarerareeventsandhistoricalcrashdatadoesnotcapturenearcrashesthatarealsocriticalforimprovingsafety.Thispaper focusesonSSMandthei......
  • 【Unity精品模型资源】Anime Girls Pack: 为你的Unity项目注入动漫活力
    ......