闂傚倸鍊搁崐鎼佸磹妞嬪海鐭嗗〒姘e亾妤犵偛顦甸弫鎾绘偐閸愯弓鐢绘俊鐐€栭悧婊堝磻濞戙垹鍨傞柛宀€鍋涚痪褔鏌涢顐簻濞存粍鐗曢湁婵犲﹤鎳忛崵鈧梻鍥ь樀閺屻劌鈹戦崱妯烘闁荤姵鍔х换婵嬪蓟閿濆鍋勬繛鑼帛缂嶅牏绱撴担铏瑰笡闁烩晩鍨堕悰顔锯偓锝庡枟閸婇攱绻涢崼鐔奉嚋婵炲牆缍婂缁樻媴妞嬪簼瑕嗙紓鍌氱С閻掞妇绮嬪澶婇唶闁哄洨鍋熼悾鍝勨攽鎺抽崐鎰板磻閹剧粯鐓冮柦妯侯樈濡偓濡ょ姷鍋涢柊锝夊箠閻愬搫唯妞ゆ梻鎳撴禍鍓р偓骞垮劚閹冲寮ㄦ禒瀣厽婵妫楁禍婊兠瑰⿰鍫㈢暫婵﹨娅i幉鎾礋椤愩垹笑婵犵妲呴崑鍕偓姘煎櫍閸┾偓妞ゆ帊娴囨竟妯汇亜閿曞倷鎲鹃柛鈹惧亾濡炪倖宸婚崑鎾剁磼閻樿尙效鐎规洘娲熼弻鍡楊吋閸涱垳鏋冮梺鐟板悑閹矂鎮℃径宀€绀婇柡宥庡幗閻撱儵鏌i弴鐐测偓鍦偓姘炬嫹
时间:2021-04-09 10:21:21 所属分类:软件开发 浏览量: 194
近年来,随着信息技术的发展,工业软件架构开始从传统的 C /S 架构向 B /S 架构与混合架构转变[1 - 3],工业软件开发也从 Windows Native 向 electron 等跨平台桌面程序转变。与此同时,随着智能工厂、工业互联网的概念日益火热[4 - 5],移动应用在工业领域
濠电姷鏁告慨鎾儉婢舵劕绾ч幖瀛樻尭娴滈箖鏌¢崶銉ョ仼缁炬儳缍婇弻锝夋偄缁嬫妫嗗Δ鐘靛仦閹瑰洭寮诲☉婊庢Ъ濡炪們鍔岀换妯侯嚕椤愶箑纾兼繛鎴炵墧缁ㄥ姊洪崷顓炲妺闁搞劎鏁婚崺鈧い鎺戝€归弳顒傗偓瑙勬礃閸ㄥ潡鐛鈧顒勫Ψ閿旂粯缍岄梻鍌欐祰椤宕曢崗鍏煎弿闁靛牆顦介弫浣衡偓骞垮劚閹冲寮ㄦ禒瀣厽婵妫楁禍婊兠瑰⿰鍫㈢暫婵﹨娅i幉鎾礋椤愩垹笑婵犵妲呴崑鍕偓姘煎櫍閸┾偓妞ゆ帊娴囨竟妯汇亜閿曞倷鎲鹃柛鈹惧亾濡炪倖宸婚崑鎾剁磼閻樿尙效鐎规洘娲熼弻鍡楊吋閸涱垳鏋冮梺鐟板悑閹矂鎮℃径宀€绀婇柡宥庡幗閻撳繘鏌涢锝囩畺濠殿垰鍚嬬换娑㈠箻閹颁胶鍚嬮梺鍝勬湰濞茬喎鐣烽悡搴樻斀闁搞儜鍕典画闂備浇宕垫慨鐢稿礉韫囨稑绀堟繝闈涚墛瀹曞弶绻涢幋鐐殿暡閻庢碍姘ㄩ幉鍛婃償閿濆倸浜炬慨妯煎亾鐎氾拷
近年来,随着信息技术的发展,工业软件架构开始从传统的 C /S 架构向 B /S 架构与混合架构转变[1 - 3],工业软件开发也从 Windows Native 向 electron 等跨平台桌面程序转变。与此同时,随着智能工厂、工业互联网的概念日益火热[4 - 5],移动应用在工业领域的应用也呈现出增长之势[6]。目前市场上,基于 Android 操作系统的工业 PDA 与工业平板计算机最为主流,也有少量 Windows 操作系统、基于 Linux 内核的操作系统的工业平板计算机。在一些非防爆区域,基于 iOS( iPadOS) 的 iPad 也是一个常见的选择。作为开发者,如果同时面向所有平台开发原生应用势必会带来庞大的工作量,但是如果单纯使用 Web 端,则又缺少了很多原生功能。因此,许多开发者将目光转向了跨平台开发架构,例如 Flutter、React-Native 等。本文将以 Flutter 框架为基础,以在批量控制系统中的应用为例,阐述选择 Flutter 框架的缘由以及相关 Android 应用软件设计与开发过程。
1 Flutter 概述
Flutter 是谷歌开发并开源的跨平台 UI 框架,提供 Material 与 Cupertino 两套预定义的小部件。目前 Flutter 稳定版支持 Android、iOS( iPadOS) 操作系统。 Flutter 拥有基于 C/C + + 的 Skia 渲染引擎,配合 Dart VM 与 libtxt,实现了几近原生级别的用户体验。相比 React-Native、Cordova 等跨平台技术,Flutter 不需要额外的 JavaScript 桥,因而性能更好、UI 渲染更流畅[7]。 Flutter 使用了类似于 React、SwiftUI 的基于状态管理的声明式开发,提供支持热重载的 JIT 与高性能的 AOT 两种运行方式,为开发者提供了极大的便利。在跨平台开发中,与原生交互的问题往往是难以避免的。本文所述的应用于批量控制系统的工业移动应用软件属于业务密集型应用软件[8],对于原生功能的需求不强,因此十分适合使用跨平台框架开发。
2 软件设计
本文所述软件示例包含批量控制的基础功能,例如,批次查看、批次控制、批次操作等。但其设计在一定程度上拥有较大的可拓展性,以满足日后不断增加的需求。
2. 1 架构设计软件基本架构如图 1 所示,软件从结构上可以分为 Flutter 部分和 Android 原生部分。Android 部分实现了提供平台专有特性的封装,比如接入特定厂家提供的外设等。
Flutter 部分包括 SDK 层、工具层以及业务层。其中: SDK 层提供 Flutter 与 Dart 的基础功能,包括 UI 组件、渲染、IO、数据转换、异步操作、原生交互等。工具层接入了一些第三方模块,并且封装了部分 SDK 的基础功能为业务层所用,具体模块如表 1 所示。业务层通过工具层提供的接口,实现各种与批量 Web 服务器之间的数据交换接口、用于全局状态管理的 Bloc,以及所有 UI 与页面路由。
2. 2 全局状态管理与业务逻辑分离 Flutter 提供了组件级的状 态管理 ( Ephemeral State) 和基于 Provider 的 ChangeNotifier 的跨组件状态管理。前者实现全局状态管理需要大量的、重复的回调函数,后者不方便业务逻辑封装。针对这些问题,本文选用了 Bloc 作为全局状态管理工具。 Bloc 意为业务逻辑组件( Business Logic Component) ,旨在将 UI 与业务解耦,提高代码的可维护性。遵循 Bloc 模式还有利于增强可测试性与可重用性,提高可拓展性与代码可读性。示例应用的 Bloc 层设计如图 2 所示。业务逻辑层包含身份验证模块、批次管理模块、批次控制模块、历史批次模块等,每一个模块对应一个 Bloc。以身份验证模块为例,身份验证模块对应 Authentication Bloc,包含一个用于映射事件到状态的流生成器 mapEventToState 与一个用于存储身份验证信息的 Authentication Repository。其中 mapEventToState 简易流程如图 3 所示。 Bloc 通过 BlocProvider 或 MultiBlocProvider 将 Bloc 注入 BuildContext 向子组件提供 Bloc。在子组件中使用 BlocBuilder、BlocListener、MultiBlocListener 或 BlocConsumer 获取或监听 State 变化,从而对组件进行更新。
2. 3 REST API 与 Protobuf REST API 来自于批量 Web 服务器,Web 服务器往往承载着面向多端的数据交互任务。然而对于不同平台,开发者往往需要再专门开发特定语言专用的 SDK 或适配器,这项工作既枯燥又繁琐。Protobuf 正是目前解决这一问题的最好方法,开发者只需要编写 Protobuf 消息,使用 protoc 及相关插件即可生成多种语言的消息序列化与反序列化的代码。Protobuf 还提供了序列化为二进制或 JSON 格式两个选择,使用二进制会大大提升传输效率与解析效率,使用 JSON 则可以方便调试、增加可读性[9]。
2. 4 注入依赖 Bloc 依赖于 Repository,API 依赖于 HTTP 客户端,数据持久化依赖于 shared_preferences,依赖与被依赖的关系在程序中经常出现,过渡的依赖会导致代码的可维护性降低。因此需要把控制权抽离,并交由第三方处理,即控制反转( IOC,Inversion of Control) 。在开发过程中,只需要从第三方容器( IOC 容器) 获取并向类中注入依赖,即可实现依赖解耦。轻量级服务定位器库 get_it 提供了一种高效的 IOC 容器和依赖之间的依赖关系处理方式。
2. 5 UI 设计 Flutter 向开发者提供了 Material 与 Cupertino 两套预定义的 UI 组件库。从历次的官方调研与 Github Issues 反馈可知,开发者普遍对 Material 库兴趣更高、好评更多、社区更活跃。Flutter 官方的路线图上也将 Material 库作为不同平台的优先开发适配的 UI 库。另一方面,Flutter 作为跨平台框架,在设计和开发过程中应当考虑不同屏幕的适配问题。Material Design 要求应当根据断点设计响应式的 UI 布局。
3 外设接入与原生开发
工业移动应用软件通常需要各类外设的支持,比 如: 激光扫码、身份证验证、RFID 读取、红外摄像等。使用这些外设则需要使用特定平台的 SDK 或使用广播的方式接收数据。如图 4 所示,Flutter 与 Android 之间约定一个通道,两者之间可以互相调用( invoke) 方法并回调返回数据,从而实现两者之间数据交换。
一些工业级 PDA 或平板也提供了系统级的应用程序来为外设接入提供便利。图 5 提供了一种激光扫码的接入方式。系统级的应用程序负责控制外设硬件,当接收到扫码数据时,通过系统广播通知所有应用软件。应用软件接收到广播后,经由 MethodChannel,将二维码数据发送到 QrcodeBloc 中。QrcodeBloc 负责解析二维码,若解析失败,则直接通知用户扫码失败; 若解析成功,则向某一业务模块发送 Event。该业务将根据 Event 刷新数据或界面,通知用户扫码结果。为了保证软件兼容性,图 5 所示的接入方式依然保留了传统摄像头扫码方式。
4 国际化解决方案
Flutter 官方和 Flutter 社区有许多优秀的国际化解决方案,例如 i18n_extension 和 easy_localization。 i18n_extension 使用扩展的方式将多语言实现添加到 String 类型中,开发者只需要从字符串的一个 Getter 中取值即可。i18n_extension 还优化了使用 ID 映射翻译语句的设计,以往的国际化通常是使用一个特定的 ID 和当前语言来查找翻译语句,这种方式对于开发者而言不够直观; 而 i18n_extension 使用某一特定语言的翻译语句作为 ID,如此可以大大提升代码的可读性。 easy_localization 相比 i18n_extension 提供了代码生成器与多种文件解析器,可以更方便接入其他技术栈的多语言方案。
5 结束语
本文介 绍 了 Flutter 框架并系统性描述了基于 Flutter 的移动工业应用软件的设计与开发方式,进一步验证了 Flutter 在移动工业应用软件中使用的可行性,为开发者提供了一种高效、便捷的开发方式,从而帮助自动化厂商更快搭建移动平台解决方案。
参考文献:
[1] 张国慨. 基于 C/S + B/S 混合模式架构下的风电厂监控系统设计[J]. 电脑编程技巧与维护,2016( 9) : 32 - 33.
[2] 马文涛. B/S 架构下的组态软件设计[D]. 青岛: 山东大学,2014.
[3] 郑辉,史国芳,施尹志,等. 批次报表软件在批量生产中的应用[J]. 仪器仪表标准化与计量,2019( 4) : 17.
[4] 王玉芹,许冬涛,丁玉林,等. 智能巡检定位系统在神宁煤化工安全生产管理中的应用[J]. 自动化应用,2017( 10) : 140 - 142
《基于 Flutter 的跨平台的工业移动应用软件设计》来源:《仪表技术》,作者:汪若彪,史国芳,施尹志,余坦对,陈 晖
濠电姷鏁告慨鐑藉极閸涘﹥鍙忓ù鍏兼綑閸ㄥ倿鏌i悢宄扮盎闁兼澘娼″鍫曞醇濞戞ê顬夊┑鐐叉噽婵灚绌辨繝鍥ч柛灞剧煯婢规洟姊洪崨濠庢疁濞存粌鐖煎濠氬Ω閳哄倸浜為梺绋挎湰缁嬫垿顢旈敓锟�:闂傚倸鍊搁崐鎼佸磹妞嬪海鐭嗗〒姘e亾鐎规洦鍨堕獮鎰償閵忥紕褰块梺鐟板悑閻n亪宕瑰ú顏勭煑闊洦绋掗悡鐔兼煏韫囧﹥鍤夌憸鐗堝笒缁€鍕煟濡偐甯涢柣鎾存礋閺岀喐瀵肩€涙ɑ閿梺鍝勵儑閸犳牠寮诲☉姘e亾閿濆骸浜炲褜鍓熼弻鏇㈠炊瑜嶉顓犫偓娈垮櫘閸o絽鐣烽崼鏇椻偓鏍敊閼恒儱纾冲┑顔硷工椤嘲鐣烽悢纰辨晝闁靛洦濡搁崶銊у幐闁诲繒鍋犻褔鍩€椤掍胶澧辩紓鍌涙崌閹崇偤濡烽妷褏鐛┑鐘灱濞夋盯寮甸鍕柧濠靛倸鎲¢埛鎺懨归敐鍫燁仩閻㈩垱鐩弻鐔哄枈閸楃偘绨藉┑鈥冲级閸旀瑥顕i幘顔藉亹闁归鐒︾紞妤呮⒒娴e憡鎯堥柛鐕佸亰閹囧幢濞嗘垳绗夐梺鎸庣箓濡稓绮绘ィ鍐╃厱闁斥晛鍠氬▓娆撴倵濮橆厽绶查棁澶嬬節婵犲倸顏╅柛鏂诲€濆Λ浣瑰緞閹邦厾鍙嗗┑鐘绘涧濡瑩骞栭幇鐗堢厱闁哄倹顑欓崕鎰庨崶褝韬い銏$☉椤繈骞戦幇顒佸創闂傚倷绀侀幖顐︽儗婢跺本宕叉繝闈涙閺嗭附銇勮箛鎾村櫤濠殿垱鎸抽弻娑樷槈濮楀牆濮涙繛瀛樼矋閻楃姴顫忕紒妯肩懝闁逞屽墴閸┾偓妞ゆ帒鍊告禒婊堟煠濞茶鐏︾€规洏鍨藉畷銊︾節娴h櫣鐣鹃梻浣虹帛閸旀牕岣垮▎鎴犵當鐟滃繒妲愰幒妤婃晩閻熸瑥瀚悵鏇㈡⒑闂堟稓澧崇紓宥勭閻e嘲顫滈埀顒佷繆閹间焦鏅滅紓浣癸供濡劑姊婚崒姘偓椋庢濮橆兗缂氶柤濮愬€愰崑鎾绘濞戞氨鍔悗瑙勬磸閸ㄦ椽濡堕敐澶婄闁靛ě灞芥櫍闂傚倷鑳舵灙缂佺粯锚铻為悹鎭掑妽瀹曟煡鏌涢埄鍏︽粍绂嶅⿰鍫熺厵闂侇叏绠戦弸娑㈡煛鐎n亪顎楅棁澶嬬節婵犲倸鏆欓柍閿嬫⒒缁辨帗娼忛妸锕€闉嶉梺鐟板槻閹冲繘藝閻楀牊鍎熸俊顖滅帛濞呭啴姊婚崒娆戝妽闁诡喖鐖煎畷婵嗩吋閸滀焦瀵岄梺鑺ッˇ浠嬪吹閺囥垺鐓欓柟顖涙緲琚氶梺绋款儏鐎氫即寮婚敐澶婄闁惧浚鍋呭畷鍐差渻閵堝棙鐓ユい锔诲灦閳ユ棃宕橀鍢壯囨煕閳╁喛渚涙慨濠傛健濮婅櫣绮欏▎鎯у壉闂佸憡姊瑰ú鐔兼晲閻愭祴鏀介悗锝庘偓顓涙櫊閺屽秹宕崟顐熷亾婵犳艾鐭楅柛鈩冦仜閺€浠嬫煟閹邦厽缍戦柣蹇ョ畱閻f繈鏁愰崨顔间淮闂佽鍠氶崑銈夊蓟閵娧€鍋撻敐鍐ㄥ缂併劌顭峰娲传閸曨剙顦╁銈冨妼濡鍩㈠鍡欑瘈闁告洏鍔屾禍鐐箾閸繄浠㈤柡瀣ㄥ€曢…鑳槼妞ゃ劌锕悰顕€宕卞☉妯肩潉闂佸壊鍋呯换宥呩缚婵犲洦鈷戦柡鍌樺劜濞呭懘鏌涢悤浣镐喊妞ゃ垺姊圭€佃偐鈧稒菤閹风粯绻涙潏鍓у埌闁硅绻濋獮鍡涘醇閵夛妇鍘辨繝鐢靛Т婵亶宕烽鐐茬柧闂傚倷绶氬ḿ褑鍣归梺绋挎湰缁本鏅舵ィ鍐┾拻濞达綀娅g敮娑㈡煕閺冣偓濞叉牞鐏掓繝鐢靛Т濞层倝鎮块鈧弻娑樷槈濡吋鎲奸梺缁樻尵婵兘鎯€椤忓牆绾ч柛顭戝枦閸╃偞绻濋埛鈧崒姘ギ闂佸搫鐭夌紞浣逛繆閻戣棄唯闁挎洍鍋撴繛鍫燁殜濮婃椽宕崟顒佹嫳缂備礁顑嗛崹鍧楀春閵忊剝鍎熼柕濞垮劤閻も偓婵$偑鍊栫敮鎺楀磹妞嬪孩顫曟慨妞诲亾婵﹦绮粭鐔煎焵椤掆偓宀h儻顦查摶鐐翠繆閵堝懏鍣归柣銈庡枛闇夐柛蹇撳悑缂嶆垹绱掗悩闈涙灈闁诡喗顨呴埥澶娾枍閾忣偄鐏﹂柛鎺戯功閳ь剟娼ч幗婊呭婵傚憡鍊甸柨婵嗛楠炴鐥鈩冪【闂囧绻濇繝鍌氼伀濠⒀冪仛閹便劍绻濋崘鈹夸虎濡ょ姷鍋為崝鏍箚閺冨牊鏅查柛灞句緱濞兼棃姊婚崒娆戭槮闁圭⒈鍋婇幃褍饪伴崼婵堫槶濠殿喗蓱婢у酣宕戦幘缁橆棃婵炴垶鐗曟禒顕€鎮楃憴鍕闁挎洏鍨介妴浣糕枎閹炬潙娈愰梺鍐叉惈閸燁偊鎮欐繝鍌楁斀闁绘ê鐏氶弳鈺佲攽椤旂虎妫庡褎绻堝铏圭矙濞嗘儳鍓遍梺鍦规晶钘壩i幇鏉跨闁归绀侀幃鎴︽⒑缁洖澧查柨鏇楁櫅铻為柛鎰靛枟閳锋垹鐥鐐村櫤闁绘繍浜弻鐔兼偡閻楀牆鏋犻悗娈垮櫘閸嬪﹪鐛Ο鑲╃<婵☆垳绮鐔兼⒒娴h姤纭堕柛锝忕畵楠炲繘鏁撻敓锟�.闂傚倸鍊搁崐鎼佸磹妞嬪海鐭嗗〒姘e亾鐎规洦鍨跺畷绋课旀担绯曞亾閸洘鐓曟い鎰Т閸旀岸鏌i幒鎴犱粵闁靛洤瀚伴獮鎺戭吋閸ヨ埖袦濠电姭鎷冪仦鐣屼画缂備胶绮粙鎾寸閿曞倸纾兼慨姗堢到娴滅偓绻濋棃娑卞剰闁藉啰鍠栭弻銊モ槈濡警浠遍梺绋款儐閹瑰洭寮幇顓熷劅闁炽儴灏欓弫鏍⒒娴h銇熼柛妯恒偢椤㈡牗寰勯幇顒冩憰濠电偞鍨堕崺鍐磻閹剧粯鏅查幖瀛樼箘閺佹牠鏌℃担鍝ュⅵ闁诡喗顨呴埢鎾诲垂椤旂晫浜為梻浣告啞椤ㄥ棙绻涙繝鍥ュù锝囩《濡插牊淇婇鐐存暠闁诲骸顭峰娲偡闁箑娈舵繝娈垮櫘閸欏啫顕g粙搴撴瀻闁瑰墽琛ラ幏缁樼箾鏉堝墽鎮奸弸顏堟煙椤旇棄鐏︾紒缁樼箞婵偓闁宠棄鎳撻埀顒佸椤ㄣ儵鎮欑拠褍浼愬銈嗘尭閵堢ǹ鐣烽崼鏇炵厸闁告劦浜濆▓浠嬫⒒閸屾瑧顦﹂柟纰卞亞缁棃寮婚妷銉ь槷闁瑰吋鐣崝宀勬偂濠靛鐓涢柛鎰╁妼閳ь剛鏁诲畷鎴﹀箻閼姐倕绁﹂梺鍓茬厛閸犳牗鎱ㄦ惔鈾€鏀介柍钘夋娴滄繃銇勯妸銉伐闁伙絿鍏樻慨鈧柕鍫濇噽椤斿﹤鈹戞幊閸婃捇鎳楅崼鏇炲偍闁归棿鐒﹂埛鎴︽煕閹炬潙绲诲ù婊€绮欓弻娑氣偓锝庝簻椤忣亪鏌¢崨顓犲煟妞ゃ垺宀搁崺鈧い鎺嗗亾妞ゎ偄绻橀幖鍦喆閸曨偅鐎梻浣瑰缁诲倸螞濞嗘挻鍋熸慨妯垮煐閸婄敻鎮峰▎蹇擃仾缂佸矁娉曠槐鎾愁吋閸曨収妲銈嗘穿缂嶄礁鐣峰⿰鍕闁荤喐澹嗛敍蹇涙⒒娓氣偓濞佳囥偑閸偂绻嗛柛銉㈡櫇閻捇鏌涢幘妤€鎳愰敍婵嬫⒑缁嬫寧婀伴柣鐔村姂椤㈡瑦寰勯幇顓犲幈闁诲函缍嗛崑鍛暦瀹€鍕厸鐎光偓鐎n剛袦濡ょ姷鍋涢澶愬箖濞嗘挸骞㈡俊顖濇娴煎矂姊虹拠鈥虫灍妞ゃ劌锕妴浣割潩鐠鸿櫣鍔﹀銈嗗笒鐎氼剟鎷戦悢鍏肩叆婵犻潧妫欐刊鍏肩箾鐏忔牗娅婇柡宀嬬秮楠炴﹢宕樺顔煎Ψ闂備浇顕х换鎰涘▎鎴炲床婵炴垯鍨洪弲鏌ユ煕濞戝崬鏋熼柟顔界懇濮婃椽骞愭惔銏狀槱婵炲瓨绮犳禍顏堝箖娴兼惌鏁婇柣锝呯灱閹虫繈姊洪柅鐐茶嫰婢у鈧鍣崑濠囩嵁濡偐纾兼俊顖滅帛椤忕喖姊绘担鑺ョ《闁革綇绠撻獮蹇涙晸閿燂拷,闂傚倸鍊搁崐鎼佸磹妞嬪海鐭嗗〒姘e亾妤犵偛顦甸弫鎾绘偐閸愯弓鐢绘俊鐐€栭悧婊堝磻濞戙垹鍨傞柛宀€鍋為悡鏇熴亜椤撶喎鐏ュù婊呭仦閵囧嫰鍩¢崘銊ュ箣闂佸搫鏈惄顖炪€侀弴銏″亹闁肩⒈鍏涢幃锝夋⒑鐠囨煡顎楅柣蹇斿哺閹繝鏁撻悩鑼舵憰闂侀潧艌閺呮粓宕戦崱娑欑厱閻忕偛澧介埥澶嬨亜韫囥儲瀚�闂傚倸鍊搁崐宄懊归崶顒夋晪鐟滃繘鍩€椤掍胶鈻撻柡鍛Т閻e嘲螣閼姐倗鐦堝┑顔斤供閸樻悂骞愰崘顔解拺闁告稑锕ユ径鍕煕鐎n偅宕岄柟铏崌瀹曠ǹ螖娴e搫寮伴梻濠庡亜濞村嫮寰婇懞銉ь洸闁哄稁鐏愰悷鎵冲牚闁告洦鍘鹃悡鈧梺鍓х帛閻楃娀寮婚妸銉㈡斀闁糕剝锚濞咃綁姊洪崫鍕棤闁稿鍊濆濠氬Ω閵夈垺顫嶉梺鎯ф禋閸嬪嫰顢旈敓锟�濠电姷鏁告慨鐑藉极閹间礁纾绘繛鎴欏灪閸嬨倝鏌曟繛褍鍟悘濠囨倵閸忓浜鹃梺鍛婃处閸撴瑦绂嶉柆宥嗏拺闁告稑锕g欢閬嶆煕閻樺啿鍝洪柕鍡楁嚇瀵濡烽敂鎯у箥闂備胶绮崹鍫曟晝閳轰讲鏋旈柡鍐ㄥ€荤壕濂告煃瑜滈崜鐔风暦閸楃偐妲堟繛鍡樺灥楠炴绻濈喊妯活潑闁搞劎鏁诲畷鎴﹀箛椤旇姤娈板┑鐐村灟閸ㄦ椽鎮¢悢鍝ョ瘈闁割煈鍋呯亸浼存倵濮樼偓瀚�.
转载请注明来自:http://www.zazhifabiao.com/lunwen/dzxx/rjkf/48143.html
上一篇:卡拉OK场所点单软件设计方案