app模板、应用模板、组件模板、widget模板
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

609 lines
20 KiB

4 years ago
  1. # TIS 应用与组件 - 开发
  2. ## 1. 安装依赖
  3. ```
  4. npm install
  5. ```
  6. 如果您的设备支持联网,请分别在template、\__test__、src/tis_app_frame、src/tis_component_example、src/tis_widget_frame 这几个文件夹下分别删除node_modules,并且重新执行npm install进行必要的依赖安装
  7. ## 2. 一健启动
  8. ```
  9. npm run start
  10. ```
  11. 浏览器里打开 http://localhost:8001/TIS_PLATFORM/ ,即可预览框架中的运行效果
  12. 默认的应用地址 http://localhost:7000/, 这是应用独立启动的地址,如果您需要单独进入应用而不使用平台框架的依赖,点此进入,这也是您的应用在框架中开发的启动地址
  13. 默认的公共业务组件地址 http://localhost:7001/ ,这是公共业务组件的地址,如果您需要单独预览公共业务组件而不使用平台框架的依赖,点此进入,这也是您的组件在框架中开发的启动地址
  14. 默认的浮窗应用地址 http://localhost:7002/ ,这是浮窗应用的地址,如果您需要单独预览浮窗应用地址而不使用平台框架的依赖,点此进入,这也是您的浮窗组件在框架中开发的启动地址
  15. __如果您在src下新复制了一份tis_app_frame(tis_component_example或tis_widget_frame)请手动修改该目录下vue.config.js中的dev port__
  16. 修改前:
  17. ```js
  18. const port = 7001; // dev port
  19. ```
  20. 修改后:
  21. ```js
  22. const port = 7003; // dev port 从3开始,0,1,2均被默认的三个例子占用
  23. ```
  24. ```
  25. npm run start:default
  26. ```
  27. 启动默认的框架依赖,包括:框架、tis-ui服务、一个默认的例子应用。使应用能够预览在框架中的运行效果,并且能够调用框架提供的各种接口,建议开发者执行此命令
  28. ```
  29. npm run start:platform
  30. ```
  31. 单独启动框架
  32. ```
  33. npm run start:tis-ui
  34. ```
  35. 单独启动tis-ui服务,使应用能够基于tis-ui进行开发
  36. ```
  37. npm run start:apps_widgets
  38. ```
  39. 启动所有的浮窗应用
  40. ```
  41. npm run start:ws
  42. ```
  43. 启动websocket测试程序,应用可以通过此命令测试后台对前端的推送以及消息接收功能
  44. 如果您需要和后端的ws地址链接,进行调试,请修改**lib/platform/dist/TIS_PLATFORM/manifest/manifest.json** 中的wsUrl
  45. ```json
  46. {
  47. "wsUrl": "ws://localhost:9999",
  48. "whitelist": []
  49. }
  50. ```
  51. ```
  52. npm run start:design
  53. ```
  54. 一站式开发平台,包含了整个开发平台的介绍、api手册、tis-ui的开发示例等,是开发者入门学习的帮助文档
  55. ## 3. 编码
  56. ### 3.1 编码前须知
  57. 开发者拿到此模板请根据需要重新命名src下的三个工程的文件夹名称,例如:指挥决策软件,请将tis_app_frame重命名为tis_app_frame_zhjc
  58. - tis(平台)_app(类别为app)_frame(应用框架)_xxx(唯一id简拼)
  59. - tis(平台)_widget(类别为浮窗app)_frame(应用框架)_xxx(唯一id简拼)
  60. - tis(平台)_component(业务组件)_xxx(唯一id简拼)
  61. 请开发者务必按照上述命名规范进行命名,否则集成阶段不会预期加载您的软件
  62. ### 3.2 编码中
  63. 修改tis_app_frame/ 和 tis_component_example/ 和 tis_widget_frame/ 里的文件
  64. 可在浏览器里查看到实时修改结果
  65. ### 3.3 配置文件
  66. 在tis_app_frame/public文件夹下您可以看到名为esplug.json的文件夹,在这里您需要填写一些简单的配置。
  67. 1. 引入第三方业务组件
  68. 您需要将第三方业务组件相关资源拷贝到sdk文件夹中,然后重新运行您的项目,否则将不会生效
  69. 2. 按照如下填写配置文件
  70. component中的组件您可以根据自己的需要进行二次拓展
  71. - 拓展前
  72. ```json
  73. {
  74. "name": "组件测试用例", //必填 组件中文名称
  75. "component": "testApp", //必填 组件对外暴露的名称
  76. "icon": "icon-huojian", //选填 icon
  77. "segprefix": "TIS_COMPONET_EXAMPLE", //组件所在的文件夹名称,必填
  78. "dependencies": ["tis-component-demo-2"]//选填 外部依赖
  79. },
  80. ```
  81. - 拓展后
  82. ```json
  83. {
  84. "name": "组件测试用例", //必填 组件中文名称
  85. "component": "testApp", //必填 组件对外暴露的名称
  86. "icon": "icon-huojian", //选填 icon
  87. "segprefix": "TIS_COMPONET_EXAMPLE", //组件所在的文件夹名称,必填
  88. "dependencies": ["tis-component-demo-2"],//选填 外部依赖
  89. "position":"", //拓展属性
  90. "width":"", //拓展属性
  91. "height":"" //拓展属性
  92. },
  93. ```
  94. 3. 在esplug.json中将引入的组件配置到components数组当中,并且填写好当前开发应用的name
  95. ```json
  96. {
  97. "name": "应用框架示例", //必填 应用名称
  98. "components": [ //选填 组件集合
  99. {
  100. "name": "组件测试用例", //必填 组件中文名称
  101. "component": "testApp", //必填 组件对外暴露的名称
  102. "icon": "icon-huojian", //选填 icon
  103. "segprefix": "TIS_COMPONET_EXAMPLE", //组件所在的文件夹名称,必填
  104. "dependencies": ["tis-component-demo-2"]//选填 外部依赖
  105. },
  106. {
  107. "name": "组件测试用例2",
  108. "component": "testApp2",
  109. "icon": "icon-huojian",
  110. "segprefix": "tis-component-demo-2"
  111. },
  112. {
  113. "name":"kt应用市场代码",
  114. "component":"pcmarket",
  115. "segprefix":"TIS_YYSC"
  116. }
  117. ]
  118. }
  119. ```
  120. 4. 在项目中引入组件
  121. ```js
  122. <template>
  123. <div id="app">
  124. <component :is="kt_yysc"></component>
  125. </div>
  126. </div>
  127. </template>
  128. export default {
  129. name: "App",
  130. data() {
  131. return {
  132. kt_yysc: "",
  133. };
  134. },
  135. mounted() {
  136. this.$tis.loadComponent("testApp")//组件的segprefix
  137. .then((res) => {
  138. console.log("load component", res);
  139. this.compName = "testApp";
  140. })
  141. .catch((err) => {
  142. this.compName = "testApp";
  143. console.error(err);
  144. });
  145. };
  146. ```
  147. 5. CSS多端适配
  148. 本项目采取了基于__视口单位(Viewport units)__的CSS自适应布局单位,标准设计稿尺寸为 1600*1200
  149. vw(Viewport Width)、vh(Viewport Height)是基于视图窗口的单位,是css3的一部分,基于视图窗口的单位,除了vw、vh还有vmin、vmax。
  150. - vw:1vw 等于视口宽度的1%
  151. - Vh:1vh 等于视口高度的1%
  152. - vmin: 选取 vw 和 vh 中最小的那个,即在手机竖屏时,- 1vmin=1vw
  153. - vmax:选取 vw 和 vh 中最大的那个 ,即在手机竖屏时,1vmax=1vh
  154. 我们预置了px转换vw单位的插件,您可以方便的使用设计稿中的px单位,项目会自动帮助您进行单位转换,如果您需要按需配置,请在项目目录下的 postcss.config.js中进行自定义配置
  155. ```js
  156. module.exports = {
  157. parser: false,
  158. sourceMap: false,
  159. plugins: {
  160. 'postcss-px-to-viewport': {
  161. // options
  162. unitToConvert: 'px',//(String) 需要转换的单位,默认为"px"
  163. viewportWidth: 1200, // (Number) 设计稿的视口宽度,一般是750
  164. unitPrecision: 3, // (Number) 单位转换后保留的精度(很多时候无法整除)
  165. viewportUnit: 'vw', // (String) 希望使用的视口单位
  166. selectorBlackList: ['.ignore', '.hairlines'],
  167. /*(Array) 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位
  168. 如果传入的值为字符串的话,只要选择器中含有传入值就会被匹配
  169. 例如 selectorBlackList 为 ['body'] 的话, 那么 .body-class 就会被忽略
  170. 如果传入的值为正则表达式的话,那么就会依据CSS选择器是否匹配该正则
  171. 例如 selectorBlackList 为 [/^body$/] , 那么 body 会被忽略,而 .body 不会*/
  172. minPixelValue: 1, // (Number) 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
  173. mediaQuery: false, // (Boolean) 媒体查询里的单位是否需要转换单位
  174. exclude: [/^node_modules$/],// (Array or Regexp) 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
  175. //include:/\/src\/mobile\//
  176. /*(Array or Regexp) 如果设置了include,那将只有匹配到的文件才会被转换,例如只转换 'src/mobile' 下的文件
  177. 如果值是一个正则表达式,将包含匹配的文件,否则将排除该文件
  178. 如果传入的值是一个数组,那么数组里的值必须为正则
  179. 注意:exclude和include是可以一起设置的,将取两者规则的交集*/
  180. landscapeUnit: 'vw', //(String)横屏时使用的单位
  181. landscapeWidth: 1200 //(Number)横屏时使用的视口宽度
  182. }
  183. }
  184. }
  185. ```
  186. 6. 静态资源的引用
  187. 如果您在开发过程中在css文件中需要引入一些图片、文字等静态资源文件,请您使用内联style,否则将不会有预期效果
  188. 例如:
  189. ```css
  190. {
  191. background:url('/assets/temp.png')
  192. }
  193. ```
  194. 上述的url会由于公共路径的变化而不会生效,您可以使用内联style来实现背景图的引用
  195. ```html
  196. <template>
  197. <div :style="{background:`url(${require(`./assets/bg2.png`)})`}">
  198. </div>
  199. </template>
  200. <script>
  201. export default {
  202. name: "tisc-aim-list"
  203. };
  204. </script>
  205. <style lang="scss" scoped>
  206. div {
  207. /* background-image: url("/TIS_APP_FRAME/bg2.png"); */
  208. background-size: cover;
  209. background-repeat: no-repeat;
  210. width: 100%;
  211. height: 220px;
  212. }
  213. </style>
  214. ```
  215. 7. 在项目中引入地图
  216. 如果您希望在组件中引入地图组件,那么请按照如下方式引入,具体的地图接口、API等请参见《地图程序员手册》
  217. ```html
  218. <template>
  219. <div style=" width:100%; height:100%;position:absolute;
  220. top:0;
  221. bottom: 0;
  222. left: 0;
  223. right: 0;">
  224. <div name="outerDiv" id="outerDiv"></div>
  225. </div>
  226. </template>
  227. <script>
  228. //import $bus15 from "../assets/util/bus";
  229. import { setInterval } from "timers";
  230. export default {
  231. //组件名称必须填写,并且必须和注册名称、打包名称(异步引入时需要)保持一致
  232. name: "mapMGIS15",
  233. data() {
  234. return {
  235. statusClock: null,
  236. timeStamp: 2 * 60 * 1000,
  237. // timeStamp:20*1000,
  238. workspaceName: "workspace"
  239. };
  240. },
  241. components: {
  242. },
  243. mounted() {
  244. window.Mgs.GDataManager.newFile();
  245. window.Mgs.GDataManager._eventSourceInitialize();
  246. var map2DManager = window.esapp.ShareMap.Map2DManager;
  247. var self = this;
  248. var map = map2DManager.loadMap("outerDiv", {
  249. alias: "100w21",
  250. version: 1000,
  251. url: window.MGS_IP_URL,
  252. centerPoint: [35.24277, 113.54164, 7],
  253. panelControl: []
  254. });
  255. window.esMap = window.emap2d = map;
  256. var layer = map.Layer2DManager.addLayer(
  257. window.esapp.ShareMap.EsMapConstants.LAYER_TYPE_2D.PLOTTING,
  258. {
  259. layerName: "默认图层",
  260. needToBeShared: true
  261. },
  262. {
  263. needAddToTree: true
  264. }
  265. );
  266. layer.setLayerAutoSave(true);
  267. map.DrawControl.setDrawingLayer(layer);
  268. self.bindMapStatusSave();
  269. setTimeout(function () {
  270. self.loadAfter();
  271. }, 3000);
  272. },
  273. methods: {
  274. bindMapStatusSave() {
  275. var self = this;
  276. var options = {
  277. fileName: self.workspaceName + ".sml",
  278. userName: self.workspaceName,
  279. success: function () {
  280. },
  281. fail: function () {
  282. }
  283. };
  284. this.statusClock = setInterval(function () {
  285. window.Mgs.GFileManager.saveWorkSpace(options);
  286. }, this.timeStamp);
  287. },
  288. loadAfter() {
  289. var self = this;
  290. var options = {
  291. fileName: self.workspaceName + ".sml",
  292. userName: this.workspaceName,
  293. isOverlay: true,
  294. success() {
  295. // self.$message({
  296. // type: "success",
  297. // message: "打开工作区文件成功"
  298. // });
  299. }
  300. };
  301. window.Mgs.GFileManager.openFile(options);
  302. }
  303. }
  304. };
  305. </script>
  306. <style>
  307. #outerDiv {
  308. margin: 0;
  309. padding: 0;
  310. width: 100%;
  311. height: 100%;
  312. overflow: hidden;
  313. z-index: 10;
  314. position: absolute;
  315. background: url(/TIS_DLBHZJQD/gridres/images/nomap256x256.png) repeat;
  316. }
  317. .mgstag {
  318. border: 2px solid #09f;
  319. position: absolute;
  320. background-color: transparent;
  321. background-color: rgba(255, 255, 255, 0.6);
  322. z-index: 999;
  323. min-width: 150px;
  324. min-height: 100px;
  325. max-width: 200px;
  326. }
  327. .mgstag:after,
  328. .mgstag:before {
  329. content: "";
  330. display: block;
  331. position: absolute;
  332. bottom: -40px;
  333. left: 50px;
  334. border: 17px dashed transparent;
  335. border-top: 21px solid #09f;
  336. font-size: 0;
  337. line-height: 0;
  338. }
  339. .mgstag:after {
  340. bottom: -38px;
  341. border-color: rgba(255, 255, 255, 0.9) transparent transparent;
  342. }
  343. .mgstag .mgstag-head {
  344. text-align: center;
  345. background-color: #09f;
  346. font-weight: bold;
  347. font-size: 12px;
  348. }
  349. .mgstag .mgstag-content {
  350. overflow-x: hidden;
  351. overflow-y: auto;
  352. font-size: 12px;
  353. }
  354. .emp-icon-path {
  355. background-repeat: no-repeat;
  356. background-size: 100% 100%;
  357. }
  358. /* 气泡弹框 */
  359. .tooltip-pane:before {
  360. left: calc(50% - 6px);
  361. position: absolute;
  362. pointer-events: none;
  363. border: 6px solid transparent;
  364. background: transparent;
  365. content: "";
  366. border-top-color: #fff;
  367. bottom: -12px;
  368. }
  369. #magnifyWin {
  370. display: auto;
  371. position: absolute;
  372. overflow: hidden;
  373. bottom: 50px;
  374. z-index: 9999;
  375. width: 360px;
  376. height: 360px;
  377. padding: 1px;
  378. background-color: #9fa29d;
  379. border-radius: 8px;
  380. box-shadow: 0 0 7px #bcb4ac;
  381. cursor: pointer;
  382. background-color: rgba(200, 200, 250, 0.2);
  383. }
  384. </style>
  385. ```
  386. 在lib/platform/dist/TIS_PLATFORM/map15/TerraGlobe/config.js修改地图后端的接口基地址serverIp、MGS_IP
  387. ```js
  388. function isPc(){
  389. var agents = ["android","windows phone","iphone","ipad","ipod","symbianos","syberos"];
  390. for(var i = 0;i < agents.length;i ++){
  391. if(new RegExp(agents[i],"i").test(window.navigator.userAgent.toLowerCase())){
  392. return true
  393. }
  394. }
  395. return false
  396. }
  397. if(window.IS_MOBILE){
  398. if (isOnLine) {
  399. } else {
  400. // serverIp = "130.30.1.16";
  401. // serverIp = "192.168.11.146";
  402. serverIp = "10.10.10.89",//地图服务基地址
  403. MGS_IP_URL = 'http://' + serverIp + ":3886/";
  404. MGS_SERVER_URL = MGS_IP_URL + "api/services";
  405. MGS_TILE_URL = MGS_IP_URL + "gis3globle"; //瓦片
  406. MGS_TILE_URL_OFFLINE = MGS_IP_URL + "api/services/get_tile/get_tile/";
  407. MGS_2D_TILE = MGS_IP_URL + "gis3globle/maps/services"; //二维瓦片
  408. }
  409. }
  410. var isOnLine = false;
  411. window.isOnLine = false
  412. window.IS_MOBILE = isPc();
  413. window.MGS_PATH_NAME = "./map15";
  414. if (isOnLine) {
  415. MGS_IP_URL = "http://192.168.56.162:9999/";
  416. MGS_SERVER_URL = MGS_IP_URL + "MGSServer";
  417. MGS_TILE_URL = MGS_IP_URL + "gis3globle"; //瓦片
  418. MGS_TILE_URL_OFFLINE = MGS_IP_URL + "api/services/get_tile/get_tile/";
  419. MGS_2D_TILE = MGS_IP_URL + "gis3globle/maps/services" //二维瓦片
  420. } else {
  421. MGS_IP_URL = "http://10.10.10.89:3806/";
  422. MGS_SERVER_URL = MGS_IP_URL + "api/services";
  423. MGS_TILE_URL = MGS_IP_URL + "gis3globle"; //瓦片
  424. MGS_TILE_URL_OFFLINE = MGS_IP_URL + "api/services/get_tile/get_tile/";
  425. MGS_2D_TILE = MGS_IP_URL + "gis3globle/maps/services" //二维瓦片
  426. }
  427. MGS_IP = "http://10.10.10.89";//地图服务基地址
  428. // debugger
  429. // MGIS.Terramap.serviceIp="130.30.1.16";
  430. ```
  431. ### 3.4 在框架中预览
  432. 当前开发框架已为您默认配置好了应用的入口,如果您有需要自定义配置,默认的配置路径在
  433. **lib/platform/manifest/apps_widgets.json**
  434. entry:""//您项目的运行地址
  435. id:""//一般默认为您的工程项目名
  436. icon:""//您的app应用图标
  437. ```json
  438. {
  439. "apps": [
  440. {
  441. "name": "应用框架示例",
  442. "components": [
  443. {
  444. "name": "组件测试用例",
  445. "component": "testApp",
  446. "icon": "icon-huojian",
  447. "segprefix": "TIS_COMPONET_EXAMPLE",
  448. "dependencies": [
  449. "tis-component-demo-2"
  450. ]
  451. },
  452. {
  453. "name": "组件测试用例2",
  454. "component": "testApp2",
  455. "icon": "icon-huojian",
  456. "segprefix": "tis-component-demo-2"
  457. },
  458. {
  459. "name": "kt应用市场代码",
  460. "component": "pcmarket",
  461. "segprefix": "TIS_YYSC"
  462. },
  463. ...
  464. ],
  465. "id": "tis_app_frame", //应用唯一id
  466. "entry": "http://localhost:7000", //端口
  467. "icon": "http://localhost:7000/icon.png"
  468. },
  469. ...
  470. },
  471. "widgets":[]
  472. }
  473. ```
  474. ### 3.5 工程整理
  475. 在开发模板中我们预设了一些例子,例如sdk文件夹中的组件,大多数情况下,您需要自行引入您需要的组件,而不是使用这些示例,所以当您完全了解开发工程的结构后请务必及时删除这些不必要的示例。
  476. 例如:tis_app_frame/sdk 下的TIS_YYSC和tis-component-demo-2就是您需要删除的不必要文件
  477. ## 4. 构建打包
  478. ```
  479. npm run build
  480. ```
  481. - tis_app_frame 的构建产物在 tis_app_frame/dist
  482. - tis_component_example 的构建产物在 tis_component_example/dist
  483. - tis_widget_frame 的构建产物在 tis_widget_frame/dist
  484. 如果您有多个项目,那么打包构建后的产物会生成在当前项目工程的dist文件夹中
  485. __请注意,dist目录中是src文件夹下所有工程的打包集合,您需要按需使用,例如您只基于tis_app_frame工程开发了您的应用,那么tis_widget_frame与tis_component_example便不是您需要的文件,请您在提取构建产物时务必检查__
  486. ## 5. 其他
  487. ### 5.1 目录结构说明
  488. ```
  489. .
  490. ├── __test__ //测试文件夹
  491. │   └── websocket //websocket测试
  492. ├── dist //打包构建产物
  493. │   ├── TIS_APP_FRAME
  494. │   │   ├── css
  495. │   │   └── js
  496. │   ├── TIS_COMPONET_EXAMPLE
  497. │   │   ├── css
  498. │   │   └── js
  499. │   └── TIS_WIDGET_FRAME
  500. │   ├── css
  501. │   └── js
  502. ├── lib //外部依赖
  503. │   ├── default_app //默认的app模板依赖
  504. │   │   └── dist
  505. │   ├── platform //平台框架依赖
  506. │   │   └── dist
  507. │   ├── tis_design //一站式开发平台帮助文档
  508. │   │   └── examples
  509. │   └── ui //ui外部依赖
  510. │   ├── tis-ui
  511. │   └── vue
  512. └── src //源码存放文件夹
  513. ├── tis_app_frame //默认的app模板
  514. │   ├── dist //打包构建产物
  515. │   ├── public //静态资源存放目录
  516. │   ├── sdk //第三方组件存放目录
  517. │   ├── src //源码存放文件夹
  518. │   └── webpack_plugins //webpack插件
  519. ├── tis_componet_example //默认的component模板
  520. │   ├── dist
  521. │   ├── public
  522. │   ├── sdk
  523. │   ├── src
  524. │   └── webpack_plugins
  525. └── tis_widget_frame //默认的widget模板
  526. ├── dist
  527. ├── public
  528. ├── sdk
  529. ├── src
  530. └── webpack_plugins
  531. ```
  532. ### 5.2 更换必要的lib库
  533. 框架(TIS_PLATFORM)、界面UI库(tis-ui、tis-m)进行更新变更,如您想体验到新版的框架和界面UI库,请将lib/platform/dist/TIS_PLATFORM 或者 ui/tis-ui 下的文件删除,并替换成同名的最新文件即可
  534. ### 5.3 配置代理
  535. 当您在sdk文件夹中引入一些组件依赖,而这些组件依赖是异步构建的,例如您试图兼容一些kt已开发好的组件,那么您必须在config.js中配置您当前运行环境的域名才能保证组件所有异步资源的正常加载,例如:在tis_app_frame工程中您引入了一个名为TIS_YYSC的异步构建的kt组件,那么您需要在config.js中作如下配置,确保在开发环境中资源可以被正常加载。
  536. ```
  537. '/TIS_YYSC':{
  538. target:'http://localhost:7000',
  539. changeOrigin:true
  540. }
  541. ```