在架设完毕odoo 11的网站之后,第一次面临手机app该如何访问后台网站的问题,是不是模式类似asp.net mvc 那样的模式,或者还存在其他的访问方法,带着这个疑问与困惑,开始的我的研究学习之路。通过研究,初步得出一个结论,那就是实用odoo11作为后台的数据提供者,和以前的具体操作方式多一种不同的方式。
1.第一种方式,是需要在后台写controller的模式,这样自己配制路由,再去访问model类提供的方法,这种方式还没有去试验测试。
2.第二种方法,不需要自己再去写controller类,而是利用odoo框架自带的机制,前端需要做的是提供model类名method方法,以及相关参数,这种接口的方式最大化的利用了框架自身的机制,有点量身定做的感觉,同时还可以做到对外部访问者一定的保密。
下面开始具体的OdooJsonRpc类的整理。
定义类的基本成员,这个大部分参数是根据框架的情况设定的
private jsonRpcID: number = 0; private headers: Headers; private odoo_server: string; private http_auth: string; private list = "/web/database/list"; private get_list = "/web/database/get_list"; private jsonrpc = "/jsonrpc"; constructor(private http: Http, private utils: Utils) { this.http = http; }
设置相关成员参数的方法,比如网站地址,授权信息等
public init(configs: any) { this.odoo_server = configs.odoo_server; this.http_auth = configs.http_auth || null; } public setOdooServer(odoo_server: string) { this.odoo_server = odoo_server; } public setHttpAuth(http_auth: string) { this.http_auth = http_auth; }
接下来是设置请求后台参数时的格式,这里最大的好处是结合框架,动态的传递需要的参数,这里是整理成json的格式
/** * Builds a request for odoo server * @param url Odoo Server URL * @param params Object */ private buildRequest(url: String, params: any) { this.jsonRpcID += 1; return JSON.stringify({ jsonrpc: "2.0", method: "call", id: this.jsonRpcID, params: params, }); }
接下来是相对高一级别的请求方法,这里整合url地址和参数为json样式,所有访问后台的方法都要调用这个方法,很关键的一个基本方法。
/** * Sends a JSON request to the odoo server * @param url Url of odoo * @param params Object */ public sendRequest(url: string, params: Object): Promise<any> { let options = this.buildRequest(url, params); this.headers = new Headers({ 'Content-Type': 'application/json; charset=utf-8', }); let result = this.http.post(this.odoo_server + url, options, { headers: this.headers }) .toPromise() return result; }
下面的一些方法是对上面请求的一个具体的应用,同时也是app在登录后台中必须的一些系统方法。
/** * Gets the server info */ public getServerInfo() { return this.sendRequest("/web/webclient/version_info", {}); } /** * Gets the session info */ public getSessionInfo() { return this.sendRequest("/web/session/get_session_info", {}); } /** * Gets the Odoo Server Version Number */ public getServerVersionNumber(): Promise<number> { return this.getServerInfo().then((res: any): Promise<number> => { return new Promise<number>((resolve) => { resolve(JSON.parse(res._body)["result"]["server_version_info"][0]); }); }); } /** * Get the database list */ public getDbList(): Promise<string> { let dbParams = { context: {} } return this.getServerVersionNumber().then((data: number) => { if (data <= 8) { return this.sendRequest(this.get_list, dbParams); } else if (data == 9) { return this.sendRequest(this.jsonrpc, dbParams); } else { return this.sendRequest(this.list, dbParams); } }) } /** * Returns all modules that are installed in your database */ public modules(): Promise<string> { let params = { context: {} } return this.sendRequest("/web/session/modules", params) } /** * Login to the database * @param db Database name of odoo * @param login Username * @param password password */ public login(db: string, login: string, password: string) { let params = { db: db, login: login, password: password, base_location: this.odoo_server, context: {} }; return this.sendRequest("/web/session/authenticate", params) } /** * Check whether the session is live or not */ public check(): Promise<string> { let params = { context: this.getContext() } return this.sendRequest("/web/session/check", params) } /** * Destroy the session */ public destroy() { let params = { context: {} } return this.sendRequest("/web/session/destroy", params) }
以上是手机app访问后台网站,登录过程的体现,按这些基本上是可以测试app能否调用后台odoo的接口了。
这一步我们需要写一个Page类,测试登录的过程。首先是定义一些参数,比如http,https协议的选择,还有我们前面OdooJsonRpc类的依赖注入
private listForProtocol: Array<{ protocol: string}> = [] public perfectUrl: boolean = false public odooUrl public selectedProtocol private dbList: Array<{ dbName: string }> = [] private selectedDatabase private email private password constructor(public navCtrl: NavController, private alert: AlertController, public navParams: NavParams, private odooRpc: OdooJsonRpc, private loadingCtrl: LoadingController, private utils: Utils) { this.listForProtocol.push({ protocol: "http"}) this.listForProtocol.push({ protocol: "https"}) }
第二步,手机端检查url网站的正确性并从后台获取数据库的列表信息,这里开始正式进入于后台的交互 ,此步骤成功基本上意味着接口接近成功。注意我注释掉了红色的部分。如果访问成果,设置了参数perfectUrl为真,也即登录相关界面可以显示出来。
public checkUrl() { this.utils.presentLoading("Please Wait") this.odooRpc.init({ odoo_server: this.selectedProtocol + "://" + this.odooUrl //http_auth: 'username:password' // optional }) this.odooRpc.getDbList().then((dbList: any) => { this.perfectUrl = true this.utils.dismissLoading() this.fillData(dbList) }).catch((err: any) => { this.utils.presentAlert("Error", "You Entered a wrong Odoo URL", [{ text: "Ok" }]) this.utils.dismissLoading() }); } public fillData(res: any) { let body = JSON.parse(res._body) let json = body['result']; this.dbList.length = 0; for (var key in json) { this.dbList.push({ dbName: json[key] }); } }
执行之前的界面如下
输入网站地址之后,正确执行后的界面,显示出了输入账号和密码数据库的选择
经过打包成apk的格式,在手机上测试成功通过,也就意味着ionic访问 odoo11网站接口初步成功。下一步就是研究如何访问网站具体业务的接口问题。在结束之前,放张ionic在浏览器测试不成功的截图,记得一定要打包再测试。
参考项目:https://github.com/mtfaroks/Odoo-JsonRpc-with-ionic3.x