aipexbase-js 1.1.8 → 1.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1 +1,2731 @@
1
- const t={getItem(t){try{return localStorage.getItem(t)}catch(t){return console.warn("No localStorage available"),null}},setItem(t,e){try{localStorage.setItem(t,e)}catch(t){console.warn("Cannot write to localStorage")}},removeItem(t){try{localStorage.removeItem(t)}catch(t){console.warn("Cannot remove from localStorage")}}},e=async(t,e)=>(await fetch(t,e)).json();class s{constructor({baseUrl:s,apiKey:r,storage:i,request:a}){this.baseUrl=s,this.apiKey=r,this.storage=i||t,this.requestImpl=a||e}getApiKey(){return this.apiKey}setToken(t){t?this.storage.setItem("baas_token",t):this.storage.removeItem("baas_token")}getToken(){return this.storage.getItem("baas_token")}async request(t,e={}){const s=`${this.baseUrl}${t}`,r={"Content-Type":"application/json",CODE_FLYING:`${this.apiKey}`,...this.getToken()?{Authorization:`Bearer ${this.getToken()}`}:{},...e.headers||{}},i=await this.requestImpl(s,{...e,headers:r});return console.log("url: ",s,"\n header:",r,"\n response:",i),i}}function r(t){return{async login({user_name:e,phone:s,email:r,password:i}={}){const a=e||s||r;if(!a)throw new Error("必须提供 user_name、phone 或 email 之一");if(!i)throw new Error("必须提供 password");const n=await t.request("/login/passwd",{method:"POST",body:JSON.stringify({phone:a,password:i})});return n.success&&t.setToken(n.data),n},async loginByEmailAndCode({email:e,code:s}={}){const r=await t.request("/login/mail",{method:"POST",body:JSON.stringify({phone:e,code:s})});return r.success&&t.setToken(r.data),r},async loginByPhoneAndCode({phone:e,code:s}={}){const r=await t.request("/login/phone",{method:"POST",body:JSON.stringify({phone:e,code:s})});return r.success&&t.setToken(r.data),r},async loginByWeChat({code:e}={}){const s=await t.request("/login/wechat",{method:"POST",body:JSON.stringify({code:e})});return s.success&&t.setToken(s.data),s},async loginByWeApp({code:e}={}){const s=await t.request("/login/weapp",{method:"POST",body:JSON.stringify({code:e})});return s.success&&t.setToken(s.data),s},getUser:async()=>t.request("/getUserInfo",{method:"GET"}),register:async e=>await t.request("/login/register",{method:"POST",body:JSON.stringify(e)}),logout:async()=>(t.setToken(null),t.request("/logout",{method:"GET"})),loginOauth2Uri:async({provider:e}={})=>await t.request("/oauth2/authorize/"+e,{method:"GET"})}}class i{constructor(t,e){this.client=t,this.table=e,this._body=null,this._method=""}list(){return new a(this.client,this.table,"list")}page(){return new a(this.client,this.table,"page")}get(){return new a(this.client,this.table,"get")}insert(){return new n(this.client,this.table,"add")}update(){return new n(this.client,this.table,"update")}delete(){return new a(this.client,this.table,"delete")}}class a{constructor(t,e,s){this.client=t,this.table=e,this.method=s,this.filters={}}_addFilter(t,e,s){return this.filters.hasOwnProperty(t)||(this.filters[t]={}),this.filters[t][e]=s,this}eq(t,e){return this._addFilter(t,"eq",e)}neq(t,e){return this._addFilter(t,"neq",e)}gt(t,e){return this._addFilter(t,"gt",e)}gte(t,e){return this._addFilter(t,"gte",e)}lt(t,e){return this._addFilter(t,"lt",e)}lte(t,e){return this._addFilter(t,"lte",e)}like(t,e){return this._addFilter(t,"like",e)}in(t,e){return this._addFilter(t,"in",e)}between(t,e){return this._addFilter(t,"between",e)}or(t){this.filters.or||(this.filters.or=[]);const e=new a(this.client,this.table,"or");return t(e),this.filters.or.push(e.build()),this}limit(t){return this}page(t,e){return this.filters.current=t,this.filters.pageSize=e,this}order(t,e="asc"){this.filters.order_by||(this.filters.order_by=[]);let s="asc";return"string"==typeof e?s=e.toLowerCase():"object"==typeof e&&null!==e&&("ascending"in e?s=e.ascending?"asc":"desc":"direction"in e&&(s=e.direction.toLowerCase())),this.filters.order_by.push({field:t,direction:s}),this}build(){return this.filters}async _execute(){return await this.client.request(`/api/data/invoke?table=${this.table}&method=${this.method}`,{method:"POST",body:this.filters?JSON.stringify(this.filters):void 0})}then(t,e){this._execute().then(t,e)}}class n extends a{constructor(t,e,s){super(t,e,s),this.data={}}values(t){return this.data={...t},this}set(t){return this.data={...t},this}build(){return{...this.filters,...this.data}}async _execute(){return await this.client.request(`/api/data/invoke?table=${this.table}&method=${this.method}`,{method:"POST",body:JSON.stringify(this.build())})}then(t,e){this._execute().then(t,e)}}function o(t){return{from:e=>new i(t,e)}}class h{constructor(t,e){this.client=t,this.apiName=e,this._params={},this._headers={},this._method="POST"}param(t,e){return this._params[t]=e,this}params(t){return Object.assign(this._params,t),this}header(t,e){return this._headers[t]=e,this}headers(t){return Object.assign(this._headers,t),this}async _execute(){const t=JSON.stringify(this._params),e=`/api/${this.apiName}`;return await this.client.request(e,{method:this._method,headers:this._headers,body:t})}then(t,e){this._execute().then(t,e)}}function c(t){return{call:e=>new h(t,e)}}class u{static API_MAP={search:"/api/bijia_spu_search",compare:"/api/bijia_spu_goods_search"};constructor(t,e){this.client=t,this._params={},this.type=e}keyword(t){return this._params.query=t,this}setParams(t={}){return Object.assign(this._params,t),this}type(t){if(!u.API_MAP[t])throw new Error(`Unsupported comparison type: ${t}`);return this.type=t,this}async _execute(){const t=u.API_MAP[this.type];return await this.client.request(t,{method:"POST",body:JSON.stringify(this._params)})}then(t,e){this._execute().then(t,e)}}function l(t){return{searchProduct:()=>new u(t,"search"),findLowestPrice:()=>new u(t,"compare")}}class p{constructor(t){this.client=t,this._params={},this._taskId=null,this._pollingInterval=2e3,this._maxRetries=30}url(t){return this._params.url=t,this._params.format="pdf-to-image",this}format(t="pdf-to-image"){return this._params.format=t,this}pollingInterval(t){return this._pollingInterval=t,this}maxRetries(t){return this._maxRetries=t,this}async createTask(){if(!this._params.url)throw new Error("PDF文件URL不能为空");const t=await this.client.request("/api/pdf2image",{method:"POST",body:JSON.stringify({url:this._params.url,format:this._params.format})});return this._taskId=t.data,t}async queryTask(t=null){const e=t||this._taskId;if(!e)throw new Error("任务ID不能为空,请先创建任务");return await this.client.request("/api/queryPDF2ImageTask",{method:"POST",body:JSON.stringify({taskId:e})})}async convert(){try{console.log("开始创建PDF转图片任务...");const t=await this.createTask();console.log("任务创建成功:",t);const e=t.data;if(!e)throw new Error("任务创建失败,未返回任务ID");console.log("开始轮询查询任务状态...");let s=0;for(;s<this._maxRetries;){const t=await this.queryTask(e);console.log(`第${s+1}次查询结果:`,t);const r=t.data?.state;if(1===r)return console.log("PDF转图片任务完成:",t.data),t;if(r<0)return console.log("PDF转图片任务失败,状态码:",r),t;s++,s<this._maxRetries&&(console.log(`等待${this._pollingInterval}ms后进行第${s+1}次查询...`),await new Promise(t=>setTimeout(t,this._pollingInterval)))}throw new Error(`PDF转图片任务超时,已重试${this._maxRetries}次`)}catch(t){throw console.error("PDF转图片失败:",t),t}}then(t,e){return this.convert().then(t,e)}catch(t){return this.convert().catch(t)}}function d(t){return{convertPdf:()=>new p(t),async quickConvert(e={}){const s=new p(t);return e.url&&s.url(e.url),e.format&&s.format(e.format),e.pollingInterval&&s.pollingInterval(e.pollingInterval),e.maxRetries&&s.maxRetries(e.maxRetries),await s.convert()}}}class m{constructor(t){this.client=t,this._params={}}company(t){return this._params.com=t,this}trackingNumber(t){return this._params.num=t,this}phone(t){return this._params.phone=t,this}_validateParams(){if(!this._params.com)throw new Error("快递公司代码不能为空");if(!this._params.num)throw new Error("快递单号不能为空");if(("shunfeng"===this._params.com||"shunfengkuaiyun"===this._params.com)&&!this._params.phone)throw new Error("顺丰快递必须提供手机号参数")}async track(){return this._validateParams(),await this.client.request("/api/expressInquiry",{method:"POST",body:JSON.stringify({com:this._params.com,num:this._params.num,resultv2:4,...this._params.phone?{phone:this._params.phone}:{}})})}then(t,e){return this.track().then(t,e)}catch(t){return this.track().catch(t)}}function y(t){return{trackPackage:()=>new m(t)}}class _{static LOCATION_MAP={location:"/api/geocoder",address:"/api/geoaddress"};constructor(t,e){this.client=t,this._params={},this.type=e}latitude(t){return this._params.latitude=t,this}longitude(t){return this._params.longitude=t,this}address(t){return this._params.address=t,this}_validateLocationParams(){if(!this._params.latitude||!this._params.longitude)throw new Error("经纬度参数不能为空")}_validateAddressParams(){if(!this._params.address)throw new Error("地址参数不能为空")}_data(){return"location"===this.type?(this._validateLocationParams(),{location:`${this._params.latitude},${this._params.longitude}`}):(this._validateAddressParams(),{address:this._params.address})}async _execute(){const t=_.LOCATION_MAP[this.type],e=this._data();let s=await this.client.request(t,{method:"POST",body:JSON.stringify(e)}),r=s;return"data"in s&&"result"in s.data&&(r.result=s.data.result,r.result.latitude=s.data.result.location.lat,r.result.longitude=s.data.result.location.lng,r.status=s.data.status),r}then(t,e){this._execute().then(t,e)}}class g{constructor(t){this.client=t}async _execute(){const t=await this.client.request("/api/amap_ip_location",{method:"POST",body:JSON.stringify({})}),e=t?.data?.rectangle;if(!e)throw new Error("返回数据中缺少 rectangle 字段");const[s,r]=e.split(";"),[i,a]=s.split(",").map(Number),[n,o]=r.split(",").map(Number);return{success:!0,latitude:(a+o)/2,longitude:(i+n)/2,speed:0,altitude:0,horizontalAccuracy:1e3}}then(t,e){this._execute().then(t,e)}}class w{constructor(t){this.client=t,this._params={}}from(t,e){return this._params.from={lat:t,lng:e},this}to(t,e){return this._params.to={lat:t,lng:e},this}decodePolyline(t){for(let e=2;e<t.length;e++)t[e]=t[e-2]+t[e]/1e6;return t}async _execute(){const{from:t,to:e}=this._params;if(!t||!e)throw new Error("必须提供起点和终点坐标");const s={from:`${t.lat},${t.lng}`,to:`${e.lat},${e.lng}`},r=await this.client.request("/api/driving",{method:"POST",body:JSON.stringify(s)}),{routes:i}=r.data.result;return{success:!0,data:{paths:i.map(t=>{const e=this.decodePolyline([...t.polyline]),s=t.steps.map(t=>{const{polyline_idx:[s,r]}=t,i=[];for(let t=s;t<=r;t+=2)i.push({latitude:e[t],longitude:e[t+1]});return{...t,polylines:i}});return{distance:t.distance,duration:t.duration,steps:s}})}}}then(t,e){this._execute().then(t,e)}}class f{constructor(t){this.client=t,this._params={}}lat(t){return this._params.lat=t,this}lng(t){return this._params.lng=t,this}radius(t){return this._params.radius=t,this}keyword(t){return this._params.keyword=t,this}async _execute(){const{lat:t,lng:e,radius:s=1e3,keyword:r}=this._params;if(!t||!e)throw new Error("必须提供经纬度参数");const i={boundary:`nearby(${t},${e},${s})`,...r&&{keyword:r}},a=await this.client.request("/api/mapsearch",{method:"POST",body:JSON.stringify(i)}),{data:n}=a.data;return{success:!0,data:n.map(t=>({...t,latitude:t.location.lat,longitude:t.location.lng}))}}then(t,e){this._execute().then(t,e)}}function P(t){return{locationToAddress:()=>new _(t,"location"),addressToLocation:()=>new _(t,"address"),currentLocation:()=>new g(t),driving:()=>new w(t),nearby:()=>new f(t)}}class S{static API_MAP={train:"/api/queryTickets",flight:"/api/queryFlight"};constructor(t,e){this.client=t,this.params={},this.mode=e}from(t){return this.params.from=t,this}to(t){return this.params.to=t,this}date(t){return this.params.date=t,this}async _execute(){const t=S.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){this._execute().then(t,e)}}function q(t){return{train:()=>new S(t,"train"),flight:()=>new S(t,"flight")}}class b{static API_MAP={feishu:"/api/feishuRobotText",wechat:"/api/wechatRobotText"};constructor(t,e){this.client=t,this.params={},this.mode=e}content(t){return this.params.content=t?.replace(/\r?\n/g," "),this}async _execute(){const t=b.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){this._execute().then(t,e)}}class A{constructor(t){this.client=t,this.payload={}}title(t){return this.payload.title=t,this}content(t){return this.payload.content=t?.replace(/\r?\n/g," "),this}to(t){return this.payload.to=t,this}params(t={}){return this.payload.params=t,this}async _execute(){return await this.client.request("/common/mail/send",{method:"POST",body:JSON.stringify(this.payload)})}then(t,e){this._execute().then(t,e)}}function x(t){return{feishuRobot:()=>new b(t,"feishu"),wechatRobot:()=>new b(t,"wechat"),mail:()=>new A(t)}}class T{static API_MAP={text2pic:"/api/word2pic",text2tts:"/api/text/tts"};constructor(t,e){this.client=t,this.params={model:"gemini-3-pro-image-preview"},this.mode=e}text(t){return this.params.text=t,this}model(t){return this.params.model=t,this}async _execute(){const t=T.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}class k{constructor(t){this.client=t}async uploadFile(t,e="mp3",s="audio/mpeg"){const r=await this.client.request("/common/uploadByUrl",{method:"POST",body:JSON.stringify({fileUrl:t,formatter:e,contentType:s})});return console.log("uploadFile response:",r),r}}class O extends k{constructor(t){super(t),this.params={}}text(t){return this.params.text=t,this}speaker(t){return this.params.speaker=t,this}createTask(){const t=this.params.text;if(!t)throw new Error("文本内容不能为空");let e=this.params.speaker;e&&""!==e||(e="zh_female_cancan_mars_bigtts");let s={text:t,speaker:e};const r=this.client.request("/api/ttsTask",{method:"POST",body:JSON.stringify(s)});return this._taskId=r.data,r}async queryTask(t=null){const e=t||this._taskId;if(!e)throw new Error("任务ID不能为空,请先创建任务");let s={taskId:e};return await this.client.request("/api/queryTts",{method:"POST",body:JSON.stringify(s)})}async _execute(){const t=await this.createTask();console.log("====TTS任务创建成功:====",t);const e=t.data.task_id;if(!e)throw new Error("任务创建失败,未返回任务ID");let s=0;for(;2!==s;){const t=await this.queryTask(e);if(s=t.data?.task_status||0,2===s){const e=await this.uploadFile(t.data.audio_url);return t.data=e.data,t}if(3===s)return t;await new Promise(t=>setTimeout(t,2e3))}}then(t,e){return this._execute().then(t,e)}}class I{constructor(t){this.client=t,this.params={}}text(t){return this.params.text=t,this}prompt(t){return this.params.prompt=t,this}conversationId(t){return this.params.conversationId=t,this}async _execute(){const{text:t,prompt:e="",conversationId:s=""}=this.params,r={prompt:e,query:t,conversation_id:s,user:this.client.getApiKey(),files:[]};return await this.client.request("/api/AiAnalysis",{method:"POST",body:JSON.stringify(r)})}then(t,e){this._execute().then(t,e)}}class N extends I{constructor(t){super(t)}url(t){return this.params.url=t,this}async _execute(){const{url:t,prompt:e,text:s,conversationId:r=""}=this.params,i=[{type:"image",transfer_method:"remote_url",url:t}],a={prompt:e,query:s,conversation_id:r,user:this.client.getApiKey(),files:t?i:[]};return await this.client.request("/api/AiAnalysis",{method:"POST",body:JSON.stringify(a)})}then(t,e){this._execute().then(t,e)}}class v extends k{static CREATE_API_MAP={video:"/api/text2video",audio:"/api/text2music"};static QUERY_API_MAP={video:"/api/queryVideo",audio:"/api/queryMusic"};constructor(t,e){super(t),this.params={},this.mode=e,this._taskId=null}text(t){return this.params.text=t,this}createTask(){const t=this.params.text;if(!t)throw new Error("文本内容不能为空");const e=v.CREATE_API_MAP[this.mode];let s={};s="video"===this.mode?{text:t}:{prompt:this.cleanString(t)};const r=this.client.request(e,{method:"POST",body:JSON.stringify(s)});return this._taskId=r.data,r}async queryTask(t=null){const e=t||this._taskId;if(!e)throw new Error("任务ID不能为空,请先创建任务");const s=v.QUERY_API_MAP[this.mode];let r={};return r="video"===this.mode?{id:e}:{item_ids:e},await this.client.request(s,{method:"POST",body:JSON.stringify(r)})}async _execute(){const t=await this.createTask();console.log("任务创建成功:",t);const e=t.data;if(!e)throw new Error("任务创建失败,未返回任务ID");let s="";for(;"succeeded"!==s;){const t=await this.queryTask(e);if(s=t.data?.status||"","succeeded"===s){if("video"===this.mode){const e=await this.uploadFile(t.data.content.video_url,"mp4","video/mp4");t.data.content.video_url=e.data}else{const e=await this.uploadFile(t.data.audio_url,"mp3","audio/mpeg");t.data.audio_url=e.data}return t}if("failed"===s)return t;await new Promise(t=>setTimeout(t,2e3))}}then(t,e){this._execute().then(t,e)}cleanString(t){return t?(t=(t=(t=t.toString()).replace(/[\n\r\t]+/g,",")).replace(/\s{2,}/g,",")).trim():t}}function M(t){return{textToImage:()=>new T(t,"text2pic"),textToSpeech:()=>new O(t),imageToText:()=>new N(t),chat:()=>new I(t),textToVideo:()=>new v(t,"video"),textToAudio:()=>new v(t,"audio")}}class C{static API_MAP={web:"/api/webSearch",video:"/api/webSearch",image:"/api/webSearch"};constructor(t,e){this.client=t,this._params={type:e,top_k:20,site:[]},this._type=e}content(t){return this._params.content=t,this}type(t){if(!C.API_MAP[t])throw new Error(`Unsupported search type: ${t}`);return this._type=t,this._params.type=t,this}site(t){return this._params.site||(this._params.site=[]),null==t||this._params.site.push(t),this}async _execute(){const t=C.API_MAP[this._type];return await this.client.request(t,{method:"POST",body:JSON.stringify(this._params)})}then(t,e){return this._execute().then(t,e)}}function J(t){return{search:()=>new C(t,"web"),webSearch:()=>new C(t,"web"),videoSearch:()=>new C(t,"video"),imageSearch:()=>new C(t,"image")}}const E=new class{constructor(){this.plugins=new Map,this.pluginModules=new Map}register(t,e){if(this.plugins.has(t))console.warn(`Plugin ${t} is already registered`);else{if(!this.validatePlugin(e))throw console.log(`Invalid plugin module for ${t}:`,{type:typeof e,value:e,constructor:e?.constructor?.name,keys:"object"==typeof e?Object.keys(e):"N/A"}),new Error(`Invalid plugin module structure for ${t}`);this.plugins.set(t,{name:t,module:e,initialized:!1}),console.log(`Plugin ${t} registered successfully`)}}validatePlugin(t){return null!=t&&("function"==typeof t||"object"==typeof t&&!Array.isArray(t))}init(t,e){const s=this.plugins.get(t);if(!s)throw new Error(`Plugin ${t} not found`);let r;if("function"!=typeof s.module&&"object"!=typeof s.module)throw new Error(`Invalid plugin module type for ${t}`);return r=s.module,s.initialized=!0,"function"==typeof r.init&&r.init(),r}getRegisteredPlugins(){return Array.from(this.plugins.keys())}isRegistered(t){return this.plugins.has(t)}unregister(t){this.plugins.has(t)&&(this.plugins.delete(t),console.log(`Plugin ${t} unregistered`))}};class B{constructor(t){this.client=t,this._params={}}interval(t){return this._params.interval=t,this}vsCurrency(t){return this._params.vsCurrency=t,this}days(t){return this._params.days=t,this}async query(){return await this.client.request("/api/historytrend",{method:"POST",body:JSON.stringify({interval:this._params.interval,vs_currency:this._params.vsCurrency,days:this._params.days})})}then(t,e){return this.query().then(t,e)}catch(t){return this.query().catch(t)}}function D(t){return{historytrend:()=>new B(t)}}class R{static API_MAP={googleSearch:"/api/googleSearch"};constructor(t){this.client=t,this.params={}}content(t){return this.params.content=t,this}num(t){return this.params.num=t,this}type(t){return this.params.type=t,this}async _execute(){const t=R.API_MAP.googleSearch;return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){this._execute().then(t,e)}}function $(t){return{search:()=>new R(t)}}class F{static API_MAP={list:"/api/queryToutiaoIndex",content:"/api/queryToutiaoContent",NewsByCategory:"/api/NewsByCategory",NewsByRegion:"/api/NewsByRegion"};constructor(t,e){this.client=t,this.mode=e,this.params={}}type(t){return this.params.type=t,this}page(t){return this.params.page=t,this}page_size(t){return this.params.pageSize=t,this}is_filter(t){return this.params.isFilter=t,this}uniquekey(t){return this.params.uniquekey=t,this}category(t){return this.params.category=t,this}region(t){return this.params.region=t,this}async _execute(){const t=F.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function L(t){return{queryToutiaoIndex:()=>new F(t,"list"),queryToutiaoContent:()=>new F(t,"content"),queryNYNewsByCategory:()=>new F(t,"NewsByCategory"),queryNYNewsByRegion:()=>new F(t,"NewsByRegion")}}class W{static API_MAP={nationalWeather:"/api/nationalWeather",internationalWeather:"/api/weather"};constructor(t,e){this.client=t,this.mode=e,this.params={}}city(t){return"nationalWeather"!==this.mode&&console.warn("city 参数仅适用于 nationalWeather 模式"),this.params.city=t,this}latitude(t){return"internationalWeather"!==this.mode&&console.warn("latitude 参数仅适用于 internationalWeather 模式"),this.params["location.latitude"]=t,this}longitude(t){return"internationalWeather"!==this.mode&&console.warn("longitude 参数仅适用于 internationalWeather 模式"),this.params["location.longitude"]=t,this}async _execute(){this._validateParams();const t=W.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}_validateParams(){if("nationalWeather"===this.mode){if(!this.params.city)throw new Error("nationalWeather 模式需要提供 city 参数")}else if(!("internationalWeather"!==this.mode||this.params["location.latitude"]&&this.params["location.longitude"]))throw new Error("internationalWeather 模式需要提供 latitude 和 longitude 参数")}then(t,e){return this._execute().then(t,e)}}function z(t){return{queryNationalWeather:()=>new W(t,"nationalWeather"),queryWeather:()=>new W(t,"internationalWeather")}}class U{static API_MAP={frate:"/api/frate",rmbquot:"/api/rmbquot"};constructor(t,e){this.client=t,this.mode=e,this.params={}}type(t){return this.params.type=t,this}bank(t){return this.params.bank=t,this}async _execute(){const t=U.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function j(t){return{frate:()=>new U(t,"frate"),rmbquot:()=>new U(t,"rmbquot")}}class G{static API_MAP={queryCaipu:"/api/queryCaipu",RandomRecipes:"/api/RandomRecipes",MealPlan:"/api/MealPlan"};constructor(t,e){this.client=t,this.params={},this.mode=e}word(t){return this.params.word=t,this}num(t){return this.params.num=t,this}page(t){return this.params.page=t,this}tags(t){return this.params.tags=t,this}number(t){return this.params.number=t,this}timeFrame(t){return this.params.timeFrame=t,this}targetCalories(t){return this.params.targetCalories=t,this}diet(t){return this.params.diet=t,this}exclude(t){return this.params.exclude=t,this}async _execute(){const t=G.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function K(t){return{queryIngredients:()=>new G(t,"queryCaipu"),queryDishName:()=>new G(t,"queryCaipu"),query:()=>new G(t,"queryCaipu"),queryRandomRecipes:()=>new G(t,"RandomRecipes"),queryMealPlan:()=>new G(t,"MealPlan")}}class Y{static API_MAP={queryCarPrice:"/api/queryCarPrice"};constructor(t){this.client=t,this.params={}}search(t){return this.params.search=t,this}async _execute(){const t=Y.API_MAP.queryCarPrice;return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function H(t){return{query:()=>new Y(t)}}class Q{static API_MAP={queryDiseaseByName:"/api/queryDiseaseByName"};constructor(t){this.client=t,this.params={}}word(t){return this.params.word=t,this}async _execute(){const t=Q.API_MAP.queryDiseaseByName;return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function V(t){return{query:()=>new Q(t)}}class X{static API_MAP={queryCalorie:"/api/queryCalorie"};constructor(t){this.client=t,this.params={}}sex(t){return this.params.sex=t,this}height(t){return this.params.height=t,this}weight(t){return this.params.weight=t,this}age(t){return this.params.age=t,this}level(t){return this.params.level=t,this}async _execute(){const t=X.API_MAP.queryCalorie;return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function Z(t){return{query:()=>new X(t)}}class tt{static API_MAP={nationalGoldprice:"/api/nationalGoldprice"};constructor(t){this.client=t,this.params={}}async _execute(){const t=tt.API_MAP.nationalGoldprice;return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function et(t){return{query:()=>new tt(t)}}class st{static API_MAP={youtubeSearch:"/api/youtubeSearch"};constructor(t){this.client=t,this.params={}}q(t){return this.params.q=t,this}type(t){return this.params.type=t,this}async _execute(){const t=st.API_MAP.youtubeSearch;return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function rt(t){return{search:()=>new st(t)}}class it{static API_MAP={queryTimezone:"/api/timezone"};constructor(t){this.client=t,this.params={}}location(t){return this.params.location=t,this}timestamp(t){return this.params.timestamp=t,this}async _execute(){const t=it.API_MAP.queryTimezone;return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function at(t){return{search:()=>new it(t)}}class nt{static API_MAP={queryNationalScenic:"/api/queryNationalScenic",restaurantsSearch:"/api/restaurantsSearch",hotelsSearch:"/api/hotelsSearch",attractionSearch:"/api/attractionSearch"};constructor(t,e){this.client=t,this.params={},this.model=e}word(t){return this.params.word=t,this}num(t){return this.params.num=t,this}page(t){return this.params.page=t,this}province(t){return this.params.province=t,this}city(t){return this.params.city=t,this}query(t){return this.params.query=t,this}async _execute(){const t=nt.API_MAP[this.model];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function ot(t){return{query:()=>new nt(t,"queryNationalScenic"),queryRestaurantsSearch:()=>new nt(t,"restaurantsSearch"),queryHotelsSearch:()=>new nt(t,"hotelsSearch"),queryAttractionSearch:()=>new nt(t,"attractionSearch")}}class ht{static API_MAP={queryFootballMatch:"/api/queryFootballMatch",footballRank:"/api/footballRank"};constructor(t,e){this.client=t,this.mode=e,this.params={}}type(t){return this.params.type=t,this}async _execute(){const t=ht.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function ct(t){return{match:()=>new ht(t,"queryFootballMatch"),rank:()=>new ht(t,"footballRank")}}class ut{static API_MAP={hsStock:"/api/hsStock",usaStock:"/api/usaStock",usaall:"/api/usaall",szall:"/api/szall",shall:"/api/shall"};constructor(t,e){this.client=t,this.mode=e,this.params={}}symbol(t){return this.params.gid=t,this}type(t){return this.params.type=t,this}stock(t){return this.params.stock=t,this}page(t){return this.params.page=t,this}async _execute(){const t=ut.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}function lt(t){return{queryHs:()=>new ut(t,"hsStock"),queryHk:()=>new dt(t,"hkStock"),queryUsa:()=>new ut(t,"usaStock"),queryHkAll:()=>new dt(t,"hkall"),queryUsaAll:()=>new ut(t,"usaall"),querySzAll:()=>new ut(t,"szall"),queryShAll:()=>new ut(t,"shall"),queryTimeDaily:()=>new pt(t,"TimeDaily"),queryCurrencyExchange:()=>new pt(t,"CurrencyExchange"),queryDigitalCurrencyDaily:()=>new pt(t,"DigitalCurrencyDaily"),queryTechnicalIndicators:()=>new pt(t,"TechnicalIndicators")}}class pt{static API_MAP={TimeDaily:"/api/TimeDaily",CurrencyExchange:"/api/CurrencyExchange",DigitalCurrencyDaily:"/api/DigitalCurrencyDaily",TechnicalIndicators:"/api/TechnicalIndicators"};constructor(t,e){this.client=t,this.mode=e,this.params={}}symbol(t){return this.params.symbol=t,this}to_currency(t){return this.params.to_currency=t,this}from_currency(t){return this.params.from_currency=t,this}market(t){return this.params.market=t,this}time_period(t){return this.params.time_period=t,this}interval(t){return this.params.interval=t,this}series_type(t){return this.params.series_type=t,this}async _execute(){const t=pt.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}class dt{static API_MAP={hkStock:"/api/hkStock",hkall:"/api/hkall"};constructor(t,e){this.client=t,this.mode=e,this.params={}}symbol(t){return this.params.num=t,this}page(t){return this.params.page=t,this}async _execute(){const t=dt.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){return this._execute().then(t,e)}}class mt{static API_MAP={SearchCocktail:"/api/SearchCocktail",ListPopularCocktails:"/api/ListPopularCocktails",ListMostLatestCocktails:"/api/ ListMostLatestCocktails",GetBeersDataByBreweryOrBrand:"/api/GetBeersDataByBreweryOrBrand",GetBeersDataByName:"/api/GetBeersDataByName"};constructor(t,e){this.client=t,this.params={},this.mode=e}s(t){return this.params.s=t,this}brewery(t){return this.params.brewery=t,this}name(t){return this.params.name=t,this}async _execute(){const t=mt.API_MAP[this.mode];return await this.client.request(t,{method:"POST",body:JSON.stringify(this.params)})}then(t,e){this._execute().then(t,e)}}function yt(t){return{queryCocktail:()=>new mt(t,"SearchCocktail"),queryPopularCocktails:()=>new mt(t,"ListPopularCocktails"),queryLatestCocktails:()=>new mt(t,"ListMostLatestCocktails"),queryBeersData:()=>new mt(t,"GetBeersDataByBreweryOrBrand"),queryBeersDataByName:()=>new mt(t,"GetBeersDataByName")}}function _t(t){const e=new s(t),i={setToken:t=>e.setToken(t),getToken:()=>e.getToken(),auth:r(e),db:o(e),api:c(e),comparison:l(e),document:d(e),logistics:y(e),location:P(e),travel:q(e),notification:x(e),ai:M(e),baidu:J(e),bitcoin:D(e),google:$(e),news:L(e),weather:z(e),money:j(e),caipu:K(e),car:H(e),disease:V(e),calorie:Z(e),goldprice:et(e),youtube:rt(e),timezone:at(e),scenic:ot(e),football:ct(e),stock:lt(e),wine:yt(e)};return E.getRegisteredPlugins().forEach(t=>{try{const s=E.init(t,e);i[t]?(console.warn(`Plugin "${t}" conflicts with built-in module. Merging plugin methods into existing module.`),Object.assign(i[t],s)):i[t]=s}catch(e){console.error(`Failed to load plugin ${t}:`,e)}}),i}export{_t as createClient,E as pluginLoader};
1
+ // --- 默认实现 ---
2
+ const defaultStorage = {
3
+ getItem(key) {
4
+ try {
5
+ return localStorage.getItem(key);
6
+ } catch (e) {
7
+ console.warn("No localStorage available");
8
+ return null;
9
+ }
10
+ },
11
+ setItem(key, value) {
12
+ try {
13
+ localStorage.setItem(key, value);
14
+ } catch (e) {
15
+ console.warn("Cannot write to localStorage");
16
+ }
17
+ },
18
+ removeItem(key) {
19
+ try {
20
+ localStorage.removeItem(key);
21
+ } catch (e) {
22
+ console.warn("Cannot remove from localStorage");
23
+ }
24
+ }
25
+ };
26
+ const defaultRequest = async (url, options) => {
27
+ const res = await fetch(url, options);
28
+ return res.json();
29
+ };
30
+ class BaaSClient {
31
+ constructor({
32
+ baseUrl,
33
+ apiKey,
34
+ storage,
35
+ request
36
+ }) {
37
+ this.baseUrl = baseUrl;
38
+ this.apiKey = apiKey;
39
+
40
+ // 如果未传入 storage 或 request,使用默认实现
41
+ this.storage = storage || defaultStorage;
42
+ this.requestImpl = request || defaultRequest;
43
+ }
44
+ getApiKey() {
45
+ return this.apiKey;
46
+ }
47
+ setToken(token) {
48
+ if (token) {
49
+ this.storage.setItem("baas_token", token);
50
+ } else {
51
+ this.storage.removeItem("baas_token");
52
+ }
53
+ }
54
+ getToken() {
55
+ return this.storage.getItem("baas_token");
56
+ }
57
+ async request(path, options = {}) {
58
+ const url = `${this.baseUrl}${path}`;
59
+ const headers = {
60
+ "Content-Type": "application/json",
61
+ "CODE_FLYING": `${this.apiKey}`,
62
+ ...(this.getToken() ? {
63
+ "Authorization": `Bearer ${this.getToken()}`
64
+ } : {}),
65
+ ...(options.headers || {})
66
+ };
67
+ const res = await this.requestImpl(url, {
68
+ ...options,
69
+ headers
70
+ });
71
+ console.log('url: ', url, '\n header:', headers, '\n response:', res);
72
+ return res;
73
+ }
74
+ }
75
+
76
+ function authModule(client) {
77
+ return {
78
+ async login({
79
+ user_name,
80
+ phone,
81
+ email,
82
+ password
83
+ } = {}) {
84
+ const account = user_name || phone || email;
85
+ if (!account) {
86
+ throw new Error("必须提供 user_name、phone 或 email 之一");
87
+ }
88
+ if (!password) {
89
+ throw new Error("必须提供 password");
90
+ }
91
+ const res = await client.request("/login/passwd", {
92
+ method: "POST",
93
+ body: JSON.stringify({
94
+ phone: account,
95
+ password: password
96
+ })
97
+ });
98
+ if (res.success) {
99
+ client.setToken(res.data);
100
+ }
101
+ return res;
102
+ },
103
+ async loginByEmailAndCode({
104
+ email,
105
+ code
106
+ } = {}) {
107
+ const res = await client.request("/login/mail", {
108
+ method: "POST",
109
+ body: JSON.stringify({
110
+ phone: email,
111
+ code: code
112
+ })
113
+ });
114
+ if (res.success) {
115
+ client.setToken(res.data);
116
+ }
117
+ return res;
118
+ },
119
+ async loginByPhoneAndCode({
120
+ phone,
121
+ code
122
+ } = {}) {
123
+ const res = await client.request("/login/phone", {
124
+ method: "POST",
125
+ body: JSON.stringify({
126
+ phone: phone,
127
+ code: code
128
+ })
129
+ });
130
+ if (res.success) {
131
+ client.setToken(res.data);
132
+ }
133
+ return res;
134
+ },
135
+ async loginByWeChat({
136
+ code
137
+ } = {}) {
138
+ const res = await client.request("/login/wechat", {
139
+ method: "POST",
140
+ body: JSON.stringify({
141
+ code: code
142
+ })
143
+ });
144
+ if (res.success) {
145
+ client.setToken(res.data);
146
+ }
147
+ return res;
148
+ },
149
+ async loginByWeApp({
150
+ code
151
+ } = {}) {
152
+ const res = await client.request("/login/weapp", {
153
+ method: "POST",
154
+ body: JSON.stringify({
155
+ code: code
156
+ })
157
+ });
158
+ if (res.success) {
159
+ client.setToken(res.data);
160
+ }
161
+ return res;
162
+ },
163
+ async getUser() {
164
+ return client.request("/getUserInfo", {
165
+ method: "GET"
166
+ });
167
+ },
168
+ async register(data) {
169
+ return await client.request("/login/register", {
170
+ method: "POST",
171
+ body: JSON.stringify(data)
172
+ });
173
+ },
174
+ async logout() {
175
+ client.setToken(null);
176
+ return client.request("/logout", {
177
+ method: "GET"
178
+ });
179
+ },
180
+ async loginOauth2Uri({
181
+ provider
182
+ } = {}) {
183
+ return await client.request(`/oauth2/authorize/` + provider, {
184
+ method: "GET"
185
+ });
186
+ }
187
+ };
188
+ }
189
+
190
+ class QueryBuilder {
191
+ constructor(client, table) {
192
+ this.client = client;
193
+ this.table = table;
194
+ this._body = null;
195
+ this._method = "";
196
+ }
197
+ list() {
198
+ return new FilterBuilder(this.client, this.table, 'list');
199
+ }
200
+ page() {
201
+ return new FilterBuilder(this.client, this.table, 'page');
202
+ }
203
+ get() {
204
+ return new FilterBuilder(this.client, this.table, 'get');
205
+ }
206
+ insert() {
207
+ return new DataBuilder(this.client, this.table, "add");
208
+ }
209
+ update() {
210
+ return new DataBuilder(this.client, this.table, "update");
211
+ }
212
+ delete() {
213
+ return new FilterBuilder(this.client, this.table, "delete");
214
+ }
215
+ }
216
+ class FilterBuilder {
217
+ constructor(client, table, method) {
218
+ this.client = client;
219
+ this.table = table;
220
+ this.method = method;
221
+ this.filters = {};
222
+ }
223
+
224
+ // 内部统一方法
225
+ _addFilter(field, operator, value) {
226
+ if (!this.filters.hasOwnProperty(field)) {
227
+ this.filters[field] = {};
228
+ }
229
+ this.filters[field][operator] = value;
230
+ return this; // 支持链式调用
231
+ }
232
+
233
+ // =
234
+ eq(field, value) {
235
+ return this._addFilter(field, "eq", value);
236
+ }
237
+
238
+ // !=
239
+ neq(field, value) {
240
+ return this._addFilter(field, "neq", value);
241
+ }
242
+
243
+ // >
244
+ gt(field, value) {
245
+ return this._addFilter(field, "gt", value);
246
+ }
247
+
248
+ // >=
249
+ gte(field, value) {
250
+ return this._addFilter(field, "gte", value);
251
+ }
252
+
253
+ // <
254
+ lt(field, value) {
255
+ return this._addFilter(field, "lt", value);
256
+ }
257
+
258
+ // <=
259
+ lte(field, value) {
260
+ return this._addFilter(field, "lte", value);
261
+ }
262
+ like(file, value) {
263
+ return this._addFilter(file, "like", value);
264
+ }
265
+
266
+ // in
267
+ in(field, values) {
268
+ return this._addFilter(field, "in", values);
269
+ }
270
+
271
+ // between
272
+ between(field, values) {
273
+ return this._addFilter(field, "between", values);
274
+ }
275
+
276
+ // 顶层 or
277
+ or(callback) {
278
+ if (!this.filters.or) {
279
+ this.filters.or = [];
280
+ }
281
+ const subBuilder = new FilterBuilder(this.client, this.table, "or");
282
+ callback(subBuilder);
283
+ this.filters.or.push(subBuilder.build());
284
+ return this;
285
+ }
286
+ limit(count) {
287
+ return this;
288
+ }
289
+ page(number, size) {
290
+ this.filters.current = number;
291
+ this.filters.pageSize = size;
292
+ return this;
293
+ }
294
+ order(field, directionOrOptions = "asc") {
295
+ if (!this.filters.order_by) {
296
+ this.filters.order_by = [];
297
+ }
298
+ let direction = "asc";
299
+ if (typeof directionOrOptions === "string") {
300
+ direction = directionOrOptions.toLowerCase();
301
+ } else if (typeof directionOrOptions === "object" && directionOrOptions !== null) {
302
+ if ("ascending" in directionOrOptions) {
303
+ direction = directionOrOptions.ascending ? "asc" : "desc";
304
+ } else if ("direction" in directionOrOptions) {
305
+ direction = directionOrOptions.direction.toLowerCase();
306
+ }
307
+ }
308
+ this.filters.order_by.push({
309
+ field,
310
+ direction
311
+ });
312
+ return this;
313
+ }
314
+ build() {
315
+ return this.filters;
316
+ }
317
+ async _execute() {
318
+ return await this.client.request(`/api/data/invoke?table=${this.table}&method=${this.method}`, {
319
+ method: "POST",
320
+ body: this.filters ? JSON.stringify(this.filters) : undefined
321
+ });
322
+ }
323
+ then(resolve, reject) {
324
+ this._execute().then(resolve, reject);
325
+ }
326
+ }
327
+ class DataBuilder extends FilterBuilder {
328
+ constructor(client, table, method) {
329
+ super(client, table, method);
330
+ this.data = {};
331
+ }
332
+ values(data) {
333
+ this.data = {
334
+ ...data
335
+ };
336
+ return this;
337
+ }
338
+ set(data) {
339
+ this.data = {
340
+ ...data
341
+ };
342
+ return this;
343
+ }
344
+ build() {
345
+ return {
346
+ ...this.filters,
347
+ ...this.data
348
+ };
349
+ }
350
+ async _execute() {
351
+ return await this.client.request(`/api/data/invoke?table=${this.table}&method=${this.method}`, {
352
+ method: "POST",
353
+ body: JSON.stringify(this.build())
354
+ });
355
+ }
356
+ then(resolve, reject) {
357
+ this._execute().then(resolve, reject);
358
+ }
359
+ }
360
+ function dbModule(client) {
361
+ return {
362
+ from(table) {
363
+ return new QueryBuilder(client, table);
364
+ }
365
+ };
366
+ }
367
+
368
+ class ApiBuilder {
369
+ constructor(client, apiName) {
370
+ this.client = client;
371
+ this.apiName = apiName;
372
+ this._params = {};
373
+ this._headers = {};
374
+ this._method = "POST";
375
+ }
376
+ param(key, value) {
377
+ this._params[key] = value;
378
+ return this;
379
+ }
380
+ params(obj) {
381
+ Object.assign(this._params, obj);
382
+ return this;
383
+ }
384
+ header(key, value) {
385
+ this._headers[key] = value;
386
+ return this;
387
+ }
388
+ headers(obj) {
389
+ Object.assign(this._headers, obj);
390
+ return this;
391
+ }
392
+ async _execute() {
393
+ const body = JSON.stringify(this._params);
394
+ const url = `/api/${this.apiName}`;
395
+ return await this.client.request(url, {
396
+ method: this._method,
397
+ headers: this._headers,
398
+ body
399
+ });
400
+ }
401
+ then(resolve, reject) {
402
+ this._execute().then(resolve, reject);
403
+ }
404
+ }
405
+ function apiModule(client) {
406
+ return {
407
+ call(apiName) {
408
+ return new ApiBuilder(client, apiName);
409
+ }
410
+ };
411
+ }
412
+
413
+ class ComparisonBuilder {
414
+ static API_MAP = {
415
+ search: "/api/bijia_spu_search",
416
+ compare: "/api/bijia_spu_goods_search"
417
+ };
418
+ constructor(client, type) {
419
+ this.client = client;
420
+ this._params = {};
421
+ this.type = type;
422
+ }
423
+ keyword(keyword) {
424
+ this._params.query = keyword;
425
+ return this;
426
+ }
427
+
428
+ // 通用参数设置
429
+ setParams(params = {}) {
430
+ Object.assign(this._params, params);
431
+ return this;
432
+ }
433
+
434
+ // 切换查询类型
435
+ type(type) {
436
+ if (!ComparisonBuilder.API_MAP[type]) {
437
+ throw new Error(`Unsupported comparison type: ${type}`);
438
+ }
439
+ this.type = type;
440
+ return this;
441
+ }
442
+ async _execute() {
443
+ const url = ComparisonBuilder.API_MAP[this.type];
444
+ return await this.client.request(url, {
445
+ method: "POST",
446
+ body: JSON.stringify(this._params)
447
+ });
448
+ }
449
+ then(resolve, reject) {
450
+ this._execute().then(resolve, reject);
451
+ }
452
+ }
453
+ function comparisonModule(client) {
454
+ return {
455
+ searchProduct() {
456
+ return new ComparisonBuilder(client, "search");
457
+ },
458
+ findLowestPrice() {
459
+ return new ComparisonBuilder(client, "compare");
460
+ }
461
+ };
462
+ }
463
+
464
+ class Pdf2ImageBuilder {
465
+ constructor(client) {
466
+ this.client = client;
467
+ this._params = {};
468
+ this._taskId = null;
469
+ this._pollingInterval = 2000; // 默认2秒轮询间隔
470
+ this._maxRetries = 30; // 默认最大重试次数
471
+ }
472
+ url(url) {
473
+ this._params.url = url;
474
+ //给个默认值
475
+ this._params.format = "pdf-to-image";
476
+ return this;
477
+ }
478
+ format(format = "pdf-to-image") {
479
+ this._params.format = format;
480
+ return this;
481
+ }
482
+ pollingInterval(interval) {
483
+ this._pollingInterval = interval;
484
+ return this;
485
+ }
486
+ maxRetries(maxRetries) {
487
+ this._maxRetries = maxRetries;
488
+ return this;
489
+ }
490
+ async createTask() {
491
+ if (!this._params.url) {
492
+ throw new Error('PDF文件URL不能为空');
493
+ }
494
+ const response = await this.client.request("/api/pdf2image", {
495
+ method: "POST",
496
+ body: JSON.stringify({
497
+ url: this._params.url,
498
+ format: this._params.format
499
+ })
500
+ });
501
+ this._taskId = response.data;
502
+ return response;
503
+ }
504
+ async queryTask(taskId = null) {
505
+ const id = taskId || this._taskId;
506
+ if (!id) {
507
+ throw new Error('任务ID不能为空,请先创建任务');
508
+ }
509
+ return await this.client.request("/api/queryPDF2ImageTask", {
510
+ method: "POST",
511
+ body: JSON.stringify({
512
+ taskId: id
513
+ })
514
+ });
515
+ }
516
+ async convert() {
517
+ try {
518
+ // 第一步:创建任务
519
+ console.log("开始创建PDF转图片任务...");
520
+ const createRes = await this.createTask();
521
+ console.log("任务创建成功:", createRes);
522
+ const taskId = createRes.data;
523
+ if (!taskId) {
524
+ throw new Error('任务创建失败,未返回任务ID');
525
+ }
526
+
527
+ // 第二步:轮询查询任务状态
528
+ console.log("开始轮询查询任务状态...");
529
+ let retryCount = 0;
530
+ while (retryCount < this._maxRetries) {
531
+ const queryRes = await this.queryTask(taskId);
532
+ console.log(`第${retryCount + 1}次查询结果:`, queryRes);
533
+ const state = queryRes.data?.state;
534
+ if (state === 1) {
535
+ console.log("PDF转图片任务完成:", queryRes.data);
536
+ return queryRes;
537
+ }
538
+ if (state < 0) {
539
+ console.log("PDF转图片任务失败,状态码:", state);
540
+ return queryRes;
541
+ }
542
+ retryCount++;
543
+ if (retryCount < this._maxRetries) {
544
+ console.log(`等待${this._pollingInterval}ms后进行第${retryCount + 1}次查询...`);
545
+ await new Promise(resolve => setTimeout(resolve, this._pollingInterval));
546
+ }
547
+ }
548
+ throw new Error(`PDF转图片任务超时,已重试${this._maxRetries}次`);
549
+ } catch (error) {
550
+ console.error("PDF转图片失败:", error);
551
+ throw error;
552
+ }
553
+ }
554
+ then(resolve, reject) {
555
+ return this.convert().then(resolve, reject);
556
+ }
557
+ catch(reject) {
558
+ return this.convert().catch(reject);
559
+ }
560
+ }
561
+ function documentModule(client) {
562
+ return {
563
+ convertPdf() {
564
+ return new Pdf2ImageBuilder(client);
565
+ },
566
+ async quickConvert(params = {}) {
567
+ const builder = new Pdf2ImageBuilder(client);
568
+ if (params.url) builder.url(params.url);
569
+ if (params.format) builder.format(params.format);
570
+ if (params.pollingInterval) builder.pollingInterval(params.pollingInterval);
571
+ if (params.maxRetries) builder.maxRetries(params.maxRetries);
572
+ return await builder.convert();
573
+ }
574
+ };
575
+ }
576
+
577
+ class LogisticsBuilder {
578
+ constructor(client) {
579
+ this.client = client;
580
+ this._params = {};
581
+ }
582
+ company(company) {
583
+ this._params.com = company;
584
+ return this;
585
+ }
586
+ trackingNumber(trackingNumber) {
587
+ this._params.num = trackingNumber;
588
+ return this;
589
+ }
590
+ phone(phone) {
591
+ this._params.phone = phone;
592
+ return this;
593
+ }
594
+ _validateParams() {
595
+ if (!this._params.com) {
596
+ throw new Error('快递公司代码不能为空');
597
+ }
598
+ if (!this._params.num) {
599
+ throw new Error('快递单号不能为空');
600
+ }
601
+
602
+ // 顺丰快递必须提供手机号
603
+ if (this._params.com === 'shunfeng' || this._params.com === 'shunfengkuaiyun') {
604
+ if (!this._params.phone) {
605
+ throw new Error('顺丰快递必须提供手机号参数');
606
+ }
607
+ }
608
+ }
609
+ async track() {
610
+ this._validateParams();
611
+ return await this.client.request("/api/expressInquiry", {
612
+ method: "POST",
613
+ body: JSON.stringify({
614
+ com: this._params.com,
615
+ num: this._params.num,
616
+ resultv2: 4,
617
+ ...(this._params.phone ? {
618
+ phone: this._params.phone
619
+ } : {})
620
+ })
621
+ });
622
+ }
623
+ then(resolve, reject) {
624
+ return this.track().then(resolve, reject);
625
+ }
626
+ catch(reject) {
627
+ return this.track().catch(reject);
628
+ }
629
+ }
630
+ function logisticsModule(client) {
631
+ return {
632
+ trackPackage() {
633
+ return new LogisticsBuilder(client);
634
+ }
635
+ };
636
+ }
637
+
638
+ class LocationBuilder {
639
+ static LOCATION_MAP = {
640
+ "location": "/api/geocoder",
641
+ "address": "/api/geoaddress"
642
+ };
643
+ constructor(client, type) {
644
+ this.client = client;
645
+ this._params = {};
646
+ this.type = type;
647
+ }
648
+ latitude(latitude) {
649
+ this._params.latitude = latitude;
650
+ return this;
651
+ }
652
+ longitude(longitude) {
653
+ this._params.longitude = longitude;
654
+ return this;
655
+ }
656
+ address(address) {
657
+ this._params.address = address;
658
+ return this;
659
+ }
660
+ _validateLocationParams() {
661
+ if (!this._params.latitude || !this._params.longitude) {
662
+ throw new Error('经纬度参数不能为空');
663
+ }
664
+ }
665
+ _validateAddressParams() {
666
+ if (!this._params.address) {
667
+ throw new Error('地址参数不能为空');
668
+ }
669
+ }
670
+ _data() {
671
+ if (this.type === "location") {
672
+ this._validateLocationParams();
673
+ return {
674
+ location: `${this._params.latitude},${this._params.longitude}`
675
+ };
676
+ } else {
677
+ this._validateAddressParams();
678
+ return {
679
+ address: this._params.address
680
+ };
681
+ }
682
+ }
683
+ async _execute() {
684
+ const url = LocationBuilder.LOCATION_MAP[this.type];
685
+ const data = this._data();
686
+ let res = await this.client.request(url, {
687
+ method: "POST",
688
+ body: JSON.stringify(data)
689
+ });
690
+ // 把接口返回值中的 result 和 status 字段进行解构,放到 data 同级目录下
691
+ let result = res;
692
+ if ('data' in res && "result" in res.data) {
693
+ result.result = res.data.result;
694
+ result.result.latitude = res.data.result.location.lat;
695
+ result.result.longitude = res.data.result.location.lng;
696
+ result.status = res.data.status;
697
+ }
698
+ return result;
699
+ }
700
+ then(resolve, reject) {
701
+ this._execute().then(resolve, reject);
702
+ }
703
+ }
704
+ class CurrentLocationBuilder {
705
+ constructor(client) {
706
+ this.client = client;
707
+ }
708
+ async _execute() {
709
+ const res = await this.client.request("/api/amap_ip_location", {
710
+ method: "POST",
711
+ body: JSON.stringify({})
712
+ });
713
+
714
+ // === 解析 rectangle 计算中心点 ===
715
+ const rectangle = res?.data?.rectangle;
716
+ if (!rectangle) {
717
+ throw new Error("返回数据中缺少 rectangle 字段");
718
+ }
719
+ const [point1, point2] = rectangle.split(';');
720
+ const [lon1, lat1] = point1.split(',').map(Number);
721
+ const [lon2, lat2] = point2.split(',').map(Number);
722
+ const longitude = (lon1 + lon2) / 2;
723
+ const latitude = (lat1 + lat2) / 2;
724
+ return {
725
+ success: true,
726
+ latitude,
727
+ longitude,
728
+ speed: 0,
729
+ altitude: 0,
730
+ horizontalAccuracy: 1000
731
+ };
732
+ }
733
+ then(resolve, reject) {
734
+ this._execute().then(resolve, reject);
735
+ }
736
+ }
737
+ class DrivingBuilder {
738
+ constructor(client) {
739
+ this.client = client;
740
+ this._params = {};
741
+ }
742
+ from(lat, lng) {
743
+ this._params.from = {
744
+ lat,
745
+ lng
746
+ };
747
+ return this;
748
+ }
749
+ to(lat, lng) {
750
+ this._params.to = {
751
+ lat,
752
+ lng
753
+ };
754
+ return this;
755
+ }
756
+ decodePolyline(polyline) {
757
+ for (let i = 2; i < polyline.length; i++) {
758
+ polyline[i] = polyline[i - 2] + polyline[i] / 1000000;
759
+ }
760
+ return polyline;
761
+ }
762
+ async _execute() {
763
+ const {
764
+ from,
765
+ to
766
+ } = this._params;
767
+ if (!from || !to) throw new Error('必须提供起点和终点坐标');
768
+ const payload = {
769
+ from: `${from.lat},${from.lng}`,
770
+ to: `${to.lat},${to.lng}`
771
+ };
772
+ const res = await this.client.request("/api/driving", {
773
+ method: "POST",
774
+ body: JSON.stringify(payload)
775
+ });
776
+ const {
777
+ routes
778
+ } = res.data.result;
779
+ const paths = routes.map(route => {
780
+ const polyline = this.decodePolyline([...route.polyline]);
781
+ const steps = route.steps.map(step => {
782
+ const {
783
+ polyline_idx: [start, end]
784
+ } = step;
785
+ const polylines = [];
786
+ for (let i = start; i <= end; i += 2) {
787
+ polylines.push({
788
+ latitude: polyline[i],
789
+ longitude: polyline[i + 1]
790
+ });
791
+ }
792
+ return {
793
+ ...step,
794
+ polylines
795
+ };
796
+ });
797
+ return {
798
+ distance: route.distance,
799
+ duration: route.duration,
800
+ steps
801
+ };
802
+ });
803
+ return {
804
+ success: true,
805
+ data: {
806
+ paths
807
+ }
808
+ };
809
+ }
810
+ then(resolve, reject) {
811
+ this._execute().then(resolve, reject);
812
+ }
813
+ }
814
+ class NearBuilder {
815
+ constructor(client) {
816
+ this.client = client;
817
+ this._params = {};
818
+ }
819
+ lat(lat) {
820
+ this._params.lat = lat;
821
+ return this;
822
+ }
823
+ lng(lng) {
824
+ this._params.lng = lng;
825
+ return this;
826
+ }
827
+ radius(radius) {
828
+ this._params.radius = radius;
829
+ return this;
830
+ }
831
+ keyword(keyword) {
832
+ this._params.keyword = keyword;
833
+ return this;
834
+ }
835
+ async _execute() {
836
+ const {
837
+ lat,
838
+ lng,
839
+ radius = 1000,
840
+ keyword
841
+ } = this._params;
842
+ if (!lat || !lng) throw new Error('必须提供经纬度参数');
843
+ const payload = {
844
+ boundary: `nearby(${lat},${lng},${radius})`,
845
+ ...(keyword && {
846
+ keyword
847
+ })
848
+ };
849
+ const res = await this.client.request("/api/mapsearch", {
850
+ method: "POST",
851
+ body: JSON.stringify(payload)
852
+ });
853
+ const {
854
+ data
855
+ } = res.data;
856
+ const normalized = data.map(d => {
857
+ return {
858
+ ...d,
859
+ latitude: d.location.lat,
860
+ longitude: d.location.lng
861
+ };
862
+ });
863
+ return {
864
+ success: true,
865
+ data: normalized
866
+ };
867
+ }
868
+ then(resolve, reject) {
869
+ this._execute().then(resolve, reject);
870
+ }
871
+ }
872
+ function locationModule(client) {
873
+ return {
874
+ locationToAddress() {
875
+ return new LocationBuilder(client, "location");
876
+ },
877
+ addressToLocation() {
878
+ return new LocationBuilder(client, "address");
879
+ },
880
+ currentLocation() {
881
+ return new CurrentLocationBuilder(client);
882
+ },
883
+ driving() {
884
+ return new DrivingBuilder(client);
885
+ },
886
+ nearby() {
887
+ return new NearBuilder(client);
888
+ }
889
+ };
890
+ }
891
+
892
+ class TravelBuilder {
893
+ static API_MAP = {
894
+ train: "/api/queryTickets",
895
+ flight: "/api/queryFlight"
896
+ };
897
+ constructor(client, mode) {
898
+ this.client = client;
899
+ this.params = {};
900
+ this.mode = mode;
901
+ }
902
+ from(city) {
903
+ this.params.from = city;
904
+ return this;
905
+ }
906
+ to(city) {
907
+ this.params.to = city;
908
+ return this;
909
+ }
910
+ date(date) {
911
+ this.params.date = date;
912
+ return this;
913
+ }
914
+ async _execute() {
915
+ const url = TravelBuilder.API_MAP[this.mode];
916
+ return await this.client.request(url, {
917
+ method: "POST",
918
+ body: JSON.stringify(this.params)
919
+ });
920
+ }
921
+ then(resolve, reject) {
922
+ this._execute().then(resolve, reject);
923
+ }
924
+ }
925
+ function travelModule(client) {
926
+ return {
927
+ train() {
928
+ return new TravelBuilder(client, "train");
929
+ },
930
+ flight() {
931
+ return new TravelBuilder(client, "flight");
932
+ }
933
+ };
934
+ }
935
+
936
+ class RobotBuilder {
937
+ static API_MAP = {
938
+ feishu: "/api/feishuRobotText",
939
+ wechat: "/api/wechatRobotText"
940
+ };
941
+ constructor(client, mode) {
942
+ this.client = client;
943
+ this.params = {};
944
+ this.mode = mode;
945
+ }
946
+ content(content) {
947
+ this.params.content = content?.replace(/\r?\n/g, " ");
948
+ return this;
949
+ }
950
+ async _execute() {
951
+ const url = RobotBuilder.API_MAP[this.mode];
952
+ return await this.client.request(url, {
953
+ method: "POST",
954
+ body: JSON.stringify(this.params)
955
+ });
956
+ }
957
+ then(resolve, reject) {
958
+ this._execute().then(resolve, reject);
959
+ }
960
+ }
961
+ class MailBuilder {
962
+ constructor(client) {
963
+ this.client = client;
964
+ this.payload = {};
965
+ }
966
+ title(title) {
967
+ this.payload.title = title;
968
+ return this;
969
+ }
970
+ content(content) {
971
+ this.payload.content = content?.replace(/\r?\n/g, " ");
972
+ return this;
973
+ }
974
+ to(target) {
975
+ this.payload.to = target;
976
+ return this;
977
+ }
978
+ params(params = {}) {
979
+ this.payload.params = params;
980
+ return this;
981
+ }
982
+ async _execute() {
983
+ return await this.client.request('/common/mail/send', {
984
+ method: "POST",
985
+ body: JSON.stringify(this.payload)
986
+ });
987
+ }
988
+ then(resolve, reject) {
989
+ this._execute().then(resolve, reject);
990
+ }
991
+ }
992
+ function notificationModule(client) {
993
+ return {
994
+ feishuRobot() {
995
+ return new RobotBuilder(client, "feishu");
996
+ },
997
+ wechatRobot() {
998
+ return new RobotBuilder(client, "wechat");
999
+ },
1000
+ mail() {
1001
+ return new MailBuilder(client);
1002
+ }
1003
+ };
1004
+ }
1005
+
1006
+ class TextGenerateBuilder {
1007
+ static API_MAP = {
1008
+ text2pic: "/api/word2pic",
1009
+ text2tts: "/api/text/tts"
1010
+ };
1011
+ constructor(client, mode) {
1012
+ this.client = client;
1013
+ this.params = {
1014
+ model: "gemini-3-pro-image-preview"
1015
+ };
1016
+ this.mode = mode;
1017
+ }
1018
+ text(text) {
1019
+ this.params.text = text;
1020
+ return this;
1021
+ }
1022
+ model(model) {
1023
+ this.params.model = model;
1024
+ return this;
1025
+ }
1026
+ async _execute() {
1027
+ const url = TextGenerateBuilder.API_MAP[this.mode];
1028
+ return await this.client.request(url, {
1029
+ method: "POST",
1030
+ body: JSON.stringify(this.params)
1031
+ });
1032
+ }
1033
+ then(resolve, reject) {
1034
+ return this._execute().then(resolve, reject);
1035
+ }
1036
+ }
1037
+ class UploadBuilder {
1038
+ constructor(client) {
1039
+ this.client = client;
1040
+ }
1041
+ async uploadFile(url, formatter = "mp3", contentType = "audio/mpeg") {
1042
+ const response = await this.client.request("/common/uploadByUrl", {
1043
+ method: "POST",
1044
+ body: JSON.stringify({
1045
+ fileUrl: url,
1046
+ formatter: formatter,
1047
+ contentType: contentType
1048
+ })
1049
+ });
1050
+ console.log("uploadFile response:", response);
1051
+ return response;
1052
+ }
1053
+ }
1054
+ class AsyncTTSBuilder extends UploadBuilder {
1055
+ constructor(client) {
1056
+ super(client);
1057
+ this.params = {};
1058
+ }
1059
+ text(text) {
1060
+ this.params.text = text;
1061
+ return this;
1062
+ }
1063
+ speaker(speaker) {
1064
+ this.params.speaker = speaker;
1065
+ return this;
1066
+ }
1067
+ createTask() {
1068
+ const text = this.params.text;
1069
+ if (!text) throw new Error("文本内容不能为空");
1070
+ let speaker = this.params.speaker;
1071
+ if (!speaker || speaker === '') speaker = "zh_female_cancan_mars_bigtts";
1072
+ const url = "/api/ttsTask";
1073
+ let playLoad = {
1074
+ text: text,
1075
+ speaker: speaker
1076
+ };
1077
+ const response = this.client.request(url, {
1078
+ method: "POST",
1079
+ body: JSON.stringify(playLoad)
1080
+ });
1081
+ this._taskId = response.data;
1082
+ return response;
1083
+ }
1084
+ async queryTask(taskId = null) {
1085
+ const id = taskId || this._taskId;
1086
+ if (!id) {
1087
+ throw new Error('任务ID不能为空,请先创建任务');
1088
+ }
1089
+ const url = "/api/queryTts";
1090
+ let playLoad = {
1091
+ taskId: id
1092
+ };
1093
+ return await this.client.request(url, {
1094
+ method: "POST",
1095
+ body: JSON.stringify(playLoad)
1096
+ });
1097
+ }
1098
+ async _execute() {
1099
+ const createRes = await this.createTask();
1100
+ console.log("====TTS任务创建成功:====", createRes);
1101
+ const taskId = createRes.data.task_id;
1102
+ if (!taskId) {
1103
+ throw new Error('任务创建失败,未返回任务ID');
1104
+ }
1105
+ let status = 0;
1106
+ while (status !== 2) {
1107
+ const queryRes = await this.queryTask(taskId);
1108
+ status = queryRes.data?.task_status || 0;
1109
+ if (status === 2) {
1110
+ const res = await this.uploadFile(queryRes.data.audio_url);
1111
+ queryRes.data = res.data;
1112
+ return queryRes;
1113
+ }
1114
+ if (status === 3) return queryRes;
1115
+ await new Promise(resolve => setTimeout(resolve, 2000));
1116
+ }
1117
+ }
1118
+ then(resolve, reject) {
1119
+ return this._execute().then(resolve, reject);
1120
+ }
1121
+ }
1122
+ class ChatBuilder {
1123
+ constructor(client) {
1124
+ this.client = client;
1125
+ this.params = {};
1126
+ }
1127
+ text(text) {
1128
+ this.params.text = text;
1129
+ return this;
1130
+ }
1131
+ prompt(prompt) {
1132
+ this.params.prompt = prompt;
1133
+ return this;
1134
+ }
1135
+ conversationId(id) {
1136
+ this.params.conversationId = id;
1137
+ return this;
1138
+ }
1139
+ async _execute() {
1140
+ const {
1141
+ text,
1142
+ prompt = "",
1143
+ conversationId = ""
1144
+ } = this.params;
1145
+ const payload = {
1146
+ prompt: prompt,
1147
+ query: text,
1148
+ conversation_id: conversationId,
1149
+ user: this.client.getApiKey(),
1150
+ files: []
1151
+ };
1152
+ return await this.client.request('/api/AiAnalysis', {
1153
+ method: "POST",
1154
+ body: JSON.stringify(payload)
1155
+ });
1156
+ }
1157
+ then(resolve, reject) {
1158
+ this._execute().then(resolve, reject);
1159
+ }
1160
+ }
1161
+ class ImageChatBuilder extends ChatBuilder {
1162
+ constructor(client) {
1163
+ super(client);
1164
+ }
1165
+ url(url) {
1166
+ this.params.url = url;
1167
+ return this;
1168
+ }
1169
+ async _execute() {
1170
+ const {
1171
+ url,
1172
+ prompt,
1173
+ text,
1174
+ conversationId = ""
1175
+ } = this.params;
1176
+ const files = [{
1177
+ type: "image",
1178
+ transfer_method: "remote_url",
1179
+ url: url
1180
+ }];
1181
+ const payload = {
1182
+ prompt: prompt,
1183
+ query: text,
1184
+ conversation_id: conversationId,
1185
+ user: this.client.getApiKey(),
1186
+ files: url ? files : []
1187
+ };
1188
+ return await this.client.request('/api/AiAnalysis', {
1189
+ method: "POST",
1190
+ body: JSON.stringify(payload)
1191
+ });
1192
+ }
1193
+ then(resolve, reject) {
1194
+ this._execute().then(resolve, reject);
1195
+ }
1196
+ }
1197
+ class MediaBuilder extends UploadBuilder {
1198
+ static CREATE_API_MAP = {
1199
+ video: "/api/text2video",
1200
+ audio: "/api/text2music"
1201
+ };
1202
+ static QUERY_API_MAP = {
1203
+ video: "/api/queryVideo",
1204
+ audio: "/api/queryMusic"
1205
+ };
1206
+ constructor(client, mode) {
1207
+ super(client);
1208
+ this.params = {};
1209
+ this.mode = mode;
1210
+ this._taskId = null;
1211
+ }
1212
+ text(text) {
1213
+ this.params.text = text;
1214
+ return this;
1215
+ }
1216
+ createTask() {
1217
+ const text = this.params.text;
1218
+ if (!text) throw new Error("文本内容不能为空");
1219
+ const url = MediaBuilder.CREATE_API_MAP[this.mode];
1220
+ let playLoad = {};
1221
+ if (this.mode === 'video') {
1222
+ playLoad = {
1223
+ text: text
1224
+ };
1225
+ } else {
1226
+ playLoad = {
1227
+ prompt: this.cleanString(text)
1228
+ };
1229
+ }
1230
+ const response = this.client.request(url, {
1231
+ method: "POST",
1232
+ body: JSON.stringify(playLoad)
1233
+ });
1234
+ this._taskId = response.data;
1235
+ return response;
1236
+ }
1237
+ async queryTask(taskId = null) {
1238
+ const id = taskId || this._taskId;
1239
+ if (!id) {
1240
+ throw new Error('任务ID不能为空,请先创建任务');
1241
+ }
1242
+ const url = MediaBuilder.QUERY_API_MAP[this.mode];
1243
+ let playLoad = {};
1244
+ if (this.mode === 'video') {
1245
+ playLoad = {
1246
+ id: id
1247
+ };
1248
+ } else {
1249
+ playLoad = {
1250
+ TaskID: id
1251
+ };
1252
+ }
1253
+ return await this.client.request(url, {
1254
+ method: "POST",
1255
+ body: JSON.stringify(playLoad)
1256
+ });
1257
+ }
1258
+ async _execute() {
1259
+ const createRes = await this.createTask();
1260
+ console.log("任务创建成功:", createRes);
1261
+ const taskId = createRes.data;
1262
+ if (!taskId) {
1263
+ throw new Error('任务创建失败,未返回任务ID');
1264
+ }
1265
+ let status = 0;
1266
+ while (status !== 2) {
1267
+ const queryRes = await this.queryTask(taskId);
1268
+ status = queryRes.data?.Status || 0;
1269
+ if (status === 2) {
1270
+ if (this.mode === 'video') {
1271
+ const res = await this.uploadFile(queryRes.data.content.video_url, "mp4", "video/mp4");
1272
+ queryRes.data.content.video_url = res.data;
1273
+ } else {
1274
+ const res = await this.uploadFile(queryRes.data.SongDetail.AudioUrl, "mp3", "audio/mpeg");
1275
+ queryRes.data.SongDetail.AudioUrl = res.data;
1276
+ }
1277
+ return queryRes;
1278
+ }
1279
+ if (status === 3) return queryRes;
1280
+ await new Promise(resolve => setTimeout(resolve, 2000));
1281
+ }
1282
+ }
1283
+ then(resolve, reject) {
1284
+ this._execute().then(resolve, reject);
1285
+ }
1286
+ cleanString(str) {
1287
+ if (!str) return str;
1288
+ str = str.toString();
1289
+ str = str.replace(/[\n\r\t]+/g, ",");
1290
+ str = str.replace(/\s{2,}/g, ",");
1291
+ return str.trim();
1292
+ }
1293
+ }
1294
+ function aiModule(client) {
1295
+ return {
1296
+ textToImage() {
1297
+ return new TextGenerateBuilder(client, "text2pic");
1298
+ },
1299
+ textToSpeech() {
1300
+ return new AsyncTTSBuilder(client);
1301
+ },
1302
+ imageToText() {
1303
+ return new ImageChatBuilder(client);
1304
+ },
1305
+ chat() {
1306
+ return new ChatBuilder(client);
1307
+ },
1308
+ textToVideo() {
1309
+ return new MediaBuilder(client, "video");
1310
+ },
1311
+ textToAudio() {
1312
+ return new MediaBuilder(client, "audio");
1313
+ }
1314
+ };
1315
+ }
1316
+
1317
+ // 百度搜索
1318
+ // webSearch
1319
+ class BaiduSearchBuilder {
1320
+ static API_MAP = {
1321
+ web: "/api/webSearch",
1322
+ video: "/api/webSearch",
1323
+ image: "/api/webSearch"
1324
+ };
1325
+ constructor(client, type) {
1326
+ this.client = client;
1327
+ this._params = {
1328
+ type: type,
1329
+ top_k: 20,
1330
+ site: []
1331
+ };
1332
+ this._type = type;
1333
+ }
1334
+
1335
+ // 设置搜索关键词
1336
+ content(content) {
1337
+ this._params.content = content;
1338
+ return this;
1339
+ }
1340
+
1341
+ // 设置搜索类型
1342
+ type(type) {
1343
+ if (!BaiduSearchBuilder.API_MAP[type]) {
1344
+ throw new Error(`Unsupported search type: ${type}`);
1345
+ }
1346
+ this._type = type;
1347
+ this._params.type = type;
1348
+ return this;
1349
+ }
1350
+
1351
+ // 设置站点限制
1352
+ site(site) {
1353
+ if (!this._params.site) {
1354
+ this._params.site = [];
1355
+ }
1356
+
1357
+ // 如果没有传参数,返回当前实例但不添加空值
1358
+ if (site === undefined || site === null) {
1359
+ return this;
1360
+ }
1361
+ this._params.site.push(site);
1362
+ return this;
1363
+ }
1364
+ async _execute() {
1365
+ const url = BaiduSearchBuilder.API_MAP[this._type];
1366
+ return await this.client.request(url, {
1367
+ method: "POST",
1368
+ body: JSON.stringify(this._params)
1369
+ });
1370
+ }
1371
+ then(resolve, reject) {
1372
+ return this._execute().then(resolve, reject);
1373
+ }
1374
+ }
1375
+ function baiduSearchModule(client) {
1376
+ return {
1377
+ search() {
1378
+ return new BaiduSearchBuilder(client, "web");
1379
+ },
1380
+ // 网页搜索
1381
+ webSearch() {
1382
+ return new BaiduSearchBuilder(client, "web");
1383
+ },
1384
+ // 视频搜索
1385
+ videoSearch() {
1386
+ return new BaiduSearchBuilder(client, "video");
1387
+ },
1388
+ // 图片搜索
1389
+ imageSearch() {
1390
+ return new BaiduSearchBuilder(client, "image");
1391
+ }
1392
+ };
1393
+ }
1394
+
1395
+ /**
1396
+ * 简单的插件加载器
1397
+ * 支持外部插件挂载到client对象上
1398
+ */
1399
+
1400
+ class PluginLoader {
1401
+ constructor() {
1402
+ this.plugins = new Map();
1403
+ this.pluginModules = new Map();
1404
+ }
1405
+
1406
+ /**
1407
+ * 注册插件
1408
+ * @param {string} name - 插件名称
1409
+ * @param {Function|Object} pluginModule - 插件模块(可以是函数或对象)
1410
+ */
1411
+ register(name, pluginModule) {
1412
+ if (this.plugins.has(name)) {
1413
+ console.warn(`Plugin ${name} is already registered`);
1414
+ return;
1415
+ }
1416
+
1417
+ // 验证插件模块结构
1418
+ if (!this.validatePlugin(pluginModule)) {
1419
+ console.log(`Invalid plugin module for ${name}:`, {
1420
+ type: typeof pluginModule,
1421
+ value: pluginModule,
1422
+ constructor: pluginModule?.constructor?.name,
1423
+ keys: typeof pluginModule === 'object' ? Object.keys(pluginModule) : 'N/A'
1424
+ });
1425
+ throw new Error(`Invalid plugin module structure for ${name}`);
1426
+ }
1427
+ this.plugins.set(name, {
1428
+ name,
1429
+ module: pluginModule,
1430
+ initialized: false
1431
+ });
1432
+ console.log(`Plugin ${name} registered successfully`);
1433
+ }
1434
+
1435
+ /**
1436
+ * 验证插件模块结构
1437
+ * @param {Function|Object} pluginModule - 插件模块(可以是函数或对象)
1438
+ * @returns {boolean}
1439
+ */
1440
+ validatePlugin(pluginModule) {
1441
+ // 支持函数或对象两种形式
1442
+ // 排除 null(typeof null === 'object')
1443
+ return pluginModule !== null && pluginModule !== undefined && (typeof pluginModule === 'function' || typeof pluginModule === 'object' && !Array.isArray(pluginModule));
1444
+ }
1445
+
1446
+ /**
1447
+ * 初始化插件
1448
+ * @param {string} name - 插件名称
1449
+ * @param {BaaSClient} client - 客户端实例
1450
+ * @returns {Object} 插件模块实例
1451
+ */
1452
+ init(name, client) {
1453
+ const plugin = this.plugins.get(name);
1454
+ if (!plugin) {
1455
+ throw new Error(`Plugin ${name} not found`);
1456
+ }
1457
+
1458
+ // 判断插件模块类型
1459
+ let pluginInstance;
1460
+ if (typeof plugin.module === 'function' || typeof plugin.module === 'object') {
1461
+ pluginInstance = plugin.module;
1462
+ } else {
1463
+ throw new Error(`Invalid plugin module type for ${name}`);
1464
+ }
1465
+ plugin.initialized = true;
1466
+
1467
+ // 如果插件模块有初始化方法,调用它
1468
+ if (typeof pluginInstance.init === 'function') {
1469
+ pluginInstance.init();
1470
+ }
1471
+ return pluginInstance;
1472
+ }
1473
+
1474
+ /**
1475
+ * 获取所有已注册的插件名称
1476
+ * @returns {Array} 插件名称列表
1477
+ */
1478
+ getRegisteredPlugins() {
1479
+ return Array.from(this.plugins.keys());
1480
+ }
1481
+
1482
+ /**
1483
+ * 检查插件是否已注册
1484
+ * @param {string} name - 插件名称
1485
+ * @returns {boolean}
1486
+ */
1487
+ isRegistered(name) {
1488
+ return this.plugins.has(name);
1489
+ }
1490
+
1491
+ /**
1492
+ * 移除插件
1493
+ * @param {string} name - 插件名称
1494
+ */
1495
+ unregister(name) {
1496
+ if (this.plugins.has(name)) {
1497
+ this.plugins.delete(name);
1498
+ console.log(`Plugin ${name} unregistered`);
1499
+ }
1500
+ }
1501
+ }
1502
+
1503
+ // 全局插件加载器实例
1504
+ const pluginLoader = new PluginLoader();
1505
+
1506
+ class BitCoinBuilder {
1507
+ constructor(client) {
1508
+ this.client = client;
1509
+ this._params = {};
1510
+ }
1511
+ interval(interval) {
1512
+ this._params.interval = interval;
1513
+ return this;
1514
+ }
1515
+ vsCurrency(vsCurrency) {
1516
+ this._params.vsCurrency = vsCurrency;
1517
+ return this;
1518
+ }
1519
+ days(days) {
1520
+ this._params.days = days;
1521
+ return this;
1522
+ }
1523
+ async query() {
1524
+ return await this.client.request("/api/historytrend", {
1525
+ method: "POST",
1526
+ body: JSON.stringify({
1527
+ interval: this._params.interval,
1528
+ vs_currency: this._params.vsCurrency,
1529
+ days: this._params.days
1530
+ })
1531
+ });
1532
+ }
1533
+ then(resolve, reject) {
1534
+ return this.query().then(resolve, reject);
1535
+ }
1536
+ catch(reject) {
1537
+ return this.query().catch(reject);
1538
+ }
1539
+ }
1540
+ function bitCoinModule(client) {
1541
+ return {
1542
+ historytrend() {
1543
+ return new BitCoinBuilder(client);
1544
+ }
1545
+ };
1546
+ }
1547
+
1548
+ class GoogleSearchBuilder {
1549
+ static API_MAP = {
1550
+ googleSearch: "/api/googleSearch"
1551
+ };
1552
+ constructor(client) {
1553
+ this.client = client;
1554
+ this.params = {};
1555
+ }
1556
+ /**
1557
+ *
1558
+ */
1559
+ content(value) {
1560
+ this.params.content = value;
1561
+ return this;
1562
+ }
1563
+
1564
+ /**
1565
+ *
1566
+ */
1567
+ num(value) {
1568
+ this.params.num = value;
1569
+ return this;
1570
+ }
1571
+
1572
+ /**
1573
+ *
1574
+ */
1575
+ type(value) {
1576
+ this.params.type = value;
1577
+ return this;
1578
+ }
1579
+ async _execute() {
1580
+ const url = GoogleSearchBuilder.API_MAP.googleSearch;
1581
+ return await this.client.request(url, {
1582
+ method: "POST",
1583
+ body: JSON.stringify(this.params)
1584
+ });
1585
+ }
1586
+ then(resolve, reject) {
1587
+ this._execute().then(resolve, reject);
1588
+ }
1589
+ }
1590
+ function googleSearchModule(client) {
1591
+ return {
1592
+ /** 根据关键词来查询youtube里面的内容 */
1593
+ search() {
1594
+ return new GoogleSearchBuilder(client);
1595
+ }
1596
+ };
1597
+ }
1598
+
1599
+ /******************************************************************
1600
+ * ToutiaoBuilder
1601
+ * mode = 'list' 时:查询新闻列表
1602
+ * mode = 'content' 时:查询新闻详情
1603
+ ******************************************************************/
1604
+ class ToutiaoBuilder {
1605
+ static API_MAP = {
1606
+ list: '/api/queryToutiaoIndex',
1607
+ content: '/api/queryToutiaoContent',
1608
+ NewsByCategory: "/api/NewsByCategory",
1609
+ NewsByRegion: "/api/NewsByRegion"
1610
+ };
1611
+ constructor(client, mode) {
1612
+ this.client = client;
1613
+ this.mode = mode; // 'list' | 'content'
1614
+ this.params = {};
1615
+ }
1616
+
1617
+ /*========== 列表参数 ==========*/
1618
+ /** 频道:top、guonei、yule、tiyu … */
1619
+ type(value) {
1620
+ this.params.type = value;
1621
+ return this;
1622
+ }
1623
+
1624
+ /** 页码,默认 1,最大 50 */
1625
+ page(value) {
1626
+ this.params.page = value;
1627
+ return this;
1628
+ }
1629
+
1630
+ /** 每页条数,默认 30,最大 30 */
1631
+ page_size(value) {
1632
+ this.params.pageSize = value;
1633
+ return this;
1634
+ }
1635
+
1636
+ /** 是否只返回有详情的文章:1 是,0 否 */
1637
+ is_filter(value) {
1638
+ this.params.isFilter = value;
1639
+ return this;
1640
+ }
1641
+
1642
+ /*========== 详情参数 ==========*/
1643
+ /** 新闻唯一 ID */
1644
+ uniquekey(value) {
1645
+ this.params.uniquekey = value;
1646
+ return this;
1647
+ }
1648
+
1649
+ /**
1650
+ * 类别
1651
+ */
1652
+ category(value) {
1653
+ this.params.category = value;
1654
+ return this;
1655
+ }
1656
+
1657
+ /**
1658
+ * 地区
1659
+ */
1660
+ region(value) {
1661
+ this.params.region = value;
1662
+ return this;
1663
+ }
1664
+
1665
+ /*========== 执行 ==========*/
1666
+ async _execute() {
1667
+ const url = ToutiaoBuilder.API_MAP[this.mode];
1668
+ return await this.client.request(url, {
1669
+ method: 'POST',
1670
+ body: JSON.stringify(this.params)
1671
+ });
1672
+ }
1673
+ then(resolve, reject) {
1674
+ return this._execute().then(resolve, reject);
1675
+ }
1676
+ }
1677
+
1678
+ /******************************************************************
1679
+ * 工厂函数:toutiaoModule
1680
+ ******************************************************************/
1681
+ function toutiaoModule(client) {
1682
+ return {
1683
+ /** 获取新闻列表 */
1684
+ queryToutiaoIndex() {
1685
+ return new ToutiaoBuilder(client, 'list');
1686
+ },
1687
+ /** 获取新闻详情 */
1688
+ queryToutiaoContent() {
1689
+ return new ToutiaoBuilder(client, 'content');
1690
+ },
1691
+ /** 纽约时报按类别获取新闻列表 */
1692
+ queryNYNewsByCategory() {
1693
+ return new ToutiaoBuilder(client, 'NewsByCategory');
1694
+ },
1695
+ /** 纽约时报按地区获取新闻列表 */
1696
+ queryNYNewsByRegion() {
1697
+ return new ToutiaoBuilder(client, 'NewsByRegion');
1698
+ }
1699
+ };
1700
+ }
1701
+
1702
+ class WeatherBuilder {
1703
+ static API_MAP = {
1704
+ nationalWeather: "/api/nationalWeather",
1705
+ internationalWeather: "/api/weather"
1706
+ };
1707
+ constructor(client, mode) {
1708
+ this.client = client;
1709
+ this.mode = mode; // 'nationalWeather' | 'weather'
1710
+ this.params = {};
1711
+ }
1712
+
1713
+ /**
1714
+ * 要查询的城市名称/id,城市名称如:温州、上海、北京,需要utf8 urlencode
1715
+ */
1716
+ city(value) {
1717
+ if (this.mode !== 'nationalWeather') {
1718
+ console.warn('city 参数仅适用于 nationalWeather 模式');
1719
+ }
1720
+ this.params.city = value;
1721
+ return this;
1722
+ }
1723
+
1724
+ /**
1725
+ * 纬度坐标,范围:-90.0 到 90.0
1726
+ */
1727
+ latitude(value) {
1728
+ if (this.mode !== 'internationalWeather') {
1729
+ console.warn('latitude 参数仅适用于 internationalWeather 模式');
1730
+ }
1731
+ this.params['location.latitude'] = value;
1732
+ return this;
1733
+ }
1734
+
1735
+ /**
1736
+ * 经度坐标,范围:-180.0 到 180.0
1737
+ */
1738
+ longitude(value) {
1739
+ if (this.mode !== 'internationalWeather') {
1740
+ console.warn('longitude 参数仅适用于 internationalWeather 模式');
1741
+ }
1742
+ this.params['location.longitude'] = value;
1743
+ return this;
1744
+ }
1745
+ async _execute() {
1746
+ // 验证必要参数
1747
+ this._validateParams();
1748
+ const url = WeatherBuilder.API_MAP[this.mode];
1749
+ return await this.client.request(url, {
1750
+ method: "POST",
1751
+ body: JSON.stringify(this.params)
1752
+ });
1753
+ }
1754
+ _validateParams() {
1755
+ if (this.mode === 'nationalWeather') {
1756
+ if (!this.params.city) {
1757
+ throw new Error('nationalWeather 模式需要提供 city 参数');
1758
+ }
1759
+ } else if (this.mode === 'internationalWeather') {
1760
+ if (!this.params['location.latitude'] || !this.params['location.longitude']) {
1761
+ throw new Error('internationalWeather 模式需要提供 latitude 和 longitude 参数');
1762
+ }
1763
+ }
1764
+ }
1765
+ then(resolve, reject) {
1766
+ return this._execute().then(resolve, reject);
1767
+ }
1768
+ }
1769
+ function weatherModule(client) {
1770
+ return {
1771
+ /** 按城市查询天气 */
1772
+ queryNationalWeather() {
1773
+ return new WeatherBuilder(client, 'nationalWeather');
1774
+ },
1775
+ /** 按坐标查询天气 */
1776
+ queryWeather() {
1777
+ return new WeatherBuilder(client, 'internationalWeather');
1778
+ }
1779
+ };
1780
+ }
1781
+
1782
+ /******************************************************************
1783
+ * ExchangeBuilder
1784
+ * mode = 'frate' 外汇汇率
1785
+ * mode = 'rmbquot' 人民币牌价
1786
+ ******************************************************************/
1787
+ class ExchangeBuilder {
1788
+ static API_MAP = {
1789
+ frate: '/api/frate',
1790
+ rmbquot: '/api/rmbquot'
1791
+ };
1792
+ constructor(client, mode) {
1793
+ this.client = client;
1794
+ this.mode = mode; // 'frate' | 'rmbquot'
1795
+ this.params = {};
1796
+ }
1797
+
1798
+ /*========== 公共参数 ==========*/
1799
+ /** 返回格式:0 或 1,默认 0 */
1800
+ type(value) {
1801
+ this.params.type = value;
1802
+ return this;
1803
+ }
1804
+
1805
+ /*========== 人民币牌价专属 ==========*/
1806
+ /** 银行编码:1 招行、2 建行、3 中行、4 交行、5 农行,默认 3 */
1807
+ bank(value) {
1808
+ this.params.bank = value;
1809
+ return this;
1810
+ }
1811
+
1812
+ /*========== 执行 ==========*/
1813
+ async _execute() {
1814
+ const url = ExchangeBuilder.API_MAP[this.mode];
1815
+ return await this.client.request(url, {
1816
+ method: 'POST',
1817
+ body: JSON.stringify(this.params)
1818
+ });
1819
+ }
1820
+ then(resolve, reject) {
1821
+ return this._execute().then(resolve, reject);
1822
+ }
1823
+ }
1824
+
1825
+ /******************************************************************
1826
+ * 工厂函数:exchangeModule
1827
+ ******************************************************************/
1828
+ function exchangeModule(client) {
1829
+ return {
1830
+ /** 外汇汇率 */
1831
+ frate() {
1832
+ return new ExchangeBuilder(client, 'frate');
1833
+ },
1834
+ /** 人民币牌价 */
1835
+ rmbquot() {
1836
+ return new ExchangeBuilder(client, 'rmbquot');
1837
+ }
1838
+ };
1839
+ }
1840
+
1841
+ class QueryCaipuBuilder {
1842
+ static API_MAP = {
1843
+ queryCaipu: "/api/queryCaipu",
1844
+ RandomRecipes: "/api/RandomRecipes",
1845
+ MealPlan: "/api/MealPlan"
1846
+ };
1847
+ constructor(client, mode) {
1848
+ this.client = client;
1849
+ this.params = {};
1850
+ this.mode = mode;
1851
+ }
1852
+
1853
+ /**
1854
+ * 食材或菜名
1855
+ */
1856
+ word(value) {
1857
+ this.params.word = value;
1858
+ return this;
1859
+ }
1860
+
1861
+ /**
1862
+ * 返回数量
1863
+ */
1864
+ num(value) {
1865
+ this.params.num = value;
1866
+ return this;
1867
+ }
1868
+
1869
+ /**
1870
+ * 分页
1871
+ */
1872
+ page(value) {
1873
+ this.params.page = value;
1874
+ return this;
1875
+ }
1876
+
1877
+ /**
1878
+ * 随机食谱必须遵守的标签
1879
+ */
1880
+ tags(value) {
1881
+ this.params.tags = value;
1882
+ return this;
1883
+ }
1884
+
1885
+ /**
1886
+ * 要返回的随机食谱数量,必须介于 1 和 100 之间
1887
+ */
1888
+ number(value) {
1889
+ this.params.number = value;
1890
+ return this;
1891
+ }
1892
+
1893
+ /**
1894
+ * 计划时间
1895
+ */
1896
+ timeFrame(value) {
1897
+ this.params.timeFrame = value;
1898
+ return this;
1899
+ }
1900
+
1901
+ /**
1902
+ * 一天的目标卡路里
1903
+ */
1904
+ targetCalories(value) {
1905
+ this.params.targetCalories = value;
1906
+ return this;
1907
+ }
1908
+
1909
+ /**
1910
+ * 输入膳食计划必须遵循的饮食方式,例如“素食”、“纯素食”、“原始人饮食”等。
1911
+ */
1912
+ diet(value) {
1913
+ this.params.diet = value;
1914
+ return this;
1915
+ }
1916
+
1917
+ /**
1918
+ * 以逗号分隔的过敏原或成分列表,这些过敏原或成分必须排除在外。
1919
+ */
1920
+ exclude(value) {
1921
+ this.params.exclude = value;
1922
+ return this;
1923
+ }
1924
+ async _execute() {
1925
+ const url = QueryCaipuBuilder.API_MAP[this.mode];
1926
+ return await this.client.request(url, {
1927
+ method: "POST",
1928
+ body: JSON.stringify(this.params)
1929
+ });
1930
+ }
1931
+ then(resolve, reject) {
1932
+ return this._execute().then(resolve, reject);
1933
+ }
1934
+ }
1935
+ function queryCaipuModule(client) {
1936
+ return {
1937
+ /** 按食材查询菜谱 */
1938
+ queryIngredients() {
1939
+ return new QueryCaipuBuilder(client, "queryCaipu");
1940
+ },
1941
+ /** 按菜名查询菜谱 */
1942
+ queryDishName() {
1943
+ return new QueryCaipuBuilder(client, "queryCaipu");
1944
+ },
1945
+ /** 按食材和菜名查询菜谱 */
1946
+ query() {
1947
+ return new QueryCaipuBuilder(client, "queryCaipu");
1948
+ },
1949
+ /** 随机菜谱 */
1950
+ queryRandomRecipes() {
1951
+ return new QueryCaipuBuilder(client, "RandomRecipes");
1952
+ },
1953
+ /** 创建饮食计划 */
1954
+ queryMealPlan() {
1955
+ return new QueryCaipuBuilder(client, "MealPlan");
1956
+ }
1957
+ };
1958
+ }
1959
+
1960
+ class QueryCarPriceBuilder {
1961
+ static API_MAP = {
1962
+ queryCarPrice: "/api/queryCarPrice"
1963
+ };
1964
+ constructor(client) {
1965
+ this.client = client;
1966
+ this.params = {};
1967
+ }
1968
+ /**
1969
+ * 车辆具体信息,例如:奥迪A6L、小米SU7
1970
+ */
1971
+ search(value) {
1972
+ this.params.search = value;
1973
+ return this;
1974
+ }
1975
+ async _execute() {
1976
+ const url = QueryCarPriceBuilder.API_MAP.queryCarPrice;
1977
+ return await this.client.request(url, {
1978
+ method: "POST",
1979
+ body: JSON.stringify(this.params)
1980
+ });
1981
+ }
1982
+ then(resolve, reject) {
1983
+ return this._execute().then(resolve, reject);
1984
+ }
1985
+ }
1986
+ function queryCarPriceModule(client) {
1987
+ return {
1988
+ /** 按车名查询价格 */
1989
+ query() {
1990
+ return new QueryCarPriceBuilder(client);
1991
+ }
1992
+ };
1993
+ }
1994
+
1995
+ class QueryDiseaseBuilder {
1996
+ static API_MAP = {
1997
+ queryDiseaseByName: "/api/queryDiseaseByName"
1998
+ };
1999
+ constructor(client) {
2000
+ this.client = client;
2001
+ this.params = {};
2002
+ }
2003
+
2004
+ /**
2005
+ * 疾病名称
2006
+ */
2007
+ word(value) {
2008
+ this.params.word = value;
2009
+ return this;
2010
+ }
2011
+ async _execute() {
2012
+ const url = QueryDiseaseBuilder.API_MAP.queryDiseaseByName;
2013
+ return await this.client.request(url, {
2014
+ method: "POST",
2015
+ body: JSON.stringify(this.params)
2016
+ });
2017
+ }
2018
+ then(resolve, reject) {
2019
+ return this._execute().then(resolve, reject);
2020
+ }
2021
+ }
2022
+ function queryDiseaseModule(client) {
2023
+ return {
2024
+ /** 按疾病名称查询 */
2025
+ query() {
2026
+ return new QueryDiseaseBuilder(client);
2027
+ }
2028
+ };
2029
+ }
2030
+
2031
+ class CalorieBuilder {
2032
+ static API_MAP = {
2033
+ queryCalorie: "/api/queryCalorie"
2034
+ };
2035
+ constructor(client) {
2036
+ this.client = client;
2037
+ this.params = {};
2038
+ }
2039
+
2040
+ /**
2041
+ * 性别,1:男 2:女, 默认1
2042
+ */
2043
+ sex(value) {
2044
+ this.params.sex = value;
2045
+ return this;
2046
+ }
2047
+
2048
+ /**
2049
+ * 身高(CM), 支持最多1位小数; 如: 178
2050
+ */
2051
+ height(value) {
2052
+ this.params.height = value;
2053
+ return this;
2054
+ }
2055
+
2056
+ /**
2057
+ * 体重(KG), 支持最多1位小数; 如: 67.8
2058
+ */
2059
+ weight(value) {
2060
+ this.params.weight = value;
2061
+ return this;
2062
+ }
2063
+
2064
+ /**
2065
+ * 年龄(岁)
2066
+ */
2067
+ age(value) {
2068
+ this.params.age = value;
2069
+ return this;
2070
+ }
2071
+
2072
+ /**
2073
+ * 运动量等级:1:无运动习惯者/久坐族;2:轻度运动者/每周1至3天运动;3:中度运动者/每周3至5天运动;4:激烈运动者/每周6至7天运动;5:超激烈运动者/体力活工作/每天训练2次
2074
+ */
2075
+ level(value) {
2076
+ this.params.level = value;
2077
+ return this;
2078
+ }
2079
+ async _execute() {
2080
+ const url = CalorieBuilder.API_MAP.queryCalorie;
2081
+ return await this.client.request(url, {
2082
+ method: "POST",
2083
+ body: JSON.stringify(this.params)
2084
+ });
2085
+ }
2086
+ then(resolve, reject) {
2087
+ return this._execute().then(resolve, reject);
2088
+ }
2089
+ }
2090
+ function calorieModule(client) {
2091
+ return {
2092
+ query() {
2093
+ return new CalorieBuilder(client);
2094
+ }
2095
+ };
2096
+ }
2097
+
2098
+ class GoldpriceBuilder {
2099
+ static API_MAP = {
2100
+ nationalGoldprice: "/api/nationalGoldprice"
2101
+ };
2102
+ constructor(client) {
2103
+ this.client = client;
2104
+ this.params = {};
2105
+ }
2106
+ async _execute() {
2107
+ const url = GoldpriceBuilder.API_MAP.nationalGoldprice;
2108
+ return await this.client.request(url, {
2109
+ method: "POST",
2110
+ body: JSON.stringify(this.params)
2111
+ });
2112
+ }
2113
+ then(resolve, reject) {
2114
+ return this._execute().then(resolve, reject);
2115
+ }
2116
+ }
2117
+ function goldpriceModule(client) {
2118
+ return {
2119
+ /** 查询国内金价 */
2120
+ query() {
2121
+ return new GoldpriceBuilder(client);
2122
+ }
2123
+ };
2124
+ }
2125
+
2126
+ class YoutubeSearchBuilder {
2127
+ static API_MAP = {
2128
+ youtubeSearch: "/api/youtubeSearch"
2129
+ };
2130
+ constructor(client) {
2131
+ this.client = client;
2132
+ this.params = {};
2133
+ }
2134
+
2135
+ /**
2136
+ * 指定要搜索的查询词。
2137
+ */
2138
+ q(value) {
2139
+ this.params.q = value;
2140
+ return this;
2141
+ }
2142
+
2143
+ /**
2144
+ * 限制搜索查询仅检索特定类型的资源,可接受的值包括: video,channel,playlist
2145
+ */
2146
+ type(value) {
2147
+ this.params.type = value;
2148
+ return this;
2149
+ }
2150
+ async _execute() {
2151
+ const url = YoutubeSearchBuilder.API_MAP.youtubeSearch;
2152
+ return await this.client.request(url, {
2153
+ method: "POST",
2154
+ body: JSON.stringify(this.params)
2155
+ });
2156
+ }
2157
+ then(resolve, reject) {
2158
+ return this._execute().then(resolve, reject);
2159
+ }
2160
+ }
2161
+ function youtubeSearchModule(client) {
2162
+ return {
2163
+ /** 根据关键词来查询youtube里面的内容 */
2164
+ search() {
2165
+ return new YoutubeSearchBuilder(client);
2166
+ }
2167
+ };
2168
+ }
2169
+
2170
+ class TimezoneBuilder {
2171
+ static API_MAP = {
2172
+ queryTimezone: "/api/timezone"
2173
+ };
2174
+ constructor(client) {
2175
+ this.client = client;
2176
+ this.params = {};
2177
+ }
2178
+
2179
+ /**
2180
+ * 查询地点的经纬度坐标,格式为"纬度,经度"
2181
+ */
2182
+ location(value) {
2183
+ this.params.location = value;
2184
+ return this;
2185
+ }
2186
+
2187
+ /**
2188
+ * 查询时间的时间戳(秒数),用于确定当时的时区规则(考虑历史时区变化)
2189
+ */
2190
+ timestamp(value) {
2191
+ this.params.timestamp = value;
2192
+ return this;
2193
+ }
2194
+ async _execute() {
2195
+ const url = TimezoneBuilder.API_MAP.queryTimezone;
2196
+ return await this.client.request(url, {
2197
+ method: "POST",
2198
+ body: JSON.stringify(this.params)
2199
+ });
2200
+ }
2201
+ then(resolve, reject) {
2202
+ return this._execute().then(resolve, reject);
2203
+ }
2204
+ }
2205
+ function timezoneModule(client) {
2206
+ return {
2207
+ search() {
2208
+ return new TimezoneBuilder(client);
2209
+ }
2210
+ };
2211
+ }
2212
+
2213
+ class QueryScenicBuilder {
2214
+ static API_MAP = {
2215
+ queryNationalScenic: "/api/queryNationalScenic",
2216
+ restaurantsSearch: "/api/restaurantsSearch",
2217
+ hotelsSearch: "/api/hotelsSearch",
2218
+ attractionSearch: "/api/attractionSearch"
2219
+ };
2220
+ constructor(client, model) {
2221
+ this.client = client;
2222
+ this.params = {};
2223
+ this.model = model;
2224
+ }
2225
+
2226
+ /**
2227
+ * 景区关键字
2228
+ */
2229
+ word(value) {
2230
+ this.params.word = value;
2231
+ return this;
2232
+ }
2233
+
2234
+ /**
2235
+ * 返回数量
2236
+ */
2237
+ num(value) {
2238
+ this.params.num = value;
2239
+ return this;
2240
+ }
2241
+
2242
+ /**
2243
+ * 翻页
2244
+ */
2245
+ page(value) {
2246
+ this.params.page = value;
2247
+ return this;
2248
+ }
2249
+
2250
+ /**
2251
+ * 按景点省份检索
2252
+ */
2253
+ province(value) {
2254
+ this.params.province = value;
2255
+ return this;
2256
+ }
2257
+
2258
+ /**
2259
+ * 按景点城市检索
2260
+ */
2261
+ city(value) {
2262
+ this.params.city = value;
2263
+ return this;
2264
+ }
2265
+
2266
+ /**
2267
+ * 查询参数:输入可以是以下几种形式之一:geoId、显示名称、网址
2268
+ */
2269
+ query(value) {
2270
+ this.params.query = value;
2271
+ return this;
2272
+ }
2273
+ async _execute() {
2274
+ const url = QueryScenicBuilder.API_MAP[this.model];
2275
+ return await this.client.request(url, {
2276
+ method: "POST",
2277
+ body: JSON.stringify(this.params)
2278
+ });
2279
+ }
2280
+ then(resolve, reject) {
2281
+ return this._execute().then(resolve, reject);
2282
+ }
2283
+ }
2284
+ function queryScenicModule(client) {
2285
+ return {
2286
+ /** 查询国内景区 */
2287
+ query() {
2288
+ return new QueryScenicBuilder(client, "queryNationalScenic");
2289
+ },
2290
+ /** 国外搜索餐厅 */
2291
+ queryRestaurantsSearch() {
2292
+ return new QueryScenicBuilder(client, "restaurantsSearch");
2293
+ },
2294
+ /** 国外搜索酒店 */
2295
+ queryHotelsSearch() {
2296
+ return new QueryScenicBuilder(client, "hotelsSearch");
2297
+ },
2298
+ /** 国外搜索景点 */
2299
+ queryAttractionSearch() {
2300
+ return new QueryScenicBuilder(client, "attractionSearch");
2301
+ }
2302
+ };
2303
+ }
2304
+
2305
+ /******************************************************************
2306
+ * FootballBuilder
2307
+ * mode = 'queryFootballMatch' 足球赛程查询
2308
+ * mode = 'footballRank' 足球排名查询
2309
+ ******************************************************************/
2310
+ class FootballBuilder {
2311
+ static API_MAP = {
2312
+ queryFootballMatch: "/api/queryFootballMatch",
2313
+ footballRank: "/api/footballRank"
2314
+ };
2315
+ constructor(client, mode) {
2316
+ this.client = client;
2317
+ this.mode = mode; // 'queryFootballMatch' | 'footballRank'
2318
+ this.params = {};
2319
+ }
2320
+
2321
+ /**
2322
+ * 足球联赛类型, 可选: jiangsu(江苏城市足球联赛、苏超) xijia(西甲) dejia(德甲) yingchao(英超) yijia(意甲) fajia(法甲) zhongchao(中超)
2323
+ */
2324
+ type(value) {
2325
+ this.params.type = value;
2326
+ return this;
2327
+ }
2328
+
2329
+ /*========== 执行 ==========*/
2330
+ async _execute() {
2331
+ const url = FootballBuilder.API_MAP[this.mode];
2332
+ return await this.client.request(url, {
2333
+ method: "POST",
2334
+ body: JSON.stringify(this.params)
2335
+ });
2336
+ }
2337
+ then(resolve, reject) {
2338
+ return this._execute().then(resolve, reject);
2339
+ }
2340
+ }
2341
+
2342
+ /******************************************************************
2343
+ * 工厂函数:footballModule
2344
+ ******************************************************************/
2345
+ function footballModule(client) {
2346
+ return {
2347
+ /** 足球赛程查询 */
2348
+ match() {
2349
+ return new FootballBuilder(client, 'queryFootballMatch');
2350
+ },
2351
+ /** 足球排名查询 */
2352
+ rank() {
2353
+ return new FootballBuilder(client, 'footballRank');
2354
+ }
2355
+ };
2356
+ }
2357
+
2358
+ /******************************************************************
2359
+ * StockBuilder
2360
+ * mode = 'hsStock' 沪深股票查询
2361
+ * mode = 'hkStock' 港股查询
2362
+ * mode = 'usaStock' 美股查询
2363
+ ******************************************************************/
2364
+ class StockBuilder {
2365
+ static API_MAP = {
2366
+ hsStock: "/api/hsStock",
2367
+ usaStock: "/api/usaStock",
2368
+ usaall: "/api/usaall",
2369
+ szall: "/api/szall",
2370
+ shall: "/api/shall"
2371
+ };
2372
+ constructor(client, mode) {
2373
+ this.client = client;
2374
+ this.mode = mode; // 'hsStock' | 'hkStock' | 'usaStock' | 'hkall'
2375
+ this.params = {};
2376
+ }
2377
+
2378
+ /**
2379
+ * 股票编号,上海股市以sh开头,深圳股市以sz开头如:sh601009
2380
+ * (type为0或者1时gid不传,仅适用于沪深股票查询)
2381
+ */
2382
+ symbol(value) {
2383
+ this.params.gid = value;
2384
+ return this;
2385
+ }
2386
+
2387
+ /**
2388
+ * 0代表上证综合指数,1代表深证成份指数
2389
+ * (输入此字段时,gid字段不起作用,仅适用于沪深股票查询)
2390
+ */
2391
+ type(value) {
2392
+ this.params.type = value;
2393
+ return this;
2394
+ }
2395
+
2396
+ /**
2397
+ * a表示A股,b表示B股,默认所有,仅适用沪深股市列表
2398
+ */
2399
+ stock(value) {
2400
+ this.params.stock = value;
2401
+ return this;
2402
+ }
2403
+
2404
+ /**
2405
+ * 第几页,默认第1页(每页20条)
2406
+ * (仅适用于港股列表、美股列表查询)
2407
+ */
2408
+ page(value) {
2409
+ this.params.page = value;
2410
+ return this;
2411
+ }
2412
+
2413
+ /*========== 执行 ==========*/
2414
+ async _execute() {
2415
+ const url = StockBuilder.API_MAP[this.mode];
2416
+ return await this.client.request(url, {
2417
+ method: "POST",
2418
+ body: JSON.stringify(this.params)
2419
+ });
2420
+ }
2421
+ then(resolve, reject) {
2422
+ return this._execute().then(resolve, reject);
2423
+ }
2424
+ }
2425
+
2426
+ /******************************************************************
2427
+ * 工厂函数:stockModule
2428
+ ******************************************************************/
2429
+ function stockModule(client) {
2430
+ return {
2431
+ /** 沪深股票查询 */
2432
+ queryHs() {
2433
+ return new StockBuilder(client, 'hsStock');
2434
+ },
2435
+ /** 港股查询 */
2436
+ queryHk() {
2437
+ return new StockHkBuilder(client, 'hkStock');
2438
+ },
2439
+ /** 美股查询 */
2440
+ queryUsa() {
2441
+ return new StockBuilder(client, 'usaStock');
2442
+ },
2443
+ /** 港股列表查询 */
2444
+ queryHkAll() {
2445
+ return new StockHkBuilder(client, 'hkall');
2446
+ },
2447
+ /** 美股列表查询 */
2448
+ queryUsaAll() {
2449
+ return new StockBuilder(client, 'usaall');
2450
+ },
2451
+ /** 深圳股市列表查询 */
2452
+ querySzAll() {
2453
+ return new StockBuilder(client, 'szall');
2454
+ },
2455
+ /** 上海股市列表查询 */
2456
+ queryShAll() {
2457
+ return new StockBuilder(client, 'shall');
2458
+ },
2459
+ /** 时间线查询 */
2460
+ queryTimeDaily() {
2461
+ return new InternationalStockBuilder(client, 'TimeDaily');
2462
+ },
2463
+ /** 货币汇率查询 */
2464
+ queryCurrencyExchange() {
2465
+ return new InternationalStockBuilder(client, 'CurrencyExchange');
2466
+ },
2467
+ /** 数字货币查询 */
2468
+ queryDigitalCurrencyDaily() {
2469
+ return new InternationalStockBuilder(client, 'DigitalCurrencyDaily');
2470
+ },
2471
+ /** 技术指标查询 */
2472
+ queryTechnicalIndicators() {
2473
+ return new InternationalStockBuilder(client, 'TechnicalIndicators');
2474
+ }
2475
+ };
2476
+ }
2477
+ class InternationalStockBuilder {
2478
+ static API_MAP = {
2479
+ TimeDaily: "/api/TimeDaily",
2480
+ CurrencyExchange: "/api/CurrencyExchange",
2481
+ DigitalCurrencyDaily: "/api/DigitalCurrencyDaily",
2482
+ TechnicalIndicators: "/api/TechnicalIndicators"
2483
+ };
2484
+ constructor(client, mode) {
2485
+ this.client = client;
2486
+ this.mode = mode;
2487
+ this.params = {};
2488
+ }
2489
+
2490
+ /**
2491
+ * 股票名称/数字货币/加密货币/证劵名称
2492
+ */
2493
+ symbol(value) {
2494
+ this.params.symbol = value;
2495
+ return this;
2496
+ }
2497
+
2498
+ /**
2499
+ * 至货币
2500
+ */
2501
+ to_currency(value) {
2502
+ this.params.to_currency = value;
2503
+ return this;
2504
+ }
2505
+
2506
+ /**
2507
+ * 来自货币
2508
+ */
2509
+ from_currency(value) {
2510
+ this.params.from_currency = value;
2511
+ return this;
2512
+ }
2513
+
2514
+ /**
2515
+ * 交易市场
2516
+ */
2517
+ market(value) {
2518
+ this.params.market = value;
2519
+ return this;
2520
+ }
2521
+
2522
+ /**
2523
+ * 时间段
2524
+ */
2525
+ time_period(value) {
2526
+ this.params.time_period = value;
2527
+ return this;
2528
+ }
2529
+
2530
+ /**
2531
+ * 间隔
2532
+ */
2533
+ interval(value) {
2534
+ this.params.interval = value;
2535
+ return this;
2536
+ }
2537
+
2538
+ /**
2539
+ * 系列类型
2540
+ */
2541
+ series_type(value) {
2542
+ this.params.series_type = value;
2543
+ return this;
2544
+ }
2545
+
2546
+ /*========== 执行 ==========*/
2547
+ async _execute() {
2548
+ const url = InternationalStockBuilder.API_MAP[this.mode];
2549
+ return await this.client.request(url, {
2550
+ method: "POST",
2551
+ body: JSON.stringify(this.params)
2552
+ });
2553
+ }
2554
+ then(resolve, reject) {
2555
+ return this._execute().then(resolve, reject);
2556
+ }
2557
+ }
2558
+ class StockHkBuilder {
2559
+ static API_MAP = {
2560
+ hkStock: "/api/hkStock",
2561
+ hkall: "/api/hkall"
2562
+ };
2563
+ constructor(client, mode) {
2564
+ this.client = client;
2565
+ this.mode = mode;
2566
+ this.params = {};
2567
+ }
2568
+
2569
+ /**
2570
+ * 股票代码,如:00001 为"长江实业"股票代码
2571
+ * (仅适用于港股查询)
2572
+ */
2573
+ symbol(value) {
2574
+ this.params.num = value;
2575
+ return this;
2576
+ }
2577
+
2578
+ /**
2579
+ * 第几页,默认第1页(每页20条)
2580
+ * (仅适用于港股列表、美股列表查询)
2581
+ */
2582
+ page(value) {
2583
+ this.params.page = value;
2584
+ return this;
2585
+ }
2586
+
2587
+ /*========== 执行 ==========*/
2588
+ async _execute() {
2589
+ const url = StockHkBuilder.API_MAP[this.mode];
2590
+ return await this.client.request(url, {
2591
+ method: "POST",
2592
+ body: JSON.stringify(this.params)
2593
+ });
2594
+ }
2595
+ then(resolve, reject) {
2596
+ return this._execute().then(resolve, reject);
2597
+ }
2598
+ }
2599
+
2600
+ class WineBuilder {
2601
+ static API_MAP = {
2602
+ SearchCocktail: "/api/SearchCocktail",
2603
+ ListPopularCocktails: "/api/ListPopularCocktails",
2604
+ ListMostLatestCocktails: "/api/ ListMostLatestCocktails",
2605
+ GetBeersDataByBreweryOrBrand: "/api/GetBeersDataByBreweryOrBrand",
2606
+ GetBeersDataByName: "/api/GetBeersDataByName"
2607
+ };
2608
+ constructor(client, model) {
2609
+ this.client = client;
2610
+ this.params = {};
2611
+ this.mode = model;
2612
+ }
2613
+ /**
2614
+ * 按名称搜索鸡尾酒配料
2615
+ */
2616
+ s(value) {
2617
+ this.params.s = value;
2618
+ return this;
2619
+ }
2620
+
2621
+ /**
2622
+ * 啤酒厂
2623
+ */
2624
+ brewery(value) {
2625
+ this.params.brewery = value;
2626
+ return this;
2627
+ }
2628
+
2629
+ /**
2630
+ * 名称
2631
+ */
2632
+ name(value) {
2633
+ this.params.name = value;
2634
+ return this;
2635
+ }
2636
+ async _execute() {
2637
+ const url = WineBuilder.API_MAP[this.mode];
2638
+ return await this.client.request(url, {
2639
+ method: "POST",
2640
+ body: JSON.stringify(this.params)
2641
+ });
2642
+ }
2643
+ then(resolve, reject) {
2644
+ this._execute().then(resolve, reject);
2645
+ }
2646
+ }
2647
+ function WineModule(client) {
2648
+ return {
2649
+ /** 根据名称查询鸡尾酒 */
2650
+ queryCocktail() {
2651
+ return new WineBuilder(client, 'SearchCocktail');
2652
+ },
2653
+ /** 获取最热门的鸡尾酒 */
2654
+ queryPopularCocktails() {
2655
+ return new WineBuilder(client, 'ListPopularCocktails');
2656
+ },
2657
+ /** 获取最新的鸡尾酒 */
2658
+ queryLatestCocktails() {
2659
+ return new WineBuilder(client, 'ListMostLatestCocktails');
2660
+ },
2661
+ /** 根据厂商获取啤酒数据 */
2662
+ queryBeersData() {
2663
+ return new WineBuilder(client, 'GetBeersDataByBreweryOrBrand');
2664
+ },
2665
+ /** 根据名称获取啤酒数据 */
2666
+ queryBeersDataByName() {
2667
+ return new WineBuilder(client, 'GetBeersDataByName');
2668
+ }
2669
+ };
2670
+ }
2671
+
2672
+ function createClient(config) {
2673
+ const client = new BaaSClient(config);
2674
+
2675
+ // 创建基础API对象
2676
+ const api = {
2677
+ setToken: token => client.setToken(token),
2678
+ getToken: () => client.getToken(),
2679
+ auth: authModule(client),
2680
+ db: dbModule(client),
2681
+ api: apiModule(client),
2682
+ comparison: comparisonModule(client),
2683
+ document: documentModule(client),
2684
+ logistics: logisticsModule(client),
2685
+ location: locationModule(client),
2686
+ travel: travelModule(client),
2687
+ notification: notificationModule(client),
2688
+ ai: aiModule(client),
2689
+ baidu: baiduSearchModule(client),
2690
+ bitcoin: bitCoinModule(client),
2691
+ google: googleSearchModule(client),
2692
+ news: toutiaoModule(client),
2693
+ weather: weatherModule(client),
2694
+ money: exchangeModule(client),
2695
+ caipu: queryCaipuModule(client),
2696
+ car: queryCarPriceModule(client),
2697
+ disease: queryDiseaseModule(client),
2698
+ calorie: calorieModule(client),
2699
+ goldprice: goldpriceModule(client),
2700
+ youtube: youtubeSearchModule(client),
2701
+ timezone: timezoneModule(client),
2702
+ scenic: queryScenicModule(client),
2703
+ football: footballModule(client),
2704
+ stock: stockModule(client),
2705
+ wine: WineModule(client)
2706
+ };
2707
+
2708
+ // 动态加载所有已注册的插件
2709
+ const registeredPlugins = pluginLoader.getRegisteredPlugins();
2710
+ registeredPlugins.forEach(pluginName => {
2711
+ try {
2712
+ const pluginInstance = pluginLoader.init(pluginName, client);
2713
+
2714
+ // 检查是否存在同名的默认模块
2715
+ if (api[pluginName]) {
2716
+ // 如果存在同名模块,进行合并
2717
+ console.warn(`Plugin "${pluginName}" conflicts with built-in module. ` + `Merging plugin methods into existing module.`);
2718
+ // 合并插件方法到现有模块
2719
+ Object.assign(api[pluginName], pluginInstance);
2720
+ } else {
2721
+ // 不存在同名模块,直接挂载
2722
+ api[pluginName] = pluginInstance;
2723
+ }
2724
+ } catch (error) {
2725
+ console.error(`Failed to load plugin ${pluginName}:`, error);
2726
+ }
2727
+ });
2728
+ return api;
2729
+ }
2730
+
2731
+ export { createClient, pluginLoader };