import('com.nx.assist.lua.LuaEngine') import('java.util.HashMap') import('com.nx.assist.lua.LuaEngine') -- ========================================================= -- 取单 / 回传订单状态 -- 说明: -- 1. 直接复制本文件到你的主脚本里即可 -- 2. 默认接口地址:https://rt.viphc.cn/api.php -- 3. 核心函数: -- 获取订单(设备编号) -- 反馈订单状态(设备编号, 订单, 状态) -- ========================================================= 接单接口地址 = "https://rt.viphc.cn/api.php" 接单接口超时 = 30000 默认设备名称 = "" 默认设备备注 = "" 默认设备能力 = "" 当前设备编号 = "device-001" 当前订单 = nil 手机号 = "" 验证码 = "" local function 转字符串(v , 默认值) if v == nil then return 默认值 or "" end return tostring(v) end local function 转数字(v , 默认值) local n = tonumber(v) if n == nil then return 默认值 or 0 end return n end local function 转布尔(v , 默认值) if v == nil then if 默认值 == nil then return false end return 默认值 and true or false end if v == true or v == 1 or v == "1" or v == "true" or v == "TRUE" then return true end if v == false or v == 0 or v == "0" or v == "false" or v == "FALSE" then return false end if 默认值 == nil then return false end return 默认值 and true or false end local function 空表(v) if type(v) == "table" then return v end return {} end local function 新结果(成功 , 消息 , 数据 , 原始 , 地址 , 方法) local ret = {} ret["成功"] = 成功 and true or false ret["消息"] = 转字符串(消息 , "") ret["数据"] = 空表(数据) ret["原始"] = 转字符串(原始 , "") ret["地址"] = 转字符串(地址 , "") ret["方法"] = 转字符串(方法 , "") return ret end local function 编码JSON(data) if type(jsonLib) ~= "table" or type(jsonLib.encode) ~= "function" then return "{}" end local ok , ret = pcall(function() return jsonLib.encode(空表(data)) end) if ok and ret ~= nil and ret ~= "" then return ret end return "{}" end local function 解码JSON(text) if text == nil or text == "" then return nil , "接口没有返回内容" end if type(jsonLib) ~= "table" or type(jsonLib.decode) ~= "function" then return nil , "jsonLib.decode 不可用" end local ok , ret = pcall(function() return jsonLib.decode(text) end) if ok and type(ret) == "table" then return ret , "" end return nil , "JSON 解析失败" end local function URL编码(text) text = 转字符串(text , "") text = string.gsub(text , "\n" , "\r\n") text = string.gsub(text , "([^%w%-_%.~])" , function(c) return string.format("%%%02X" , string.byte(c)) end) return text end local function 拼查询(params) if type(params) ~= "table" then return "" end local arr = {} for k , v in pairs(params) do if v ~= nil then table.insert(arr , URL编码(转字符串(k)) .. "=" .. URL编码(转字符串(v))) end end if #arr <= 0 then return "" end return "?" .. table.concat(arr , "&") end local function 接口地址(action) return 接单接口地址 .. "?action=" .. URL编码(action) end local function 处理接口返回(ok , raw , url , method) if not ok then return 新结果(false , "请求执行异常" , {} , 转字符串(raw) , url , method) end local text = 转字符串(raw , "") local data , err = 解码JSON(text) if type(data) ~= "table" then return 新结果(false , err , {} , text , url , method) end local code = 转数字(data["code"] , 0) local msg = 转字符串(data["msg"] , "") local body = 空表(data["data"]) local 成功 = code == 200 if msg == "" then msg = 成功 and "请求成功" or "请求失败" end return 新结果(成功 , msg , body , text , url , method) end local function 发起GET(action , params , timeout) local headers = HashMap() local url = 接口地址(action) .. 拼查询(params) local t = 转数字(timeout , 接单接口超时) local ok , raw = pcall(function() return LuaEngine.httpGet(url , headers , t) end) return 处理接口返回(ok , raw , url , "GET") end local function 发起POST(action , body , timeout) local url = 接口地址(action) local json = 编码JSON(body) local t = 转数字(timeout , 接单接口超时) local ok , raw = pcall(function() return LuaEngine.httpPostData(url , json , "application/json;charset=utf-8" , t) end) return 处理接口返回(ok , raw , url , "POST") end local function 取字段(tbl , key , 默认值) if type(tbl) ~= "table" then return 默认值 end local v = tbl[key] if v == nil then return 默认值 end return v end local function 取首个非空(tbl , keys , 默认值) if type(tbl) ~= "table" then return 默认值 end local i = 1 while true do local key = keys[i] if key == nil then break end local v = tbl[key] if v ~= nil and 转字符串(v , "") ~= "" then return v end i = i + 1 end return 默认值 end local function 推断任务类型(订单状态 , 验证码) local 状态 = 转字符串(订单状态 , "") local 验证码文本 = 转字符串(验证码 , "") if 状态 == "待反馈登录结果" or 状态 == "登录成功" then return "submit_exchange" end if 状态 == "发送验证码中" or 状态 == "等待设备接管" then if 验证码文本 ~= "" then return "submit_exchange" end return "check_qualification" end return "" end local function 整理订单(data) local body = 空表(data) local task = type(body["task"]) == "table" and body["task"] or nil local record = type(body["record"]) == "table" and body["record"] or {} local source = task or record if task == nil and next(record) == nil and 转字符串(body["status"] , "") == "" then return nil end local order = {} for k , v in pairs(source) do order[k] = v end local 手机号 = 转字符串(取首个非空(order , { "mobile" , "phone" , "phone_no" , "phone_num" , "mobile_phone" } , "") , "") local 验证码 = 转字符串( 取首个非空(body , { "sms_code" , "verify_code" } , 取首个非空(order , { "verify_code" , "sms_code" , "code" } , "")) , "" ) local 订单状态 = 转字符串( 取首个非空(body , { "status" , "exchange_status" } , 取首个非空(order , { "exchange_status" , "status" } , "")) , "" ) local 记录ID = 转数字(取首个非空(order , { "record_id" , "id" } , 0) , 0) local 订单编号 = 转字符串(取首个非空(order , { "record_no" , "task_order_no" , "order_no" } , "") , "") local 卡密 = 转字符串(取首个非空(order , { "card_key" , "invite_code" , "exchange_code" } , "") , "") local 任务类型 = 转字符串(取首个非空(order , { "task_type" } , 推断任务类型(订单状态 , 验证码)) , "") local 结果说明 = 转字符串(取首个非空(body , { "message" } , 取首个非空(order , { "result_message" } , "")) , "") order["record_id"] = 记录ID order["mobile"] = 手机号 order["verify_code"] = 验证码 order["exchange_status"] = 订单状态 order["task_type"] = 任务类型 order["record_no"] = 订单编号 if 卡密 ~= "" then order["card_key"] = 卡密 end return { ["订单"] = order , ["记录ID"] = 记录ID , ["订单编号"] = 订单编号 , ["手机号"] = 手机号 , ["验证码"] = 验证码 , ["卡密"] = 卡密 , ["订单状态"] = 订单状态 , ["任务类型"] = 任务类型 , ["结果说明"] = 结果说明 , } end local function 取订单记录ID(order) if type(order) == "table" then if type(order["订单"]) == "table" then return 转数字(order["记录ID"] , 转数字(order["订单"]["record_id"] , 转数字(order["订单"]["id"] , 0))) end return 转数字(order["record_id"] , 转数字(order["id"] , 0)) end return 转数字(order , 0) end local function 取订单手机号(order) if type(order) ~= "table" then return "" end if type(order["订单"]) == "table" then return 转字符串(order["手机号"] , 转字符串(order["订单"]["mobile"] , "")) end return 转字符串(order["mobile"] , "") end local function 取订单验证码(order) if type(order) ~= "table" then return "" end if type(order["订单"]) == "table" then return 转字符串(order["验证码"] , 转字符串(order["订单"]["verify_code"] , "")) end return 转字符串(order["verify_code"] , "") end function 设置接单接口地址(url) url = 转字符串(url , "") if url == "" then return 新结果(false , "接口地址不能为空" , {} , "" , "" , "LOCAL") end if string.sub(url , - 1) == "/" then url = string.sub(url , 1 , - 2) end 接单接口地址 = url return 新结果(true , "接口地址已更新" , { base_url = 接单接口地址 } , "" , 接单接口地址 , "LOCAL") end function 设置接单默认信息(device_name , remark , capabilities) 默认设备名称 = 转字符串(device_name , 默认设备名称) 默认设备备注 = 转字符串(remark , 默认设备备注) 默认设备能力 = 转字符串(capabilities , 默认设备能力) return 新结果(true , "默认设备信息已更新" , { device_name = 默认设备名称 , remark = 默认设备备注 , capabilities = 默认设备能力 } , "" , 接单接口地址 , "LOCAL") end function 获取订单(设备编号) local ret = 发起POST("device_pull_task" , { device_no = 转字符串(设备编号) , device_name = 转字符串(默认设备名称) , remark = 转字符串(默认设备备注) , capabilities = 转字符串(默认设备能力) } , 20000) if ret["成功"] ~= true then return ret end local data = 空表(ret["数据"]) local order = 整理订单(data) if order == nil then return 新结果(false , "暂无订单" , data , ret["原始"] , ret["地址"] , ret["方法"]) end local result = 新结果(true , ret["消息"] , order , ret["原始"] , ret["地址"] , ret["方法"]) result["订单"] = order["订单"] result["记录ID"] = order["记录ID"] result["订单编号"] = order["订单编号"] result["手机号"] = order["手机号"] result["验证码"] = order["验证码"] result["卡密"] = order["卡密"] result["订单状态"] = order["订单状态"] result["任务类型"] = order["任务类型"] result["结果说明"] = order["结果说明"] return result end function 标准化订单状态(状态) local s = 转字符串(状态 , "") local map = { ["登录成功"] = "登录成功" , ["已登录成功"] = "登录成功" , ["成功登录"] = "登录成功" , ["领取成功"] = "领取成功" , ["兑换成功"] = "领取成功" , ["提交成功"] = "领取成功" , ["成功"] = "领取成功" , ["领取失败"] = "领取失败" , ["兑换失败"] = "领取失败" , ["提交失败"] = "领取失败" , ["失败"] = "领取失败" , ["验证码错误"] = "验证码错误" , ["验证码有误"] = "验证码错误" , ["验证码不正确"] = "验证码错误" , ["短信验证码错误"] = "验证码错误" , ["登录超时"] = "登录超时" , ["超时"] = "登录超时" , ["验证码超时"] = "登录超时" , ["登录失败"] = "登录失败" , ["登录不成功"] = "登录失败" , ["验证码发送失败"] = "验证码发送失败" , ["发送验证码失败"] = "验证码发送失败" , ["发码失败"] = "验证码发送失败" , ["短信发送失败"] = "验证码发送失败" , ["等待用户填写验证码"] = "等待用户填写验证码" , ["等待验证码"] = "等待用户填写验证码" , ["等待用户输入验证码"] = "等待用户填写验证码" , ["等待填写验证码"] = "等待用户填写验证码" , ["等待设备接管"] = "等待设备接管" , ["待设备接管"] = "等待设备接管" , ["等待设备处理"] = "等待设备接管" } return map[s] end function 订单状态默认说明(标准状态) if 标准状态 == "登录成功" then return "设备反馈登录成功" end if 标准状态 == "领取成功" then return "设备反馈领取成功" end if 标准状态 == "领取失败" then return "设备反馈领取失败" end if 标准状态 == "验证码错误" then return "设备反馈验证码错误" end if 标准状态 == "登录超时" then return "设备反馈登录超时" end if 标准状态 == "登录失败" then return "设备反馈登录失败" end if 标准状态 == "验证码发送失败" then return "设备反馈验证码发送失败" end if 标准状态 == "等待用户填写验证码" then return "设备已进入等待验证码阶段" end if 标准状态 == "等待设备接管" then return "任务重新等待设备接管" end return "设备反馈订单状态" end function 反馈订单状态(设备编号 , 订单 , 状态 , 说明 , payload) local 标准状态 = 标准化订单状态(状态) if 标准状态 == nil or 标准状态 == "" then return 新结果(false , "不支持的订单状态:" .. 转字符串(状态) , {} , "" , 接口地址("device_submit_result") , "POST") end local 记录ID = 取订单记录ID(订单) if 记录ID <= 0 then return 新结果(false , "订单 record_id 无效" , {} , "" , 接口地址("device_submit_result") , "POST") end local ext = 空表(payload) if type(订单) == "table" and type(订单["订单"]) == "table" then ext["task_type"] = 转字符串(订单["任务类型"] , 转字符串(订单["订单"]["task_type"] , ext["task_type"])) ext["record_no"] = 转字符串(订单["订单编号"] , 转字符串(订单["订单"]["record_no"] , ext["record_no"])) elseif type(订单) == "table" then ext["task_type"] = 转字符串(订单["task_type"] , ext["task_type"]) ext["record_no"] = 转字符串(订单["record_no"] , ext["record_no"]) end ext["mobile"] = 转字符串(ext["mobile"] , 取订单手机号(订单)) ext["verify_code"] = 转字符串(ext["verify_code"] , 取订单验证码(订单)) return 发起POST("device_submit_result" , { device_no = 转字符串(设备编号) , record_id = 记录ID , status = 标准状态 , message = 转字符串(说明 , 订单状态默认说明(标准状态)) , payload = ext } , 20000) end function 安全删除虚拟机(虚拟机名称 , 强制删除 , 删除磁盘 , 重试次数 , 间隔秒) local 最大重试 = 转数字(重试次数 , 5) local 间隔 = 转数字(间隔秒 , 3) local ret关机 = 关机(虚拟机名称 , false) VM打印结果("强制关机" , ret关机) for i = 1 , 最大重试 , 1 do local 状态 = 获取虚拟机状态(虚拟机名称) VM打印结果("删除前检查虚拟机状态" , 状态) local data = VM取数据(状态) if type(状态) == "table" and 状态["成功"] == true and VM转布尔(data["running"] , false) ~= true then local ret删除 = 删除虚拟机(虚拟机名称 , 强制删除 , 删除磁盘) VM打印结果("删除虚拟机_第" .. tostring(i) .. "次" , ret删除) if type(ret删除) == "table" and ret删除["成功"] == true then return ret删除 end end sleep(间隔 * 1000) end return 删除虚拟机(虚拟机名称 , 强制删除 , 删除磁盘) end function 打印订单结果(标题 , ret) print("====================================") print(转字符串(标题 , "订单结果")) if type(ret) ~= "table" then print("返回值不是 table:" .. 转字符串(ret)) return end print("成功:" .. 转字符串(ret["成功"])) print("消息:" .. 转字符串(ret["消息"])) print("记录ID:" .. 转字符串(ret["记录ID"])) print("订单编号:" .. 转字符串(ret["订单编号"])) print("手机号:" .. 转字符串(ret["手机号"])) print("验证码:" .. 转字符串(ret["验证码"])) print("订单状态:" .. 转字符串(ret["订单状态"])) print("任务类型:" .. 转字符串(ret["任务类型"])) end -- 用法示例: -- 设置接单默认信息("雷电9", "win10-quark", "quark,sms,ocr") -- local 订单 = 获取订单("device-001") -- 打印订单结果("获取订单", 订单) -- if 订单["成功"] == true then -- print("手机号=" .. 转字符串(订单["手机号"])) -- print("验证码=" .. 转字符串(订单["验证码"])) -- local 回传 = 反馈订单状态("device-001", 订单, "登录成功") -- 打印订单结果("反馈订单状态", 回传) -- end -- ========================================================= -- 懒人精灵版 VMware API 中文函数 -- 用法: -- 1. 不要 dofile -- 2. 直接把这整段代码复制到主脚本最上面 -- 3. 然后在下面直接调用中文函数 -- ========================================================= VM接口地址 = "http://192.168.88.8:18765" VM接口超时 = 60000 function VM转字符串(v , 默认值) if v == nil then return 默认值 or "" end return tostring(v) end function VM转数字(v , 默认值) local n = tonumber(v) if n == nil then return 默认值 or 0 end return n end function VM转布尔(v , 默认值) if v == nil then if 默认值 == nil then return false end return 默认值 and true or false end if v == true or v == 1 or v == "1" or v == "true" or v == "TRUE" then return true end if v == false or v == 0 or v == "0" or v == "false" or v == "FALSE" then return false end if 默认值 == nil then return false end return 默认值 and true or false end function VM空表(v) if type(v) == "table" then return v end return {} end function VM结果(成功 , 消息 , 数据 , 原始 , 地址 , 方法) local ret = {} ret["成功"] = 成功 and true or false ret["消息"] = VM转字符串(消息 , "") ret["数据"] = VM空表(数据) ret["原始"] = VM转字符串(原始 , "") ret["地址"] = VM转字符串(地址 , "") ret["方法"] = VM转字符串(方法 , "") ret["找到"] = false return ret end function VM编码JSON(data) if type(jsonLib) ~= "table" or type(jsonLib.encode) ~= "function" then return "{}" end local ok , ret = pcall(function() return jsonLib.encode(VM空表(data)) end) if ok and ret ~= nil and ret ~= "" then return ret end return "{}" end function VM解码JSON(text) if text == nil or text == "" then return nil , "接口没有返回内容" end if type(jsonLib) ~= "table" or type(jsonLib.decode) ~= "function" then return nil , "jsonLib.decode 不可用" end local ok , ret = pcall(function() return jsonLib.decode(text) end) if ok and type(ret) == "table" then return ret , "" end return nil , "JSON解析失败" end function VM打印结果(标题 , ret) print("====================================") print(VM转字符串(标题 , "未命名")) if type(ret) ~= "table" then print("返回值不是table:" .. VM转字符串(ret)) return end print("成功:" .. VM转字符串(ret["成功"])) print("消息:" .. VM转字符串(ret["消息"])) print("地址:" .. VM转字符串(ret["地址"])) print("方法:" .. VM转字符串(ret["方法"])) print("数据:" .. VM编码JSON(ret["数据"])) end function 打印结果(标题 , ret) VM打印结果(标题 , ret) end function VM取数据(ret) if type(ret) ~= "table" then return {} end if type(ret["数据"]) == "table" then return ret["数据"] end return {} end function 取返回数据(ret) return VM取数据(ret) end function 设置接口地址(地址) 地址 = VM转字符串(地址 , "") if 地址 == "" then return VM结果(false , "接口地址不能为空" , {} , "" , "" , "") end if string.sub(地址 , - 1) == "/" then 地址 = string.sub(地址 , 1 , - 2) end VM接口地址 = 地址 return VM结果(true , "接口地址已设置" , { base_url = VM接口地址 } , "" , VM接口地址 , "LOCAL") end function 设置接口超时(毫秒) local t = VM转数字(毫秒 , 60000) if t <= 0 then t = 60000 end VM接口超时 = t return VM结果(true , "接口超时已设置" , { timeout = VM接口超时 } , "" , VM接口地址 , "LOCAL") end function VM拼接地址(path) path = VM转字符串(path , "") if path == "" then return VM接口地址 end if string.sub(path , 1 , 1) ~= "/" then path = "/" .. path end return VM接口地址 .. path end function VM_URL编码(text) text = VM转字符串(text , "") text = string.gsub(text , "\n" , "\r\n") text = string.gsub(text , "([^%w%-_%.~])" , function(c) return string.format("%%%02X" , string.byte(c)) end) return text end function VM拼接查询参数(params) if type(params) ~= "table" then return "" end local arr = {} for k , v in pairs(params) do if v ~= nil then table.insert(arr , VM_URL编码(VM转字符串(k)) .. "=" .. VM_URL编码(VM转字符串(v))) end end if #arr <= 0 then return "" end return "?" .. table.concat(arr , "&") end function VM处理返回(ok , raw , url , method) if not ok then return VM结果(false , "请求执行异常" , {} , VM转字符串(raw) , url , method) end local text = VM转字符串(raw , "") local data , err = VM解码JSON(text) if type(data) ~= "table" then return VM结果(false , err , {} , text , url , method) end local 成功 = true local 消息 = "" if data["ok"] == false then 成功 = false end if data["detail"] ~= nil and data["detail"] ~= "" then 成功 = false 消息 = VM转字符串(data["detail"]) elseif data["error"] ~= nil and data["error"] ~= "" then 成功 = false 消息 = VM转字符串(data["error"]) elseif data["message"] ~= nil and data["message"] ~= "" and data["ok"] == false then 成功 = false 消息 = VM转字符串(data["message"]) end if 消息 == "" then if 成功 then 消息 = "请求成功" else 消息 = "请求失败" end end local ret = VM结果(成功 , 消息 , data , text , url , method) if data["exists"] ~= nil then ret["找到"] = VM转布尔(data["exists"] , false) end return ret end function VM_GET(path , params , timeout) local headers = {} local url = VM拼接地址(path) .. VM拼接查询参数(params) local t = VM转数字(timeout , VM接口超时) local ok , raw = pcall(function() return LuaEngine.httpGet(url , headers , t) end) return VM处理返回(ok , raw , url , "GET") end function VM_POST(path , body , timeout) local url = VM拼接地址(path) local json = VM编码JSON(body) local t = VM转数字(timeout , VM接口超时) local ok , raw = pcall(function() return LuaEngine.httpPostData(url , json , "application/json;charset=utf-8" , t) end) return VM处理返回(ok , raw , url , "POST") end function 健康检查() return VM_GET("/health" , nil , 10000) end function 获取配置() return VM_GET("/config" , nil , 10000) end function 获取虚拟机列表() return VM_GET("/vms" , nil , 30000) end function 获取虚拟机数量() return VM_GET("/vms/count" , nil , 10000) end function 获取虚拟机状态(虚拟机名称) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) return VM_POST("/vm/status" , body , 15000) end function 判断虚拟机已开机(虚拟机名称) local ret = 获取虚拟机状态(虚拟机名称) if ret["成功"] ~= true then return false , ret end local data = VM取数据(ret) if VM转布尔(data["exists"] , false) ~= true then return false , ret end if VM转布尔(data["running"] , false) == true then return true , ret end return false , ret end function 复制虚拟机(源虚拟机 , 新虚拟机名称 , 复制类型 , 目标目录) local body = {} body["source_vm_ref"] = VM转字符串(源虚拟机) body["new_name"] = VM转字符串(新虚拟机名称) body["clone_type"] = VM转字符串(复制类型 , "full") if 目标目录 ~= nil and 目标目录 ~= "" then body["destination_root"] = VM转字符串(目标目录) end return VM_POST("/vm/clone" , body , 1800000) end function 批量复制虚拟机(源虚拟机 , 名前缀 , 数量 , 起始编号 , 位数 , 复制类型 , 目标目录) local body = {} body["source_vm_ref"] = VM转字符串(源虚拟机) body["name_prefix"] = VM转字符串(名前缀) body["count"] = VM转数字(数量 , 1) body["start_index"] = VM转数字(起始编号 , 1) body["digits"] = VM转数字(位数 , 2) body["clone_type"] = VM转字符串(复制类型 , "full") if 目标目录 ~= nil and 目标目录 ~= "" then body["destination_root"] = VM转字符串(目标目录) end return VM_POST("/vm/clone-batch" , body , 1800000) end function 开机(虚拟机名称 , 图形界面) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["gui"] = VM转布尔(图形界面 , true) return VM_POST("/vm/power-on" , body , 240000) end function 关机(虚拟机名称 , 软关机) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["soft"] = VM转布尔(软关机 , true) return VM_POST("/vm/power-off" , body , 240000) end function 删除虚拟机(虚拟机名称 , 强制删除 , 删除磁盘) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["force"] = VM转布尔(强制删除 , true) body["delete_disk"] = VM转布尔(删除磁盘 , true) return VM_POST("/vm/delete" , body , 240000) end function 关闭夸克全部后台(虚拟机名称) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) return VM_POST("/vm/quark/close-all" , body , 60000) end function 设置夸克默认浏览器(虚拟机名称) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) return VM_POST("/vm/quark/set-default-browser" , body , 90000) end function 获取截图(虚拟机名称 , 同时OCR) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["with_ocr"] = VM转布尔(同时OCR , false) return VM_POST("/vm/screenshot" , body , 60000) end function 点击坐标(虚拟机名称 , x , y , 按键类型 , 双击) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["x"] = VM转数字(x , 0) body["y"] = VM转数字(y , 0) body["button"] = VM转字符串(按键类型 , "left") body["double_click"] = VM转布尔(双击 , false) return VM_POST("/vm/click" , body , 45000) end function 查找文字节点(虚拟机名称 , 文字 , 匹配方式 , 忽略大小写 , 最低分 , 序号 , 返回图片 , 搜索左 , 搜索上 , 搜索宽 , 搜索高) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["text"] = VM转字符串(文字) body["match_mode"] = VM转字符串(匹配方式 , "contains") body["ignore_case"] = VM转布尔(忽略大小写 , true) body["min_score"] = tonumber(最低分) or 0.5 body["index"] = VM转数字(序号 , 0) if 搜索左 ~= nil then body["search_left"] = VM转数字(搜索左 , 0) end if 搜索上 ~= nil then body["search_top"] = VM转数字(搜索上 , 0) end if 搜索宽 ~= nil then body["search_width"] = VM转数字(搜索宽 , 0) end if 搜索高 ~= nil then body["search_height"] = VM转数字(搜索高 , 0) end body["return_image"] = VM转布尔(返回图片 , false) return VM_POST("/vm/find-node" , body , 60000) end function 输入文本(虚拟机名称 , 文本 , 输入间隔毫秒 , 输入后回车) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["text"] = VM转字符串(文本) body["interval_ms"] = VM转数字(输入间隔毫秒 , 20) body["press_enter"] = VM转布尔(输入后回车 , false) return VM_POST("/vm/type-text" , body , 45000) end function 发送按键(虚拟机名称 , 按键表 , 模式 , 重复次数 , 间隔毫秒) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) if type(按键表) == "table" then body["keys"] = 按键表 elseif type(按键表) == "string" then body["keys"] = { 按键表 } else body["keys"] = { "tab" } end body["mode"] = VM转字符串(模式 , "press") body["repeat"] = VM转数字(重复次数 , 1) body["delay_ms"] = VM转数字(间隔毫秒 , 80) return VM_POST("/vm/send-keys" , body , 45000) end function 查找并点击(虚拟机名称 , 文字 , 匹配方式 , 忽略大小写 , 最低分 , 序号 , 按键类型 , 双击 , 搜索左 , 搜索上 , 搜索宽 , 搜索高) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["text"] = VM转字符串(文字) body["match_mode"] = VM转字符串(匹配方式 , "contains") body["ignore_case"] = VM转布尔(忽略大小写 , true) body["min_score"] = tonumber(最低分) or 0.5 body["index"] = VM转数字(序号 , 0) if 搜索左 ~= nil then body["search_left"] = VM转数字(搜索左 , 0) end if 搜索上 ~= nil then body["search_top"] = VM转数字(搜索上 , 0) end if 搜索宽 ~= nil then body["search_width"] = VM转数字(搜索宽 , 0) end if 搜索高 ~= nil then body["search_height"] = VM转数字(搜索高 , 0) end body["button"] = VM转字符串(按键类型 , "left") body["double_click"] = VM转布尔(双击 , false) return VM_POST("/vm/find-and-click" , body , 60000) end function 抓取应用节点(虚拟机名称 , 作用域 , 最大深度 , 最大节点数 , 包含不可见 , 包含禁用 , 视图类型) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["scope"] = VM转字符串(作用域 , "foreground") body["max_depth"] = VM转数字(最大深度 , 8) body["max_nodes"] = VM转数字(最大节点数 , 600) body["include_offscreen"] = VM转布尔(包含不可见 , false) body["include_disabled"] = VM转布尔(包含禁用 , true) body["view"] = VM转字符串(视图类型 , "control") return VM_POST("/vm/ui-nodes" , body , 90000) end function 查找控件节点(虚拟机名称 , 文本 , AutomationId , 类名 , 控件类型 , 框架类型 , 作用域 , 最大深度 , 最大节点数 , 序号 , 匹配方式 , 忽略大小写 , 包含不可见 , 包含禁用 , 视图类型) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) if 文本 ~= nil and 文本 ~= "" then body["text"] = VM转字符串(文本) end if AutomationId ~= nil and AutomationId ~= "" then body["automation_id"] = VM转字符串(AutomationId) end if 类名 ~= nil and 类名 ~= "" then body["class_name"] = VM转字符串(类名) end if 控件类型 ~= nil and 控件类型 ~= "" then body["control_type"] = VM转字符串(控件类型) end if 框架类型 ~= nil and 框架类型 ~= "" then body["framework_id"] = VM转字符串(框架类型) end body["scope"] = VM转字符串(作用域 , "foreground") body["max_depth"] = VM转数字(最大深度 , 8) body["max_nodes"] = VM转数字(最大节点数 , 600) body["index"] = VM转数字(序号 , 0) body["match_mode"] = VM转字符串(匹配方式 , "contains") body["ignore_case"] = VM转布尔(忽略大小写 , true) body["include_offscreen"] = VM转布尔(包含不可见 , false) body["include_disabled"] = VM转布尔(包含禁用 , true) body["view"] = VM转字符串(视图类型 , "control") return VM_POST("/vm/find-ui-node" , body , 90000) end function 点击控件节点(虚拟机名称 , 文本 , AutomationId , 类名 , 控件类型 , 框架类型 , 作用域 , 最大深度 , 最大节点数 , 序号 , 匹配方式 , 忽略大小写 , 包含不可见 , 包含禁用 , 视图类型 , 按键类型 , 双击) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) if 文本 ~= nil and 文本 ~= "" then body["text"] = VM转字符串(文本) end if AutomationId ~= nil and AutomationId ~= "" then body["automation_id"] = VM转字符串(AutomationId) end if 类名 ~= nil and 类名 ~= "" then body["class_name"] = VM转字符串(类名) end if 控件类型 ~= nil and 控件类型 ~= "" then body["control_type"] = VM转字符串(控件类型) end if 框架类型 ~= nil and 框架类型 ~= "" then body["framework_id"] = VM转字符串(框架类型) end body["scope"] = VM转字符串(作用域 , "foreground") body["max_depth"] = VM转数字(最大深度 , 8) body["max_nodes"] = VM转数字(最大节点数 , 600) body["index"] = VM转数字(序号 , 0) body["match_mode"] = VM转字符串(匹配方式 , "contains") body["ignore_case"] = VM转布尔(忽略大小写 , true) body["include_offscreen"] = VM转布尔(包含不可见 , false) body["include_disabled"] = VM转布尔(包含禁用 , true) body["view"] = VM转字符串(视图类型 , "control") body["button"] = VM转字符串(按键类型 , "left") body["double_click"] = VM转布尔(双击 , false) return VM_POST("/vm/click-ui-node" , body , 90000) end function 查找图片(虚拟机名称 , 模板图片路径 , 模板图片Base64 , 相似度 , 序号 , 搜索左 , 搜索上 , 搜索宽 , 搜索高 , 返回图片) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) if 模板图片路径 ~= nil and 模板图片路径 ~= "" then body["template_image_path"] = VM转字符串(模板图片路径) end if 模板图片Base64 ~= nil and 模板图片Base64 ~= "" then body["template_image_base64"] = VM转字符串(模板图片Base64) end body["threshold"] = tonumber(相似度) or 0.8 body["index"] = VM转数字(序号 , 0) if 搜索左 ~= nil then body["search_left"] = VM转数字(搜索左 , 0) end if 搜索上 ~= nil then body["search_top"] = VM转数字(搜索上 , 0) end if 搜索宽 ~= nil then body["search_width"] = VM转数字(搜索宽 , 0) end if 搜索高 ~= nil then body["search_height"] = VM转数字(搜索高 , 0) end body["return_image"] = VM转布尔(返回图片 , false) return VM_POST("/vm/find-image" , body , 90000) end function 查图点击(虚拟机名称 , 模板图片路径 , 模板图片Base64 , 相似度 , 序号 , 搜索左 , 搜索上 , 搜索宽 , 搜索高 , 按键类型 , 双击) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) if 模板图片路径 ~= nil and 模板图片路径 ~= "" then body["template_image_path"] = VM转字符串(模板图片路径) end if 模板图片Base64 ~= nil and 模板图片Base64 ~= "" then body["template_image_base64"] = VM转字符串(模板图片Base64) end body["threshold"] = tonumber(相似度) or 0.8 body["index"] = VM转数字(序号 , 0) if 搜索左 ~= nil then body["search_left"] = VM转数字(搜索左 , 0) end if 搜索上 ~= nil then body["search_top"] = VM转数字(搜索上 , 0) end if 搜索宽 ~= nil then body["search_width"] = VM转数字(搜索宽 , 0) end if 搜索高 ~= nil then body["search_height"] = VM转数字(搜索高 , 0) end body["button"] = VM转字符串(按键类型 , "left") body["double_click"] = VM转布尔(双击 , false) return VM_POST("/vm/find-image-and-click" , body , 90000) end function 查找颜色(虚拟机名称 , 颜色值 , 容差 , 序号 , 搜索左 , 搜索上 , 搜索宽 , 搜索高 , 返回图片) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["color"] = VM转字符串(颜色值) body["tolerance"] = VM转数字(容差 , 10) body["index"] = VM转数字(序号 , 0) if 搜索左 ~= nil then body["search_left"] = VM转数字(搜索左 , 0) end if 搜索上 ~= nil then body["search_top"] = VM转数字(搜索上 , 0) end if 搜索宽 ~= nil then body["search_width"] = VM转数字(搜索宽 , 0) end if 搜索高 ~= nil then body["search_height"] = VM转数字(搜索高 , 0) end body["return_image"] = VM转布尔(返回图片 , false) return VM_POST("/vm/find-color" , body , 90000) end function 查色点击(虚拟机名称 , 颜色值 , 容差 , 序号 , 搜索左 , 搜索上 , 搜索宽 , 搜索高 , 按键类型 , 双击) local body = {} body["vm_ref"] = VM转字符串(虚拟机名称) body["color"] = VM转字符串(颜色值) body["tolerance"] = VM转数字(容差 , 10) body["index"] = VM转数字(序号 , 0) if 搜索左 ~= nil then body["search_left"] = VM转数字(搜索左 , 0) end if 搜索上 ~= nil then body["search_top"] = VM转数字(搜索上 , 0) end if 搜索宽 ~= nil then body["search_width"] = VM转数字(搜索宽 , 0) end if 搜索高 ~= nil then body["search_height"] = VM转数字(搜索高 , 0) end body["button"] = VM转字符串(按键类型 , "left") body["double_click"] = VM转布尔(双击 , false) return VM_POST("/vm/find-color-and-click" , body , 90000) end function 点击指定文字(虚拟机名称 , 文字 , 匹配方式 , 忽略大小写 , 最低分 , 序号 , 按键类型 , 双击 , 搜索左 , 搜索上 , 搜索宽 , 搜索高) return 查找并点击(虚拟机名称 , 文字 , 匹配方式 , 忽略大小写 , 最低分 , 序号 , 按键类型 , 双击 , 搜索左 , 搜索上 , 搜索宽 , 搜索高) end function 查找虚拟机(虚拟机名称) local ret = 获取虚拟机列表() if ret["成功"] ~= true then return ret end local data = VM取数据(ret) local items = VM空表(data["items"]) local 目标 = string.lower(VM转字符串(虚拟机名称)) local i = 1 while true do local item = items[i] if item == nil then break end if type(item) == "table" then local a = string.lower(VM转字符串(item["name"])) local b = string.lower(VM转字符串(item["display_name"])) local c = string.lower(VM转字符串(item["vmx_path"])) if 目标 == a or 目标 == b or 目标 == c then return VM结果(true , "找到虚拟机" , item , "" , ret["地址"] , ret["方法"]) end end i = i + 1 end return VM结果(false , "未找到虚拟机:" .. VM转字符串(虚拟机名称) , {} , "" , ret["地址"] , ret["方法"]) end function 取节点中心坐标(查找结果) if type(查找结果) ~= "table" then return 0 , 0 , false end local data = VM取数据(查找结果) if VM转布尔(data["exists"] , false) ~= true then return 0 , 0 , false end return VM转数字(data["center_x"] , 0) , VM转数字(data["center_y"] , 0) , true end function 等待虚拟机出现(虚拟机名称 , 超时秒 , 间隔秒) local 超时 = VM转数字(超时秒 , 120) local 间隔 = VM转数字(间隔秒 , 2) local 开始 = os.time() while true do local ret = 查找虚拟机(虚拟机名称) if ret["成功"] == true then return ret end if os.time() - 开始 >= 超时 then return VM结果(false , "等待虚拟机出现超时" , {} , "" , VM拼接地址("/vms") , "GET") end sleep(间隔 * 1000) end end function 等待虚拟机运行(虚拟机名称 , 超时秒 , 间隔秒) local 超时 = VM转数字(超时秒 , 180) local 间隔 = VM转数字(间隔秒 , 2) local 开始 = os.time() while true do local ret = 获取虚拟机状态(虚拟机名称) if ret["成功"] == true then local data = VM取数据(ret) if VM转布尔(data["exists"] , false) == true and VM转布尔(data["running"] , false) == true then return VM结果(true , "虚拟机已运行" , data , "" , VM拼接地址("/vm/status") , "POST") end end if os.time() - 开始 >= 超时 then return VM结果(false , "等待虚拟机运行超时" , {} , "" , VM拼接地址("/vm/status") , "POST") end sleep(间隔 * 1000) end end function 等待文字出现(虚拟机名称 , 文字 , 超时秒 , 间隔秒 , 匹配方式 , 忽略大小写 , 最低分 , 序号 , 搜索左 , 搜索上 , 搜索宽 , 搜索高) local 超时 = VM转数字(超时秒 , 60) local 间隔 = VM转数字(间隔秒 , 2) local 开始 = os.time() while true do local ret = 查找文字节点( 虚拟机名称 , 文字 , 匹配方式 or "contains" , 忽略大小写 , 最低分 , 序号 , false , 搜索左 , 搜索上 , 搜索宽 , 搜索高 ) if ret["成功"] == true and ret["找到"] == true then return ret end if os.time() - 开始 >= 超时 then return VM结果(false , "等待文字出现超时:" .. VM转字符串(文字) , {} , "" , VM拼接地址("/vm/find-node") , "POST") end sleep(间隔 * 1000) end end function 复制并开机(源虚拟机 , 新虚拟机名称) local a = 复制虚拟机(源虚拟机 , 新虚拟机名称 , "full" , nil) if a["成功"] ~= true then return a end local b = 开机(新虚拟机名称 , true) if b["成功"] ~= true then return b end return VM结果(true , "复制并开机成功" , { clone = VM取数据(a) , power_on = VM取数据(b) } , "" , VM拼接地址("/vm/power-on") , "POST") end -- ========================================================= -- 下面是最简单的直接调用示例 -- 直接保留就行,不会自动执行 -- 你要测试时,把前面的 -- 去掉 -- ========================================================= -- 设置接口地址("http://192.168.88.8:18765") -- 设置接口超时(60000) -- VM打印结果("健康检查", 健康检查()) -- VM打印结果("获取配置", 获取配置()) -- VM打印结果("获取虚拟机列表", 获取虚拟机列表()) -- VM打印结果("获取虚拟机数量", 获取虚拟机数量()) -- VM打印结果("获取虚拟机状态", 获取虚拟机状态("Quark-Win10-Base")) -- local ret1 = 复制虚拟机("Quark-Win10-Base", "Quark-测试-01", "full", nil) -- VM打印结果("复制虚拟机", ret1) -- local ret2 = 开机("Quark-测试-01", true) -- VM打印结果("开机", ret2) -- local ret3 = 查找文字节点("Quark-测试-01", "夸克", "contains", true, 0.5, 0, false) -- VM打印结果("查找文字", ret3) -- local ret4 = 抓取应用节点("Quark-测试-01", "foreground", 8, 600, false, true, "control") -- VM打印结果("抓取应用节点", ret4) -- local ret5 = 查找控件节点("Quark-测试-01", "确定", nil, nil, "Button", nil, "foreground", 8, 600, 0, "contains", true, false, true, "control") -- VM打印结果("查找控件节点", ret5) -- local ret6 = 点击控件节点("Quark-测试-01", "确定", nil, nil, "Button", nil, "foreground", 8, 600, 0, "contains", true, false, true, "control", "left", false) -- VM打印结果("点击控件节点", ret6) -- local ret7 = 查找图片("Quark-测试-01", "C:/temp/login_button.png", nil, 0.85, 0, nil, nil, nil, nil, false) -- VM打印结果("查找图片", ret7) -- local ret8 = 查找颜色("Quark-测试-01", "#1677FF", 12, 0, nil, nil, nil, nil, false) -- VM打印结果("查找颜色", ret8) -- local x, y, ok = 取节点中心坐标(ret3) -- print("中心坐标:" .. VM转字符串(x) .. "," .. VM转字符串(y) .. ",是否找到=" .. VM转字符串(ok)) -- if ok then -- VM打印结果("点击坐标", 点击坐标("Quark-测试-01", x, y, "left", false)) -- end -- ========================================================= -- 主流程状态机 -- ========================================================= 当前虚拟机名称 = "Quark-"..systemTime() 运行参照 = 2 print("开始复制虚拟机,预计180秒完成") local ret = 复制并开机("Quark-Win10-Base" , 当前虚拟机名称) VM打印结果("复制并开机" , ret) for i = 1 , 30 , 1 do sleep(3000) print("等待开机") local ret3 = 等待虚拟机运行(当前虚拟机名称 , 180 , 2) VM打印结果("等待虚拟机运行" , ret3) if type(ret3) == "table" and ret3["成功"] == true then print("判断登录成功,但是需要还等50秒,半开机状态") sleep(50000) 点击坐标(当前虚拟机名称 , 535 , 308 , "right" , false) sleep(2000) 点击指定文字(当前虚拟机名称 , "刷新" , "contains" , true , 0.5 , 0 , "left" , false , nil , nil , nil , nil) break end end print("打开夸克") local 开始时间 = tickCount() while 运行参照 == 2 do if tickCount() - 开始时间 > 3 * 60 * 1000 then print("设置默认浏览器超时") 运行参照 = 5 end --进入夸克浏览器内 print("打开夸克——设置默认浏览器部分") local ret = 查找控件节点(当前虚拟机名称 , "回收站" , nil , nil , nil , nil , "foreground" , 8 , 800 , 0 , "contains" , true , true , true , "control") if type(ret) == "table" and ret["成功"] == true and ret["找到"] == true then local ret = 点击控件节点(当前虚拟机名称 , "夸克" , nil , nil , nil , nil , "foreground" , 8 , 800 , 0 , "contains" , true , true , true , "control" , "left" , true) print("双击控件节点_夸克" , ret) sleep(5000) end --查找网址页面 local ret = 查找文字节点(当前虚拟机名称 , "输入网址" , "contains" , true , 0.5 , 0 , false , 173 , 360 , 308 , 389) if type(ret) == "table" and ret["成功"] == true and ret["找到"] == true then print("点击活动入口") sleep(500) 点击坐标(当前虚拟机名称 , 999 , 62 , "left" , false) sleep(1000) 点击坐标(当前虚拟机名称 , 997 , 114 , "left" , false) sleep(2000) end 点击指定文字(当前虚拟机名称 , "前往设置" , "contains" , true , 0.5 , 0 , "left" , false , nil , nil , nil , nil) local ret1 = 查找文字节点(当前虚拟机名称 , "Edge" , "contains" , true , 0.5 , 0 , false , 368 , 544 , 718 , 638) if type(ret1) == "table" and ret1["成功"] == true and ret1["找到"] == true then print("当前默认浏览器为:Edge") sleep(500) 点击指定文字(当前虚拟机名称 , "Edge" , "contains" , true , 0.5 , 0 , "left" , false , 368 , 544 , 718 , 638) sleep(1000) 点击坐标(当前虚拟机名称 , 475 , 457 , "left" , false) sleep(1000) 点击坐标(当前虚拟机名称 , 814 , 49 , "left" , false) sleep(500) end 点击指定文字(当前虚拟机名称 , "登录并领取" , "contains" , true , 0.5 , 0 , "left" , false , 578 , 138 , 684 , 215) local ret1 = 查找文字节点(当前虚拟机名称 , "手机" , "contains" , true , 0.5 , 0 , false , 598 , 498 , 699 , 533) if type(ret1) == "table" and ret1["成功"] == true and ret1["找到"] == true then print("选择手机号登录") 点击坐标(当前虚拟机名称 , 622 , 487 , "left" , false) sleep(500) end local ret1 = 查找文字节点(当前虚拟机名称 , "确认登录" , "contains" , true , 0.5 , 0 , false , 564 , 461 , 798 , 504) if type(ret1) == "table" and ret1["成功"] == true and ret1["找到"] == true then print("选择手机号登录,获取订单部分") 运行参照 = 3 sleep(500) end sleep(500) end while 运行参照 == 3 do print("获取订单") 当前订单 = 获取订单(当前设备编号) print("获取订单" , 当前订单) if type(当前订单) == "table" and 当前订单["成功"] == true then print("手机号=" .. tostring(当前订单["手机号"])) print("验证码=" .. tostring(当前订单["验证码"])) 手机号 = tostring(当前订单["手机号"]) 验证码 = tostring(当前订单["验证码"]) 运行参照 = 4 else sleep(3000) end end print("登录-判断会员状态") local 开始时间 = tickCount() while 运行参照 == 4 do if tickCount() - 开始时间 > 3 * 60 * 1000 then print("判断状态超时") 反馈订单状态(默认设备名称 , 订单 , "登录超时") 运行参照 = 5 end sleep(500) print("登录-判断会员状态") 点击指定文字(当前虚拟机名称 , "登录并领取" , "contains" , true , 0.5 , 0 , "left" , false , 578 , 138 , 684 , 215) local ret1 = 查找文字节点(当前虚拟机名称 , "手机" , "contains" , true , 0.5 , 0 , false , 598 , 498 , 699 , 533) if type(ret1) == "table" and ret1["成功"] == true and ret1["找到"] == true then print("选择手机号登录") 点击坐标(当前虚拟机名称 , 622 , 487 , "left" , false) sleep(500) end local ret1 = 查找文字节点(当前虚拟机名称 , "输入手机号" , "contains" , true , 0.5 , 0 , false , 563 , 262 , 804 , 299) if type(ret1) == "table" and ret1["成功"] == true and ret1["找到"] == true then print("输入手机号") 点击坐标(当前虚拟机名称 , 602 , 281 , "left" , false) sleep(500) 输入文本(当前虚拟机名称 , 手机号 , 20 , false) sleep(500) end local ret2 = 查找文字节点(当前虚拟机名称 , "手机验证码" , "contains" , true , 0.5 , 0 , false , 559 , 316 , 715 , 352) if type(ret2) == "table" and ret2["成功"] == true and ret2["找到"] == true then print("输入验证码") 点击坐标(当前虚拟机名称 , 607 , 336 , "left" , false) sleep(500) 输入文本(当前虚拟机名称 , 验证码 , 20 , false) sleep(500) end --没见输入框,点击登录,判断登录状态 local ret1 = 查找文字节点(当前虚拟机名称 , "输入手机号" , "contains" , true , 0.5 , 0 , false , 563 , 262 , 804 , 299) local ret2 = 查找文字节点(当前虚拟机名称 , "手机验证码" , "contains" , true , 0.5 , 0 , false , 559 , 316 , 715 , 352) if type(ret1) == "table" and ret1["成功"] == true and ret1["找到"] == true then else if type(ret2) == "table" and ret2["成功"] == true and ret2["找到"] == true then else local ret = 查找文字节点(当前虚拟机名称 , "验证码错误" , "contains" , true , 0.5 , 0 , false , 552 , 348 , 803 , 393) if type(ret) == "table" and ret["成功"] == true and ret["找到"] == true then local 回传结果 = 反馈订单状态(当前设备编号 , 当前订单 , "验证码错误") 打印订单结果("反馈订单状态-验证码错误" , 回传结果) 运行参照 = 5 else print("未见登录输入框,尝试点击登录") 点击指定文字(当前虚拟机名称 , "确认登录" , "contains" , true , 0.5 , 0 , "left" , false , 563 , 461 , 805 , 503) end end end --查找网址页面 local ret = 查找文字节点(当前虚拟机名称 , "输入网址" , "contains" , true , 0.5 , 0 , false , 173 , 360 , 308 , 389) if type(ret) == "table" and ret["成功"] == true and ret["找到"] == true then print("点击主页入口") sleep(500) 点击坐标(当前虚拟机名称 , 970 , 59 , "left" , false) sleep(1000) end --个人中心 local ret = 查找文字节点(当前虚拟机名称 , "个人中心" , "contains" , true , 0.5 , 0 , false , 280 , 147 , 134 , 51) if type(ret) == "table" and ret["成功"] == true and ret["找到"] == true then print("个人中心内,判断会员状态") sleep(500) local ret1 = 查找文字节点(当前虚拟机名称 , "网盘SVIP会员" , "contains" , true , 0.5 , 0 , false , 310 , 331 , 702 , 72) if type(ret1) == "table" and ret1["成功"] == true and ret1["找到"] == true then local ret2 = 查找文字节点(当前虚拟机名称 , "尚未开通" , "contains" , true , 0.5 , 0 , false , 310 , 331 , 702 , 72) if type(ret2) == "table" and ret2["成功"] == true and ret2["找到"] == true then local 回传结果 = 反馈订单状态(当前设备编号 , 当前订单 , "领取失败") 打印订单结果("反馈订单状态-领取失败" , 回传结果) else print("个人中心内,存在会员") local 回传结果 = 反馈订单状态(当前设备编号 , 当前订单 , "领取成功") 打印订单结果("反馈订单状态-领取成功" , 回传结果) end else local 回传结果 = 反馈订单状态(当前设备编号 , 当前订单 , "领取失败") 打印订单结果("反馈订单状态-领取失败" , 回传结果) end 运行参照 = 5 sleep(500) end end local ret = 安全删除虚拟机(当前虚拟机名称 , true , true , 5 , 3) VM打印结果("安全删除虚拟机" , ret)