查看: 1856|回复: 12

分享双十二抢购助手源码

[复制链接]
发表于 2020-12-6 09:43 | 显示全部楼层 |阅读模式
禁止求评分、诱导评分、互刷评分、互刷悬赏值,违规者封号处理。
禁止发布推广、邀请码、邀请链接、二维码或者有利益相关的任何推广行为。
所有非原创软件请发布在【精品软件区】,发帖必须按照本版块版规格式发帖。

  1. "ui";
  2. var color = "#009688";
  3. //开始时间,提前时间量,提交频率,结束时间,网络时间偏移,网络接口延迟,设备延迟,辅助提交,倒计时浮窗x,倒计时浮窗y
  4. var startTime, forwardTime, interval, lastTime, NTPClockOffset, NTPClockDelay, deviceDelay, autoSubmit, xp, yp;
  5. //自动购买,自动确认,自动结算,自动提交,自动支付,校验价格,最大价格,使用网络时间
  6. var autoBuy, autoConfirm, autoCart, autoSubmit, autoPay, checkSku, needConfirm, checkPrice, maxPrice, isUseNetTime;
  7. //捡漏,频率
  8. var jlModel, jlhz;
  9. //商品名称,购买按钮
  10. var itemName, buyName, color, size, other, volume, type, skuNum = 0, skuDelay;



  11. //倒计时浮窗
  12. var window;
  13. //定时任务
  14. var workId;
  15. //存储
  16. var storage = storages.create("tb.js");
  17. //时间工具类
  18. var timeUtils = require('TimeUtils.js');

  19. var myQueue = new ArrayQueue();

  20. importClass(android.view.View);

  21. //主页面
  22. ui.layout(
  23.     <drawer id="drawer">
  24.         <vertical>
  25.             <appbar>
  26.                 <toolbar id="toolbar" title="橱窗、收藏页模式" />
  27.                 <tabs id="tabs" />
  28.             </appbar>

  29.             <viewpager id="viewpager">
  30.                 <frame>
  31.                     <ScrollView>
  32.                         <vertical w="*" h="auto" margin="6" >
  33.                             <text h="30" id="networkTest" text="正在检测网络延迟..." gravity="top|left" textColor="red" textSize="13sp" margin="0 5" />
  34.                             <horizontal>
  35.                                 <checkbox id="isUseNetTime" text="使用网络时间" textColor="black" checked="true" />
  36.                                 <checkbox id="autoPay" text="自动支付" checked="true" />
  37.                             </horizontal>
  38.                             <horizontal>
  39.                                 <checkbox id="needConfirm" text="需要确认" checked="true" />
  40.                                 <checkbox id="checkSku" text="SKU延时:" checked="true" />
  41.                                 <input id="skuDelay" text="120" hint="120" marginBottom="-6" />
  42.                             </horizontal>
  43.                             <horizontal>
  44.                                 <checkbox id="jlModel" text="重试频率:" textColor="black" checked="true" />
  45.                                 <input id="jlhz" text="1500" hint="频率" marginBottom="-6" />
  46.                             </horizontal>
  47.                             <horizontal >
  48.                                 <checkbox id="checkPrice" text="最高价格:" textColor="black" />
  49.                                 <input id="maxPrice" text="" hint="10" marginBottom="-6" />
  50.                             </horizontal>
  51.                             <frame w="*" margin="12" h="1" bg="#e3e3e3" />
  52.                             <horizontal >
  53.                                 <checkbox id="baseTime" text="倒计时    " textColor="black" />
  54.                                 <text h="30" text="X:" gravity="top|left" textColor="black" />
  55.                                 <input id="xp" text="360" hint="360" marginBottom="-6" />
  56.                                 <text h="30" text=" , Y:" gravity="top|left" textColor="black" />
  57.                                 <input id="yp" text="1250" hint="1250" marginBottom="-6" />
  58.                             </horizontal>
  59.                             <frame w="*" margin="12" h="1" bg="#e3e3e3" />
  60.                             <horizontal >
  61.                                 <text h="30" text="商品关键字:" gravity="top|left" textColor="black" textSize="16" />
  62.                                 <input id="itemName" text="" hint="袋鼠医用" marginBottom="-6" />
  63.                             </horizontal>
  64.                             <horizontal >
  65.                                 <text h="30" text="购买关键字:" gravity="top|left" textColor="black" textSize="16" />
  66.                                 <input id="buyName" text="" hint="立即购买、领劵购买、马上抢" marginBottom="-6" />
  67.                             </horizontal>
  68.                             <vertical id="skuShow" >
  69.                                 <horizontal >
  70.                                     <text h="30" text="颜色:" gravity="top|left" textColor="black" textSize="16" />
  71.                                     <input id="color" text="" hint="颜色|颜色分类|机身颜色" marginBottom="-6" textSize="16" />
  72.                                 </horizontal>
  73.                                 <horizontal >
  74.                                     <text h="30" text="尺码:" gravity="top|left" textColor="black" textSize="16" />
  75.                                     <input id="size" text="" hint="尺码|鞋码|机身尺码" marginBottom="-6" textSize="16" />
  76.                                 </horizontal>
  77.                                 <horizontal >
  78.                                     <text h="30" text="容量:" gravity="top|left" textColor="black" textSize="16" />
  79.                                     <input id="volume" text="" hint="存储容量|化妆品净含量" marginBottom="-6" textSize="16" />
  80.                                 </horizontal>
  81.                                 <horizontal >
  82.                                     <text h="30" text="类型:" gravity="top|left" textColor="black" textSize="16" />
  83.                                     <input id="type" text="" hint="网络类型" marginBottom="-6" textSize="16" />
  84.                                 </horizontal>
  85.                                 <horizontal >
  86.                                     <text h="30" text="其他:" gravity="top|left" textColor="black" textSize="16" />
  87.                                     <input id="other" text="" hint="口味|套餐类型" marginBottom="-6" textSize="16" />
  88.                                 </horizontal>
  89.                             </vertical>
  90.                             <frame w="*" margin="12" h="1" bg="#e3e3e3" />
  91.                             <horizontal >
  92.                                 <text h="30" text="开始时间(年/月/日 时:分:秒):" gravity="top|left" textColor="black" textSize="16" />
  93.                             </horizontal>
  94.                             <horizontal >
  95.                                 <input id="startTime" text="2020/03/03 14:30:00" hint="无" marginBottom="-6" />
  96.                             </horizontal>
  97.                             <horizontal >
  98.                                 <text h="30" text="提前开始时间(毫秒):" gravity="top|left" textColor="black" textSize="16" />
  99.                                 <input id="forwardTime" text="500" hint="无" marginBottom="-6" />
  100.                             </horizontal >
  101.                             <horizontal >
  102.                                 <text h="30" text="设备启动延迟抵扣量(毫秒):" gravity="top|left" textColor="black" textSize="16" />
  103.                                 <input id="deviceDelay" text="80" hint="无" marginBottom="-6" />
  104.                             </horizontal >
  105.                             <horizontal >
  106.                                 <text h="30" text="提交频率(毫秒):" gravity="top|left" textColor="black" textSize="16" />
  107.                                 <input id="interval" text="5" hint="无" marginBottom="-6" />
  108.                             </horizontal>
  109.                             <horizontal >
  110.                                 <text h="30" text="抢购持续时间(秒):" gravity="top|left" textColor="black" textSize="16" />
  111.                                 <input id="lastTime" text="5" hint="无" marginBottom="-6" />
  112.                             </horizontal>
  113.                             <frame w="*" margin="12" h="1" bg="#e3e3e3" />
  114.                             <button id="checkFastSku" style="Widget.AppCompat.Button.Colored" text="测试SKU选择" />
  115.                             <button id="runButton" style="Widget.AppCompat.Button.Colored" text="开始运行" />
  116.                             <button id="stopUi" style="Widget.AppCompat.Button.Colored" text="退出" />
  117.                         </vertical>
  118.                     </ScrollView>
  119.                 </frame>
  120.             </viewpager>
  121.         </vertical>
  122.     </drawer>
  123. );

  124. //*********************************************************页面交互********************************************************************** */
  125. //显示倒计时浮窗
  126. ui.baseTime.on("check", function (checked) {
  127.     // 用户勾选无障碍服务的选项时,跳转到页面让用户去开启
  128.     if (checked) {
  129.         timeThread = threads.start(function () {
  130.             var clockOffset = 0;
  131.             if (ui.isUseNetTime.isChecked()) {
  132.                 clockOffset = NTPClockOffset;
  133.                 // log("================" + NTPClockOffset)
  134.             }
  135.             window = timeUtils.countDownTimeShow(ui.xp.text(), ui.yp.text(), ui.startTime.text(), ui.forwardTime.text(), clockOffset);
  136.         });
  137.     } else if (window) {
  138.         window.close();
  139.         // floaty.closeAll()
  140.         timeThread.interrupt();
  141.     }
  142. });


  143. //检查价格设置
  144. ui.checkPrice.on("check", function (checked) {
  145.     // 用户勾选价格校验
  146.     if (checked) {
  147.         // exectuion = engines.execScriptFile("time.js");
  148.         if (!ui.maxPrice.text()) {
  149.             ui.checkPrice.checked = false;
  150.             alert("警告", "限制金额的最高金额必须填写!!!");
  151.         }
  152.     }
  153. });

  154. //自动支付设置
  155. ui.autoPay.on("check", function (checked) {
  156.     if (checked) {
  157.         alert("警告", "自动支付仅限于开启了免密支付的设备,脚本会自动点击立即付款,慎用,风险自担!为了您的财产安全,请不要随意透露支付密码!!!");
  158.     }
  159. });

  160. //sku配置
  161. ui.checkSku.on("check", function (checked) {
  162.     if (checked) {
  163.         //     View.GONE //完全隐藏控件
  164.         // View.INVISIBLE //隐藏控件,但保留控件的位置
  165.         // View.VISIBLE //默认属性, 显示控件
  166.         //隐藏
  167.         ui.skuShow.setVisibility(View.VISIBLE);
  168.         alert("警告", "需要自动勾选SKU属性的才需要勾选此项,延时为选中SKU后点击确认的时间。");
  169.     } else {
  170.         ui.skuShow.setVisibility(View.GONE);
  171.     }
  172. });

  173. //确认
  174. ui.needConfirm.on("check", function (checked) {
  175.     if (checked) {
  176.         alert("警告", "开启点击后买后自动确认。");
  177.     } else {
  178.         alert("警告", "关闭自动确认,请确认点击购买后能直接进入订单页。");
  179.     }
  180. });

  181. //重试
  182. ui.jlModel.on("check", function (checked) {
  183.     if (checked) {
  184.         alert("警告", "不能购买将返回活动页重新进入。");
  185.     } else {
  186.         alert("警告", "关闭重试,若商品不能购买将不会返回重试。");
  187.     }
  188. });

  189. activity.setSupportActionBar(ui.toolbar);

  190. //创建选项菜单(右上角)
  191. ui.emitter.on("create_options_menu", menu => {
  192.     menu.add("说明");
  193. });
  194. //监听选项菜单点击
  195. ui.emitter.on("options_item_selected", (e, item) => {
  196.     switch (item.getTitle()) {
  197.         case "说明":
  198.             alert("说明", "橱窗、收藏页面商品定时抢购模式,开启定时任务,前往商品活动页面或商品收藏页面,等待定时抢购,注意浮窗不要遮挡商品位置。"
  199.                 + "启用校验最高价格,高于价格不提交订单。测试的时候可以将价格设低,测试流程就不会提交订单,比较友好。"
  200.                 + "SKU确认测试方法为:填写SKU属性,点击“测试SKU选择”,按照提示进入要抢购的商品详情页,根据检测结果调整参数。");
  201.             break;
  202.     }
  203.     e.consumed = true;
  204. });

  205. //退出脚本时 结束所有脚本
  206. events.on('exit', function () {
  207.     // engines.stopAllAndToast()
  208.     // engines.stopAll();
  209.     exit();
  210. });

  211. //启动
  212. ui.stopUi.on("click", () => {
  213.     //程序开始运行之前判断无障碍服务
  214.     // toast("退出");
  215.     // storage.clear();
  216.     ui.finish();
  217. });

  218. //校验时间
  219. ui.networkTest.on("click", () => {
  220.     threads.start(function () {
  221.         //重置时间
  222.         threads.start(NTP.sync);
  223.         //刷新延迟
  224.         setTimeout(reflushNetTime, 500);
  225.     });
  226. });

  227. //*******************************************************************页面交互***************************************************************************************** */
  228. //*******************************************************************基础方法***************************************************************************************** */
  229. //打开浮窗
  230. function openConsole() {
  231.     auto.waitFor()
  232.     //显示控制台
  233.     var middle = device.width / 2 - 400;
  234.     console.setSize(800, 800);
  235.     console.setPosition(middle, 0);
  236.     console.show();
  237. }

  238. // 时间戳转时间字符串
  239. function add0(m) {
  240.     return m < 10 ? '0' + m : m
  241. }

  242. function add00(m) {
  243.     if (m < 10) {
  244.         return '00' + m;
  245.     } else if (m < 100) {
  246.         return '0' + m;
  247.     } else {
  248.         return m;
  249.     }
  250. }

  251. function formatDate(needTime) {
  252.     //needTime是整数,否则要parseInt转换
  253.     var time = new Date(parseInt(needTime));
  254.     var h = time.getHours();
  255.     var mm = time.getMinutes();
  256.     var s = time.getSeconds();
  257.     var ms = time.getMilliseconds();
  258.     return add0(h) + ':' + add0(mm) + ':' + add0(s) + ":" + add00(ms);
  259. }

  260. // 根据时间偏移值计算真实时间
  261. function getNow() {
  262.     var now = new Date().getTime();
  263.     if (isUseNetTime) {
  264.         return now - NTPClockOffset;
  265.     }
  266.     return now;
  267. }

  268. // 检测时间字符串是否有效
  269. function strDateTime(str) {
  270.     var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/;
  271.     var r = str.match(reg);
  272.     if (r == null) return false;
  273.     var d = new Date(r[1], r[3] - 1, r[4], r[5], r[6], r[7]);
  274.     return (d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4] && d.getHours() == r[5] && d.getMinutes() == r[6] && d.getSeconds() == r[7]);
  275. }

  276. // 获取默认开始时间
  277. function getTime() {
  278.     var fmt = "YYYY-MM-dd hh:mm:ss";
  279.     var d = new Date();
  280.     var hh = d.getHours();
  281.     var mm = d.getMinutes();
  282.     if (mm < 30) {
  283.         mm = 30
  284.     } else {
  285.         hh += 1;
  286.         mm = 0
  287.     }
  288.     var o = {
  289.         "Y+": d.getYear() + 1900,
  290.         "M+": d.getMonth() + 1,
  291.         "d+": d.getDate(),
  292.         "h+": hh,
  293.         // "m+": d.getMinutes(),
  294.         // "s+": d.getSeconds()
  295.         "m+": mm,
  296.         "s+": 0
  297.     };
  298.     for (var k in o) {
  299.         if (new RegExp("(" + k + ")").test(fmt)) {
  300.             fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 4) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  301.         }
  302.     }
  303.     fmt = fmt.replace(/-/g, '/');
  304.     return fmt;
  305. }

  306. //*******************************************************************基础方法***************************************************************************************** */
  307. //*******************************************************************滑动方法***************************************************************************************** */
  308. /**
  309. * 下拉滑动
  310. * [url=home.php?mod=space&uid=952169]@Param[/url] {*} duration  不能小于350ms
  311. */
  312. function dropDown(duration) {
  313.     var width = device.width;
  314.     var height = device.height;
  315.     var y1 = height / 2;
  316.     var y2 = height * 3 / 4;
  317.     var x1 = width / 2;
  318.     var x2 = width / 2;
  319.     // log(x1+"|"+y1+"|"+x2+"|"+y2)
  320.     logInfo("刷新:" + swipe(x1, y1, x2, y2, duration))
  321. }
  322. /**
  323. * 真人模拟滑动函数
  324. *
  325. * 传入值:起点终点坐标
  326. * 效果:模拟真人滑动
  327. */
  328. function randomSwipe(sx, sy, ex, ey) {
  329.     //设置随机滑动时长范围
  330.     var timeMin = 1000
  331.     var timeMax = 3000
  332.     //设置控制点极限距离
  333.     var leaveHeightLength = 500

  334.     //根据偏差距离,应用不同的随机方式
  335.     if (Math.abs(ex - sx) > Math.abs(ey - sy)) {
  336.         var my = (sy + ey) / 2
  337.         var y2 = my + random(0, leaveHeightLength)
  338.         var y3 = my - random(0, leaveHeightLength)

  339.         var lx = (sx - ex) / 3
  340.         if (lx < 0) { lx = -lx }
  341.         var x2 = sx + lx / 2 + random(0, lx)
  342.         var x3 = sx + lx + lx / 2 + random(0, lx)
  343.     } else {
  344.         var mx = (sx + ex) / 2
  345.         var y2 = mx + random(0, leaveHeightLength)
  346.         var y3 = mx - random(0, leaveHeightLength)

  347.         var ly = (sy - ey) / 3
  348.         if (ly < 0) { ly = -ly }
  349.         var y2 = sy + ly / 2 + random(0, ly)
  350.         var y3 = sy + ly + ly / 2 + random(0, ly)
  351.     }

  352.     //获取运行轨迹,及参数
  353.     var time = [0, random(timeMin, timeMax)]
  354.     var track = bezierCreate(sx, sy, x2, y2, x3, y3, ex, ey)

  355.     // log("随机控制点A坐标:" + x2 + "," + y2)
  356.     // log("随机控制点B坐标:" + x3 + "," + y3)
  357.     // log("随机滑动时长:" + time[1])

  358.     // log("time:"+time)
  359.     // log("track:"+track)
  360.     //滑动
  361.     gestures(time.concat(track))
  362. }


  363. function bezierCreate(x1, y1, x2, y2, x3, y3, x4, y4) {
  364.     //构建参数
  365.     var h = 100;
  366.     var cp = [{ x: x1, y: y1 + h }, { x: x2, y: y2 + h }, { x: x3, y: y3 + h }, { x: x4, y: y4 + h }];
  367.     var numberOfPoints = 100;
  368.     var curve = [];
  369.     var dt = 1.0 / (numberOfPoints - 1);

  370.     //计算轨迹
  371.     for (var i = 0; i < numberOfPoints; i++) {
  372.         var ax, bx, cx;
  373.         var ay, by, cy;
  374.         var tSquared, tCubed;
  375.         var result_x, result_y;

  376.         cx = 3.0 * (cp[1].x - cp[0].x);
  377.         bx = 3.0 * (cp[2].x - cp[1].x) - cx;
  378.         ax = cp[3].x - cp[0].x - cx - bx;
  379.         cy = 3.0 * (cp[1].y - cp[0].y);
  380.         by = 3.0 * (cp[2].y - cp[1].y) - cy;
  381.         ay = cp[3].y - cp[0].y - cy - by;

  382.         var t = dt * i
  383.         tSquared = t * t;
  384.         tCubed = tSquared * t;
  385.         result_x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
  386.         result_y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
  387.         curve[i] = {
  388.             x: result_x,
  389.             y: result_y
  390.         };
  391.     }

  392.     //轨迹转路数组
  393.     var array = [];
  394.     for (var i = 0; i < curve.length; i++) {
  395.         try {
  396.             var j = (i < 100) ? i : (199 - i);
  397.             xx = parseInt(curve[j].x)
  398.             yy = parseInt(Math.abs(100 - curve[j].y))
  399.         } catch (e) {
  400.             break
  401.         }
  402.         array.push([xx, yy])
  403.     }

  404.     return array
  405. }
  406. //*******************************************************************滑动方法***************************************************************************************** */
  407. //*******************************************************************日志处理***************************************************************************************** */
  408. // 获取时分秒用于记录日志
  409. function logCommon(msg) {
  410.     console.log(formatDate(getNow()) + " " + msg);
  411. }
  412. function logInfo(msg) {
  413.     console.info(formatDate(getNow()) + " " + msg);
  414. }
  415. function logWarn(msg) {
  416.     console.warn(formatDate(getNow()) + " " + msg);
  417. }
  418. function logError(msg) {
  419.     console.error(formatDate(getNow()) + " " + msg);
  420. }

  421. //*******************************************************************日志处理***************************************************************************************** */
  422. //*******************************************************************网络时间***************************************************************************************** */

  423. // 检测网络延迟和时间偏差
  424. var NTP = {
  425.     requiredResponses: 3,
  426.     serverTimes: [],
  427.     serverDelay: [],
  428.     serverUrl: "http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp",
  429.     resyncTime: 0, // minutes
  430.     sync: function () {
  431.         var offset = storage.get("NTPClockOffset");
  432.         if (offset) {
  433.             try {
  434.                 var t = offset.split("|")[1];
  435.                 var d = NTP.fixTime() - parseInt(t, 10);
  436.                 if (d < (1000 * 60 * NTP.resyncTime)) {
  437.                     return false;
  438.                 }
  439.             } catch (e) {
  440.             }
  441.         }
  442.         NTP.getServerTime();
  443.     },
  444.     getNow: function () {
  445.         var date = new Date();
  446.         return date.getTime();
  447.     },
  448.     parseServerResponse: function (data) {
  449.         var NtpStartTime = storage.get("NtpStartTime");
  450.         var NtpStopTime = NTP.getNow();
  451.         var origtime = parseInt(data.data.t);
  452.         var delay = ((NtpStopTime - NtpStartTime) / 2);
  453.         var offset = NtpStopTime - origtime - delay;
  454.         NTP.serverTimes.push(offset);
  455.         NTP.serverDelay.push(delay);

  456.         // 因为网络问题,需要多次获取偏移值,获取平均值
  457.         if (NTP.serverTimes.length >= NTP.requiredResponses) {
  458.             var sumOffset = 0;
  459.             var sumDelay = 0;
  460.             var i = 0;
  461.             for (i = 0; i < NTP.serverTimes.length; i++) {
  462.                 sumOffset += NTP.serverTimes[i];
  463.                 sumDelay += NTP.serverDelay[i];
  464.             }
  465.             var averageOffset = Math.round(sumOffset / i);
  466.             var averageDelay = Math.round(sumDelay / i);
  467.             storage.put("NTPClockOffset", averageOffset + '|' + NTP.fixTime()); // 保存获得offset时的时间戳
  468.             storage.put("NTPClockDelay", averageDelay); // 保存获得offset时的时间戳
  469.         } else {
  470.             NTP.getServerTime();
  471.         }
  472.     },
  473.     getServerTime: function () {
  474.         var NtpStartTime = NTP.getNow();
  475.         storage.put("NtpStartTime", NtpStartTime);

  476.         var res = http.get(NTP.serverUrl);
  477.         if (res.statusCode !== 200) {
  478.             toast("获取网络时间失败: " + res.statusCode + " " + res.statusMessage);
  479.             return false;
  480.         } else {
  481.             NTP.parseServerResponse(res.body.json());
  482.         }
  483.     },
  484.     fixTime: function (timeStamp) {
  485.         if (!timeStamp) {
  486.             timeStamp = NTP.getNow();
  487.         }
  488.         var offset = storage.get("NTPClockOffset");
  489.         try {
  490.             if (!offset) {
  491.                 offset = 0;
  492.             } else {
  493.                 offset = offset.split("|")[0];
  494.             }
  495.             if (isNaN(parseInt(offset, 10))) {
  496.                 return timeStamp;
  497.             }
  498.             return timeStamp + parseInt(offset, 10);
  499.         } catch (e) {
  500.             return timeStamp;
  501.         }
  502.     }
  503. };

  504. function reflushNetTime() {
  505.     NTPClockOffset = storage.get("NTPClockOffset", "0");
  506.     NTPClockDelay = storage.get("NTPClockDelay", "0");
  507.     if (!NTPClockOffset) {
  508.         NTPClockOffset = 0;
  509.     } else {
  510.         NTPClockOffset = parseInt(NTPClockOffset.split("|")[0]);
  511.     }
  512.     if (NTPClockOffset < 0) {
  513.         var offset_str = "慢了" + -NTPClockOffset + 'ms,'
  514.     } else {
  515.         offset_str = "快了" + NTPClockOffset + 'ms,'
  516.     }
  517.     //网络延迟数据显示
  518.     ui.networkTest.setText("当前设备时间比平台" + offset_str + "网络延迟:" + NTPClockDelay + "ms");
  519. }
  520. //*******************************************************************网络时间***************************************************************************************** */
  521. //*******************************************************************初始化设置***************************************************************************************** */
  522. function initConfig() {
  523.     //刷新延迟
  524.     reflushNetTime();

  525.     //商品名称
  526.     ui.itemName.setText(storage.get("itemName", "").toString());
  527.     //购买关键字
  528.     ui.buyName.setText(storage.get("buyName", "购买").toString());

  529.     ui.autoPay.checked = storage.get("autoPay", false);

  530.     //确认sku
  531.     ui.checkSku.checked = storage.get("checkSku", false);
  532.     ui.skuDelay.setText(storage.get("skuDelay", "120").toString());

  533.     ui.needConfirm.checked = storage.get("needConfirm", true);

  534.     if (ui.checkSku.checked) {
  535.         //     View.GONE //完全隐藏控件
  536.         // View.INVISIBLE //隐藏控件,但保留控件的位置
  537.         // View.VISIBLE //默认属性, 显示控件
  538.         //隐藏
  539.         ui.skuShow.setVisibility(View.VISIBLE);
  540.     } else {
  541.         ui.skuShow.setVisibility(View.GONE);
  542.     }

  543.     //捡漏
  544.     ui.jlModel.checked = storage.get("jlModel", false);
  545.     //捡漏频率
  546.     ui.jlhz.setText(storage.get("jlhz", "100").toString());

  547.     //开启时间
  548.     ui.startTime.setText(getTime());

  549.     //校验价格
  550.     ui.checkPrice.checked = false;
  551.     //最高价格
  552.     ui.maxPrice.setText("1");

  553.     //是否适用网络时间
  554.     ui.isUseNetTime.checked = storage.get("isUseNetTime", true);
  555.     //提前时间
  556.     ui.forwardTime.setText(storage.get("forwardTime", "100").toString());
  557.     //设备启动延迟抵扣量
  558.     ui.deviceDelay.setText(storage.get("deviceDelay", "0").toString());

  559.     //提交频率
  560.     ui.interval.setText(storage.get("interval", "100").toString());
  561.     //持续时间
  562.     ui.lastTime.setText(storage.get("lastTime", "5").toString());
  563.     ui.xp.setText(storage.get("xp", "360").toString());
  564.     ui.yp.setText(storage.get("yp", "250").toString());
  565. }
  566. //*******************************************************************初始化设置***************************************************************************************** */
  567. //*******************************************************************主程序***************************************************************************************** */

  568. // 初始化用户配置
  569. //获取网络时间
  570. threads.start(NTP.sync);
  571. //初始化数据
  572. setTimeout(initConfig, 500);


  573. //*******************************************************************主程序***************************************************************************************** */
  574. //*******************************************************************主程序***************************************************************************************** */
  575. //检查急速模式
  576. ui.checkFastSku.on("click", () => {
  577.     if (ui.checkFastSku.text() == "测试SKU选择") {
  578.         ui.checkFastSku.text("停止测试");
  579.         skuNum = 0;
  580.         logInfo("开始测试SKU选择");
  581.         //保持屏幕常亮
  582.         device.keepScreenOn();
  583.         //开启控制台
  584.         threads.start(openConsole);
  585.         //开始任务
  586.         threads.start(doCheckFastJob);
  587.         ui.checkFastSku.text("停止测试");
  588.     } else {
  589.         ui.checkFastSku.text("测试SKU选择");
  590.         logError("停止测试");
  591.         skuNum = 0;
  592.         threads.start(function () {
  593.             console.hide();
  594.             device.cancelKeepingAwake();
  595.             threads.shutDownAll();
  596.         });
  597.     }
  598. });

  599. //开始
  600. ui.runButton.on("click", () => {

  601.     //准备参数

  602.     //自动支付
  603.     autoPay = ui.autoPay.checked;

  604.     //捡漏模式
  605.     jlModel = ui.jlModel.checked;
  606.     //捡漏频率 毫秒
  607.     jlhz = ui.jlhz.text();

  608.     //是否需要确认sku
  609.     checkSku = ui.checkSku.checked;
  610.     skuDelay = parseInt(ui.skuDelay.getText());

  611.     needConfirm = ui.needConfirm.checked;

  612.     //sku 项
  613.     color = ui.color.text();
  614.     size = ui.size.text();
  615.     volume = ui.volume.text();
  616.     type = ui.type.text();
  617.     other = ui.other.text();

  618.     //购买按钮名称
  619.     buyName = ui.buyName.text();
  620.     //商品名称
  621.     itemName = ui.itemName.text();

  622.     //校验价格
  623.     checkPrice = ui.checkPrice.checked;
  624.     //最高价格
  625.     maxPrice = parseInt(ui.maxPrice.getText());

  626.     //开始时间
  627.     startTime = ui.startTime.getText().toString();
  628.     //使用网络时间
  629.     isUseNetTime = ui.isUseNetTime.isChecked();
  630.     //任务提前时间 毫秒
  631.     forwardTime = parseInt(ui.forwardTime.getText());
  632.     //设备启动延迟抵扣量
  633.     deviceDelay = parseInt(ui.deviceDelay.getText());
  634.     //提交订单频率 毫秒
  635.     interval = parseInt(ui.interval.getText());
  636.     //抢购时长
  637.     lastTime = parseInt(ui.lastTime.getText());
  638.     xp = parseInt(ui.xp.getText());
  639.     yp = parseInt(ui.yp.getText());

  640.     if (!strDateTime(startTime)) {
  641.         ui.startTime.setError("请输入正确的日期");
  642.         return;
  643.     } else if (forwardTime > 1000) {
  644.         ui.forwardTime.setError("请输入0-1000之间的值");
  645.         return;
  646.     }

  647.     storage.put("autoPay", autoPay);

  648.     storage.put("jlModel", jlModel);
  649.     storage.put("jlhz", jlhz);

  650.     storage.put("checkSku", checkSku);
  651.     storage.put("skuDelay", skuDelay);

  652.     storage.put("buyName", buyName);
  653.     storage.put("itemName", itemName);

  654.     // storage.put("checkPrice", checkPrice);
  655.     // storage.put("maxPrice", maxPrice);
  656.     storage.put("isUseNetTime", isUseNetTime);

  657.     storage.put("forwardTime", forwardTime);
  658.     storage.put("interval", interval);
  659.     storage.put("lastTime", lastTime);
  660.     storage.put("deviceDelay", deviceDelay);

  661.     storage.put("xp", xp);
  662.     storage.put("yp", yp);

  663.     //启动任务
  664.     if (ui.runButton.text() == "开始运行") {
  665.         skuNum = 0;
  666.         //保持屏幕常亮
  667.         device.keepScreenOn();
  668.         //开启控制台
  669.         threads.start(openConsole);
  670.         //开始任务
  671.         threads.start(doJob);
  672.         ui.runButton.text("停止运行");
  673.     } else {
  674.         ui.runButton.text("开始运行");
  675.         logInfo("停止运行");
  676.         skuNum = 0;
  677.         threads.start(function () {
  678.             //关闭控制台
  679.             console.hide();
  680.             device.cancelKeepingAwake();
  681.             if (workId) {
  682.                 clearTimeout(workId);
  683.             }
  684.             threads.shutDownAll();
  685.         });
  686.     }

  687.     //保持脚本运行
  688.     setInterval(() => { }, 1000);
  689. });

  690. /**
  691. * 开始任务
  692. */
  693. function doJob() {

  694.     logInfo("脚本开始运行,当前时间偏移: " + NTPClockOffset + " 网络延迟: " + NTPClockDelay);
  695.     //开始时间戳
  696.     var startChecktime = new Date(Date.parse(startTime)).getTime();
  697.     //获取结束时间
  698.     var endTime = startChecktime + lastTime * 1000 - forwardTime;
  699.     //任务开始时间
  700.     var startChecktimeFix = startChecktime - forwardTime;
  701.     //开始刷新的时间
  702.     // var startFlashTime = startChecktime - flushTime;

  703.     logInfo("预期开始抢购时间为:" + formatDate(startChecktimeFix));
  704.     logInfo("预期结束抢购时间为:" + formatDate(endTime));


  705.     if (endTime - getNow() < 0) {
  706.         logError("超出预定抢购时长,抢购结束");
  707.         threads.shutDownAll();
  708.         return;
  709.     }

  710.     var stopThread = threads.start(function () {
  711.         //在新线程执行的代码
  712.         while (true) {
  713.             if (endTime - getNow() < 0) {
  714.                 logError("超出预定抢购时长,抢购结束");
  715.                 threads.shutDownAll();
  716.                 return;
  717.             }
  718.             sleep(1000);
  719.         }
  720.     });


  721.     logCommon("淘宝商品橱窗模式(活动页或收藏页)");
  722.     logCommon("正在打开手机淘宝...");
  723.     launchApp("手机淘宝");
  724.     waitForPackage("com.taobao.taobao");
  725.     logCommon("请进入活动或收藏页面...");


  726.     var readThread = threads.start(function () {
  727.         //在新线程执行的代码
  728.         while (true) {
  729.             //等待商品详情页
  730.             waitForActivity("android.app.Dialog");
  731.             //查找确认
  732.             // var confirm = className("android.widget.TextView").textContains("确定").findOne();
  733.             var confirm = textContains("确定").findOne();
  734.             var confirmButton = findClickableItem(targetItem);
  735.             if (confirmButton.clickable()) {
  736.                 logCommon("确定-a:" + confirmButton.click());
  737.             } else {
  738.                 var scope = confirm.bounds();
  739.                 logCommon("确定-as:" + click(scope.centerX(), scope.centerY()));
  740.             }
  741.             sleep(1000);
  742.         }
  743.     });


  744.     var sleepThread = threads.start(function () {
  745.         //在新线程执行的代码
  746.         while (true) {
  747.             logCommon("被盾:" + textContains("休息会").findOne().text());
  748.             var sleepScope = textContains("向右滑动验证").findOne().bounds();

  749.             var sx = sleepScope.left + (sleepScope.bottom - sleepScope.top) / 2;
  750.             var ex = sleepScope.right - (sleepScope.bottom - sleepScope.top) / 2;
  751.             var y = sleepScope.top + (sleepScope.bottom - sleepScope.top) / 2;

  752.             logCommon("开始滑动")
  753.             randomSwipe(sx, y, ex, y);
  754.             logCommon("滑动完成")
  755.             sleep(100);
  756.         }
  757.     });

  758.     var readThread = threads.start(function () {
  759.         //在新线程执行的代码
  760.         while (true) {
  761.             var readButton = textContains("我知道了").findOne();
  762.             log("被盾了:" + readButton.click());
  763.             sleep(100);
  764.         }
  765.     });

  766.     var successThread = threads.start(function () {
  767.         //在新线程执行的代码
  768.         while (true) {
  769.             var payButton = textContains("立即付款").findOne();
  770.             logError(timeUtils.getLogTime(), "下单成功");
  771.             if (autoPay) {
  772.                 payButton.parent().click();
  773.                 logError(timeUtils.getLogTime(), "尝试支付...");
  774.             }
  775.             sleep(1000);
  776.             threads.shutDownAll();
  777.             return;
  778.         }
  779.     });

  780.     //处理sku
  781.     var skus = [color, size, other, volume, type];
  782.     if (checkSku) {
  783.         for (var i = 0; i < skus.length; i++) {
  784.             let sku = skus[i];
  785.             // logCommon("查找" + sku);
  786.             if (sku) {
  787.                 threads.start(function () {
  788.                     waitForActivity("com.taobao.android.detail.wrapper.activity.DetailActivity");
  789.                     let needSearch = true;
  790.                     while (needSearch) {
  791.                         if (desc(sku).enabled(true).selected(false).exists()) {
  792.                             var color = desc(sku).enabled(true).selected(false).findOne();
  793.                             var colorButton = findClickableItem(color);
  794.                             needSearch = false;
  795.                             skuNum++;
  796.                             myQueue.push(colorButton);
  797.                         } else if (text(sku).enabled(true).selected(false).exists()) {
  798.                             var color = text(sku).enabled(true).selected(false).findOne();
  799.                             var colorButton = findClickableItem(color);
  800.                             needSearch = false;
  801.                             skuNum++;
  802.                             myQueue.push(colorButton);
  803.                         } else {
  804.                             // logError("未找到" + sku);
  805.                             sleep(50);
  806.                         }
  807.                     }
  808.                 });
  809.             }
  810.         }
  811.     }

  812.     //开始干活
  813.     var item = getItem(itemName);
  814.     var itemButton = findClickableItem(item);
  815.     logCommon("已在活动页定位商品,请确保需要抢购的商品已配置好sku等信息,并设置好购买价格,脚本将自动抢购...");

  816.     logCommon("模式确认为定时橱窗、收藏模式,等待开抢...");
  817.     workId = setTimeout(function () {
  818.         doTbCheckJob(itemButton, item);
  819.     }, startChecktimeFix - getNow() - deviceDelay);

  820. }

  821. /**
  822. * tb捡漏模式下单
  823. */
  824. function doTbCheckJob(itemButton, targetItem) {

  825.     logInfo("开始抢购...");
  826.     console.time("进入详情时间");
  827.     //是否有货
  828.     var waitForStock = false;
  829.     while (!waitForStock) {
  830.         if (itemButton) {
  831.             logCommon("商品详情:" + itemButton.click());
  832.         } else {
  833.             var scope = targetItem.bounds();
  834.             logCommon("商品详情-s:" + click(scope.centerX(), scope.centerY()));
  835.         }
  836.         //等待商品详情页
  837.         waitForActivity("com.taobao.android.detail.wrapper.activity.DetailActivity");
  838.         //如果购买标识不存在,返回
  839.         // if (!id("detail_main_sys_button").className("android.widget.TextView").textContains(buyName).enabled(true).exists()) {
  840.         //     logError("未找到[" + buyName + "],返回重试...");
  841.         //     itemDetailBack();
  842.         //     //重新查找商品
  843.         //     targetItem = getItem(itemName);
  844.         //     itemButton = findClickableItem(targetItem);
  845.         //     sleep(jlhz);
  846.         //     continue;
  847.         // }
  848.         //查找立即购买按钮
  849.         var buyButton = id("detail_main_sys_button").className("android.widget.TextView").textContains(buyName).enabled(true).findOne();
  850.         buyButton = findClickableItem(buyButton);
  851.         if (!buyButton) {
  852.             logError("查找购买按钮失败");
  853.             if (jlModel) {
  854.                 itemDetailBack();
  855.                 //重新查找商品
  856.                 targetItem = getItem(itemName);
  857.                 itemButton = findClickableItem(targetItem);
  858.                 continue;
  859.             }
  860.         }
  861.         waitForStock = buyButton.click();
  862.         logCommon(buyName + ":" + waitForStock);
  863.         if (!waitForStock) {
  864.             //如果购买标识存在,但是无法点击返回
  865.             if (jlModel) {
  866.                 itemDetailBack();
  867.                 //重新查找商品
  868.                 targetItem = getItem(itemName);
  869.                 itemButton = findClickableItem(targetItem);
  870.                 sleep(jlhz);
  871.                 continue;
  872.             }
  873.         }
  874.     }
  875.     console.timeEnd("进入详情时间");
  876.     console.time("进入提交时间");
  877.     if (checkSku) {
  878.         threads.start(function () {
  879.             while (true) {
  880.                 var skuButton = myQueue.pop();
  881.                 if (skuButton) {
  882.                     if (!skuButton.selected()) {
  883.                         skuButton.click();
  884.                         skuNum--;
  885.                     }
  886.                 } else {
  887.                     sleep(50);
  888.                 }
  889.             }
  890.         });
  891.     }
  892.     if (needConfirm) {
  893.         //查找确认
  894.         threads.start(function () {
  895.             while (true) {
  896.                 var confirm = id("confirm").enabled(true).findOne();
  897.                 var confirmButton = findClickableItem(confirm);
  898.                 if (skuNum <= 0) {
  899.                     sleep(skuDelay)
  900.                     logCommon("确认:" + confirmButton.click());
  901.                     break;
  902.                 } else {
  903.                     sleep(interval);
  904.                 }
  905.             }
  906.         });
  907.     }
  908.     //查找提交订单页面
  909.     var submit = className("android.widget.TextView").text("提交订单").enabled(true).findOne();
  910.     var submitButton = findClickableItem(submit);
  911.     console.timeEnd("进入提交时间");
  912.     while (true) {
  913.         if (checkPrice) {
  914.             text("小计: ").findOne().parent().children().forEach(child => {
  915.                 var target = child.findOne(className("android.widget.TextView").textContains("¥"));
  916.                 if (target != null) {
  917.                     var itemPriceStr = parseInt(target.text().replace("¥", ""));
  918.                     var priceStr = parseInt(itemPriceStr);
  919.                     if (priceStr && (priceStr <= maxPrice)) {
  920.                         // log("提交订单:" + click(initParam.submitScopeX,initParam.submitScopeY));
  921.                         logCommon("提交订单:" + submitButton.click());
  922.                         // log("提交订单");
  923.                         sleep(interval);
  924.                     } else {
  925.                         logError("商品价格:" + itemPriceStr + ",超过限制金额:¥" + maxPrice);
  926.                     }
  927.                 }
  928.             });
  929.         } else {
  930.             // log("提交订单:" + click(initParam.submitScopeX,initParam.submitScopeY));
  931.             logCommon("提交订单:" + submitButton.click());
  932.             // log("提交订单");
  933.             sleep(interval);
  934.         }
  935.     }
  936. }

  937. /**
  938. * 查找商品点击
  939. * [url=home.php?mod=space&uid=13415]@Param[/url] {*} itemButton
  940. */
  941. function findClickableItem(item) {
  942.     var checkItem = item;
  943.     while (true) {
  944.         if (checkItem.clickable()) {
  945.             // log("找到:" + checkItem);
  946.             return checkItem;
  947.         } else {
  948.             // log("没找到,找父类")
  949.             checkItem = checkItem.parent();
  950.             if (checkItem == null) {
  951.                 // log("找不到")
  952.                 return null;
  953.             } else {
  954.                 // log("找到父类:" + checkItem)
  955.             }
  956.         }
  957.     }
  958. }

  959. /**
  960. * 退出商品详情页
  961. */
  962. function itemDetailBack() {
  963.     logCommon("退出商品详情页:" + className("android.widget.TextView").desc("返回").findOne().click());
  964. }
  965. /**
  966. * sku页面
  967. */
  968. function itemSkuBack() {
  969.     logCommon("退出sku页:" + id("btn_skucard_closecard").findOne().click());
  970. }
  971. /**
  972. * 退出提交订单页面
  973. */
  974. function submitBack() {
  975.     logCommon("退出提交订单页:" + id("btn_back").findOne().click());
  976. }

  977. /**
  978. * 查找商品
  979. */
  980. function getItem(itemName) {
  981.     logCommon("开始查找商品:" + itemName);
  982.     var target;
  983.     while (true) {
  984.         if (textContains(itemName).exists()) {
  985.             target = textContains(itemName).findOne();
  986.             logInfo("找到" + target.text());
  987.         } else if (descContains(itemName).exists()) {
  988.             target = descContains(itemName).findOne();
  989.             logInfo("找到" + target.desc());
  990.         }
  991.         if (target) {
  992.             return target;
  993.         } else {
  994.             sleep(500);
  995.         }
  996.     }
  997. }


  998. /**
  999. * 检查是否适用急速sku模式
  1000. */
  1001. function doCheckFastJob() {
  1002.     //sku 项
  1003.     color = ui.color.text();
  1004.     size = ui.size.text();
  1005.     volume = ui.volume.text();
  1006.     type = ui.type.text();
  1007.     other = ui.other.text();
  1008.     other = ui.other.text();
  1009.     skuDelay = ui.skuDelay.text();
  1010.     logCommon("正在打开手机淘宝...");
  1011.     launchApp("手机淘宝");
  1012.     waitForPackage("com.taobao.taobao");
  1013.     var checkThread = threads.start(function () {
  1014.         while (true) {
  1015.             if (!textContains("加入购物车").exists()) {
  1016.                 logCommon("未进入商品详情页,请前往");
  1017.                 textContains("加入购物车").findOne();
  1018.                 logCommon("已进入商品详情页,开始测试sku选择");
  1019.                 continue;
  1020.             }
  1021.             sleep(1000);
  1022.         }
  1023.     });
  1024.     var addCart = textContains("加入购物车").findOne();
  1025.     logCommon("点击加入购物车,打开sku确认页面:" + addCart.click());
  1026.     var skus = [color, size, volume, type, other];

  1027.     var startSku = false;
  1028.     console.time("sku选择耗时");
  1029.     for (var i = 0; i < skus.length; i++) {
  1030.         let sku = skus[i];
  1031.         // logCommon("查找" + sku);
  1032.         if (sku) {
  1033.             threads.start(function () {
  1034.                 var needSearch = true;
  1035.                 while (needSearch) {
  1036.                     if (desc(sku).enabled(true).selected(false).exists()) {
  1037.                         var color = desc(sku).enabled(true).selected(false).findOne();
  1038.                         var colorButton = findClickableItem(color);
  1039.                         logInfo("找到" + sku);
  1040.                         needSearch = false;
  1041.                         skuNum++;
  1042.                         myQueue.push(colorButton);
  1043.                         startSku = true;
  1044.                     } else if (text(sku).enabled(true).selected(false).exists()) {
  1045.                         var color = text(sku).enabled(true).selected(false).findOne();
  1046.                         var colorButton = findClickableItem(color);
  1047.                         logInfo("找到" + sku);
  1048.                         needSearch = false;
  1049.                         skuNum++;
  1050.                         myQueue.push(colorButton);
  1051.                         startSku = true;
  1052.                     } else {
  1053.                         logError("未找到" + sku);
  1054.                         sleep(1000);
  1055.                     }
  1056.                 }
  1057.             });
  1058.         }
  1059.     }

  1060.     threads.start(function () {
  1061.         while (true) {
  1062.             var skuButton = myQueue.pop();
  1063.             if (skuButton) {
  1064.                 if (!skuButton.selected()) {
  1065.                     skuButton.click();
  1066.                     skuNum--;
  1067.                 }
  1068.             } else {
  1069.                 sleep(50);
  1070.             }
  1071.         }
  1072.     });

  1073.     //查找确认
  1074.     threads.start(function () {
  1075.         while (true) {
  1076.             var confirm = id("confirm").enabled(true).findOne();
  1077.             var confirmButton = findClickableItem(confirm);
  1078.             if (skuNum <= 0) {
  1079.                 sleep(skuDelay)
  1080.                 logCommon("确认:" + confirmButton.click());
  1081.                 break;
  1082.             } else {
  1083.                 sleep(50);
  1084.             }
  1085.         }
  1086.     });

  1087.     while (!startSku) {
  1088.         sleep(50);
  1089.     }
  1090.     while (skuNum > 0) {
  1091.         sleep(50);
  1092.     }
  1093.     console.timeEnd("sku选择耗时");

  1094.     logCommon("测试完成,如果没有选中,可能是sku属性填写错误,属性需要完全一致!");
  1095. }


  1096. function ArrayQueue() {
  1097.     var arr = [];
  1098.     //入队操作  
  1099.     this.push = function (element) {
  1100.         arr.push(element);
  1101.         return true;
  1102.     }
  1103.     //出队操作  
  1104.     this.pop = function () {
  1105.         return arr.shift();
  1106.     }
  1107.     //获取队首  
  1108.     this.getFront = function () {
  1109.         return arr[0];
  1110.     }
  1111.     //获取队尾  
  1112.     this.getRear = function () {
  1113.         return arr[arr.length - 1]
  1114.     }
  1115.     //清空队列  
  1116.     this.clear = function () {
  1117.         arr = [];
  1118.     }
  1119.     //获取队长  
  1120.     this.size = function () {
  1121.         return arr.length;
  1122.     }
  1123. }
复制代码


如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2020-12-6 10:12 | 显示全部楼层
6666
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-6 12:47 | 显示全部楼层
6666666666
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-6 14:52 | 显示全部楼层
多谢分享多谢分享
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-6 15:19 | 显示全部楼层
多谢楼主分享
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-6 16:47 | 显示全部楼层

支持楼主,谢谢分享。
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-6 17:18 | 显示全部楼层

感谢分享,谢谢提供分享
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-6 20:17 | 显示全部楼层
谢谢分享
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

头像被屏蔽
发表于 2020-12-6 23:22 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2020-12-6 23:27 | 显示全部楼层

感谢楼主的分享
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

关注公众号

相关侵权、举报、投诉及建议等,请发 E-mail:admin@discuz.vip

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖
关注公众号
返回顶部