user5 8 hónapja
commit
8365d36525
100 módosított fájl, 7567 hozzáadás és 0 törlés
  1. BIN
      .DS_Store
  2. 16 0
      .hbuilderx/launch.json
  3. 0 0
      .idea/.gitignore
  4. 9 0
      .idea/misc.xml
  5. 8 0
      .idea/modules.xml
  6. 9 0
      .idea/wdt_ERP_process_h5.iml
  7. 58 0
      .idea/workspace.xml
  8. 126 0
      App.vue
  9. 144 0
      Readme.md
  10. BIN
      api/.DS_Store
  11. 23 0
      api/auth/loginService.js
  12. 27 0
      api/file/fileService.js
  13. 43 0
      api/flowable/actCategoryService.js
  14. 19 0
      api/flowable/appModelsService.js
  15. 50 0
      api/flowable/buttonService.js
  16. 35 0
      api/flowable/conditionService.js
  17. 31 0
      api/flowable/flowCopyService.js
  18. 41 0
      api/flowable/formCategoryService.js
  19. 43 0
      api/flowable/formDefinitionJsonService.js
  20. 42 0
      api/flowable/formDefinitionService.js
  21. 52 0
      api/flowable/formService.js
  22. 35 0
      api/flowable/listenerService.js
  23. 70 0
      api/flowable/modelService.js
  24. 43 0
      api/flowable/nodeSettingService.js
  25. 102 0
      api/flowable/processService.js
  26. 43 0
      api/flowable/taskDefExtensionService.js
  27. 131 0
      api/flowable/taskService.js
  28. 39 0
      api/form/generateFormService.js
  29. 95 0
      api/form/makeFormService.js
  30. 33 0
      api/mail/mailBoxService.js
  31. 35 0
      api/mail/mailComposeService.js
  32. 27 0
      api/mail/mailTrashService.js
  33. 42 0
      api/notify/notifyService.js
  34. 43 0
      api/sys/areaService.js
  35. 25 0
      api/sys/configService.js
  36. 41 0
      api/sys/dataRuleService.js
  37. 80 0
      api/sys/dictService.js
  38. 34 0
      api/sys/logService.js
  39. 43 0
      api/sys/menuService.js
  40. 43 0
      api/sys/officeService.js
  41. 35 0
      api/sys/postService.js
  42. 77 0
      api/sys/roleService.js
  43. 59 0
      api/sys/userService.js
  44. BIN
      api/test/.DS_Store
  45. 35 0
      api/test/activiti/testActivitiLeaveService.js
  46. 60 0
      api/test/mobile/testMobileService.js
  47. 111 0
      common/auth.js
  48. 64 0
      common/dictUtils.js
  49. 11 0
      common/filter.js
  50. 167 0
      common/graceChecker.js
  51. 114 0
      common/helper.js
  52. 7 0
      common/mixin.js
  53. 143 0
      common/request.js
  54. 88 0
      common/util.js
  55. BIN
      components/.DS_Store
  56. 75 0
      components/cu-navbar/cu-navbar.vue
  57. 236 0
      components/generate-form/generate-form.vue
  58. 33 0
      components/jp-area-select/jp-area-select.vue
  59. 37 0
      components/jp-checkbox-group/jp-checkbox-group.vue
  60. 52 0
      components/jp-color-picker/README.md
  61. 320 0
      components/jp-color-picker/colorPicker.vue
  62. 86 0
      components/jp-color-picker/jp-color-picker.vue
  63. 88 0
      components/jp-datetime-picker/jp-datetime-picker.vue
  64. 104 0
      components/jp-form-upload/jp-form-upload.vue
  65. 106 0
      components/jp-image-upload/jp-image-upload.vue
  66. 127 0
      components/jp-office-select/jp-office-select.vue
  67. 84 0
      components/jp-picker/jp-picker.vue
  68. 31 0
      components/jp-slider/jp-slider.vue
  69. 200 0
      components/ly-tree/components/ly-checkbox.vue
  70. 382 0
      components/ly-tree/ly-tree-node.vue
  71. 588 0
      components/ly-tree/ly-tree.vue
  72. 498 0
      components/ly-tree/model/node.js
  73. 414 0
      components/ly-tree/model/tree-store.js
  74. 114 0
      components/ly-tree/tool/util.js
  75. 119 0
      components/user-select/user-select-dialog.vue
  76. 139 0
      components/user-select/user-select.vue
  77. 13 0
      config.js
  78. 52 0
      main.js
  79. 93 0
      manifest.json
  80. 15 0
      node_modules/.bin/prettier
  81. 7 0
      node_modules/.bin/prettier.cmd
  82. 31 0
      node_modules/.yarn-integrity
  83. 1 0
      node_modules/call-bind/.eslintignore
  84. 17 0
      node_modules/call-bind/.eslintrc
  85. 12 0
      node_modules/call-bind/.github/FUNDING.yml
  86. 13 0
      node_modules/call-bind/.nycrc
  87. 42 0
      node_modules/call-bind/CHANGELOG.md
  88. 21 0
      node_modules/call-bind/LICENSE
  89. 2 0
      node_modules/call-bind/README.md
  90. 15 0
      node_modules/call-bind/callBound.js
  91. 47 0
      node_modules/call-bind/index.js
  92. 80 0
      node_modules/call-bind/package.json
  93. 55 0
      node_modules/call-bind/test/callBound.js
  94. 66 0
      node_modules/call-bind/test/index.js
  95. 20 0
      node_modules/function-bind/.editorconfig
  96. 15 0
      node_modules/function-bind/.eslintrc
  97. 176 0
      node_modules/function-bind/.jscs.json
  98. 22 0
      node_modules/function-bind/.npmignore
  99. 168 0
      node_modules/function-bind/.travis.yml
  100. 0 0
      node_modules/function-bind/LICENSE

BIN
.DS_Store


+ 16 - 0
.hbuilderx/launch.json

@@ -0,0 +1,16 @@
+{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
+  // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
+    "version": "0.0",
+    "configurations": [{
+     	"app-plus" : 
+     	{
+     		"launchtype" : "remote"
+     	},
+     	"default" : 
+     	{
+     		"launchtype" : "remote"
+     	},
+     	"type" : "uniCloud"
+     }
+    ]
+}

+ 0 - 0
.idea/.gitignore


+ 9 - 0
.idea/misc.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/wdt_ERP_process_h5.iml" filepath="$PROJECT_DIR$/.idea/wdt_ERP_process_h5.iml" />
+    </modules>
+  </component>
+</project>

+ 9 - 0
.idea/wdt_ERP_process_h5.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 58 - 0
.idea/workspace.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ChangeListManager">
+    <list default="true" id="3e673e88-45f2-44eb-b4c4-1d450ffc1c11" name="Default Changelist" comment="" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="ProjectId" id="2l3CALYoWWKOh20ZTbXyfxbprTf" />
+  <component name="ProjectViewState">
+    <option name="showLibraryContents" value="true" />
+  </component>
+  <component name="PropertiesComponent">
+    <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
+    <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
+    <property name="WebServerToolWindowFactoryState" value="false" />
+    <property name="aspect.path.notification.shown" value="true" />
+    <property name="last_opened_file_path" value="$PROJECT_DIR$/../../wdt_ERP_new/wdt_ERP_process_vue" />
+    <property name="nodejs_package_manager_path" value="yarn" />
+  </component>
+  <component name="SvnConfiguration">
+    <configuration />
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="3e673e88-45f2-44eb-b4c4-1d450ffc1c11" name="Default Changelist" comment="" />
+      <created>1724399228519</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1724399228519</updated>
+      <workItem from="1724399230205" duration="83000" />
+      <workItem from="1724400601455" duration="1378000" />
+      <workItem from="1724651120214" duration="4119000" />
+      <workItem from="1724718569164" duration="621000" />
+      <workItem from="1724722684498" duration="2762000" />
+    </task>
+    <servers />
+  </component>
+  <component name="TypeScriptGeneratedFilesManager">
+    <option name="version" value="2" />
+  </component>
+  <component name="WindowStateProjectService">
+    <state x="1007" y="396" key="FileChooserDialogImpl" timestamp="1724654229570">
+      <screen x="0" y="0" width="2560" height="1400" />
+    </state>
+    <state x="1007" y="396" key="FileChooserDialogImpl/0.0.2560.1400@0.0.2560.1400" timestamp="1724654229570" />
+    <state x="545" y="178" width="715" height="646" key="find.popup" timestamp="1724722701621">
+      <screen x="0" y="0" width="1536" height="824" />
+    </state>
+    <state x="545" y="178" width="715" height="646" key="find.popup/0.0.1536.824@0.0.1536.824" timestamp="1724722701621" />
+    <state x="909" y="377" width="742" height="646" key="find.popup/0.0.2560.1400@0.0.2560.1400" timestamp="1724662943155" />
+    <state x="859" y="308" width="840" height="1034" key="search.everywhere.popup" timestamp="1724728794334">
+      <screen x="0" y="0" width="2560" height="1400" />
+    </state>
+    <state x="859" y="308" width="840" height="1034" key="search.everywhere.popup/0.0.2560.1400@0.0.2560.1400" timestamp="1724728794334" />
+  </component>
+</project>

+ 126 - 0
App.vue

@@ -0,0 +1,126 @@
+<script>
+	import Vue from 'vue'
+	export default {
+		onLaunch: function() {
+			uni.getSystemInfo({
+				success: function(e) {
+					// #ifndef MP
+					Vue.prototype.StatusBar = e.statusBarHeight;
+					if (e.platform == 'android') {
+						Vue.prototype.CustomBar = e.statusBarHeight + 50;
+					} else {
+						Vue.prototype.CustomBar = e.statusBarHeight + 45;
+					};
+					// #endif
+
+					// #ifdef MP-WEIXIN
+					Vue.prototype.StatusBar = e.statusBarHeight;
+					let custom = wx.getMenuButtonBoundingClientRect();
+					Vue.prototype.Custom = custom;
+					Vue.prototype.CustomBar = custom.bottom + custom.top - e.statusBarHeight;
+					// #endif		
+
+					// #ifdef MP-ALIPAY
+					Vue.prototype.StatusBar = e.statusBarHeight;
+					Vue.prototype.CustomBar = e.statusBarHeight + e.titleBarHeight;
+					// #endif
+				}
+			})
+
+			Vue.prototype.ColorList = [{
+					title: '嫣红',
+					name: 'red',
+					color: '#e54d42'
+				},
+				{
+					title: '桔橙',
+					name: 'orange',
+					color: '#f37b1d'
+				},
+				{
+					title: '明黄',
+					name: 'yellow',
+					color: '#fbbd08'
+				},
+				{
+					title: '橄榄',
+					name: 'olive',
+					color: '#8dc63f'
+				},
+				{
+					title: '森绿',
+					name: 'green',
+					color: '#39b54a'
+				},
+				{
+					title: '天青',
+					name: 'cyan',
+					color: '#1cbbb4'
+				},
+				{
+					title: '海蓝',
+					name: 'blue',
+					color: '#0081ff'
+				},
+				{
+					title: '姹紫',
+					name: 'purple',
+					color: '#6739b6'
+				},
+				{
+					title: '木槿',
+					name: 'mauve',
+					color: '#9c26b0'
+				},
+				{
+					title: '桃粉',
+					name: 'pink',
+					color: '#e03997'
+				},
+				{
+					title: '棕褐',
+					name: 'brown',
+					color: '#a5673f'
+				},
+				{
+					title: '玄灰',
+					name: 'grey',
+					color: '#8799a3'
+				},
+				{
+					title: '草灰',
+					name: 'gray',
+					color: '#aaaaaa'
+				},
+				{
+					title: '墨黑',
+					name: 'black',
+					color: '#333333'
+				},
+				{
+					title: '雅白',
+					name: 'white',
+					color: '#ffffff'
+				},
+			]
+
+		},
+		onShow: function() {
+			console.log('App Show')
+		},
+		onHide: function() {
+			console.log('App Hide')
+		}
+
+	}
+</script>
+
+<style lang="scss">
+	/*每个页面公共css */
+	@import "@/uni_modules/uview-ui/index.scss";
+	@import "static/css/jeeplus.scss";
+	/* @import 'jeeplus-flowable/lib/jeeplus-flowable.css'; */
+	@import "static/css/main.css";
+	@import "static/css/icon.css";
+	/*每个页面公共css */
+</style>

+ 144 - 0
Readme.md

@@ -0,0 +1,144 @@
+<p style="text-align: center;"><img src="https://image.weilanwl.com/uni/UniAppReadme.jpg" alt="ColorUI简介"></img></p>
+
+## 前言
+ColorUI是一个css库!!!在你引入样式后可以根据class来调用组件,一些含有交互的操作我也有简单写,可以为你开发提供一些思路。插件市场版本如果和更新日志不一样,请移步Github下载。有组件需求或者Bug提交也可以移步到issues。
+
+## 交流
+微信群:加入微信群请先添加开发者微信,备注UniApp插件市场。QQ群:240787041 或扫描二维码。
+<p style="text-align: center;"><img src="https://image.weilanwl.com/colorui/githubQrcode.jpg" alt="" style="max-width:100%;" width="748"></p>				  
+
+## 素材
+ColorUI在语雀有个群友共同在维护的知识库,里面有一些群友改的模板和UI素材供开发使用哦!
+[语雀-ColorUI群资源](https://www.yuque.com/colorui)
+ 
+## 开始使用
+下载源码解压,复制根目录的 `/colorui` 文件夹到你的根目录
+
+`App.vue` 引入关键Css `main.css` `icon.css`
+```
+<style>
+    @import "colorui/main.css";
+	@import "colorui/icon.css";
+	@import "app.css"; /* 你的项目css */
+	....
+</style>
+```
+
+------
+
+## 使用自定义导航栏
+导航栏作为常用组件有做简单封装,当然你也可以直接复制代码结构自己修改,达到个性化目的。
+
+`App.vue` 获得系统信息
+```
+onLaunch: function() {
+	uni.getSystemInfo({
+		success: function(e) {
+			// #ifndef MP
+			Vue.prototype.StatusBar = e.statusBarHeight;
+			if (e.platform == 'android') {
+				Vue.prototype.CustomBar = e.statusBarHeight + 50;
+			} else {
+				Vue.prototype.CustomBar = e.statusBarHeight + 45;
+			};
+			// #endif
+			// #ifdef MP-WEIXIN
+			Vue.prototype.StatusBar = e.statusBarHeight;
+			let custom = wx.getMenuButtonBoundingClientRect();
+			Vue.prototype.Custom = custom;
+			Vue.prototype.CustomBar = custom.bottom + custom.top - e.statusBarHeight;
+			// #endif		
+			// #ifdef MP-ALIPAY
+			Vue.prototype.StatusBar = e.statusBarHeight;
+			Vue.prototype.CustomBar = e.statusBarHeight + e.titleBarHeight;
+			// #endif
+		}
+	})
+},
+```
+
+`pages.json` 配置取消系统导航栏
+```
+"globalStyle": {
+	"navigationStyle": "custom"
+},
+```
+复制代码结构可以直接使用,注意全局变量的获取。
+
+使用封装,在`main.js` 引入 `cu-custom` 组件。
+```
+import cuCustom from './colorui/components/cu-custom.vue'
+Vue.component('cu-custom',cuCustom)
+```
+
+`page.vue` 页面可以直接调用了
+```
+<cu-custom bgColor="bg-gradual-blue" :isBack="true">
+	<block slot="backText">返回</block>
+	<block slot="content">导航栏</block>
+</cu-custom>
+```
+| 参数       | 作用   |类型    |  默认值 |
+| --------   | -----:  |-----:  | :----:  |
+| bgColor    | 背景颜色类名 |String  |   ''    |
+| isBack     | 是否开启返回 | Boolean |   false |
+| bgImage    | 背景图片路径 | String  |  ''     |
+
+| slot块       | 作用   |
+| --------   | -----:  |
+| backText    | 返回时的文字 | 
+| content     | 中间区域 | 
+| right    | 右侧区域(小程序端可使用范围很窄!)  | 
+
+
+------
+
+
+## 使用自定义Tabbar
+这部分暂时没有封装,思路可以参考下我的源码,原理是一个主页面引入多个页面,在主页面进行切换显示。这样可以解决切换时闪烁的问题。
+
+
+------
+
+
+## 更新日志
+
+ * 2019年4月25日 v2.1.6
+    *  删除var变量 向下兼容安卓APP
+	*  优化单选等表单控件
+
+ * 2019年4月25日 v2.1.5
+    *  优化图片上传
+    *  优化一些点击区域过小
+    *  优化图标旋转
+    *  优化demo显示
+    *  优化阴影
+    *  修复支付宝小程序编译出错
+
+ * 2019年4月14日 v2.1.4
+    *  新增多种阴影
+	*  修复一些var属性的错误
+	*  修复轮播图控制点隐藏不了
+	*  修改图标类名
+	*  修复表单组件里上传图片 ios没有图片显示问题
+
+ 
+ * 2019年4月01日 v2.1.3
+    *  优化代码,支持支付宝小程序
+	*  textarea 样式还原
+
+ * 2019年3月28日 v2.1.2
+	*  修复列表组件样式
+	*  优化主样式代码
+
+ * 2019年3月27日 v2.1.1
+    *  新增多种扩展
+    *  优化堆叠轮播图
+    *  优化消息列表
+	*  优化导航栏的封装
+	*  修复卡片评论错位(3月27日16:32:17)
+
+* 2019年3月25日 v2.1.0
+    *  完成元素,组件移植
+	*  icon文件更改名称,避免图标冲突
+	*  针对不同端口做了优化

BIN
api/.DS_Store


+ 23 - 0
api/auth/loginService.js

@@ -0,0 +1,23 @@
+import request from "../../common/request"
+
+export default {
+  getCode: function () {
+    return request({
+	  url: "/sys/getCode",
+      method: 'get'
+    })
+  },
+  login: function (data) {
+    return request({
+	  url: "/sys/login",
+      method: 'post',
+      data: data
+    })
+  },
+  logout: function () {
+    return request({
+	  url: "/sys/logout",
+      method: 'get'
+    })
+  }
+}

+ 27 - 0
api/file/fileService.js

@@ -0,0 +1,27 @@
+import {request, upload} from "../../common/request"
+
+export default {
+	
+  upload: function (filePath, config = {}) {
+	return upload('/file/upload?uploadPath=userdir',filePath)    
+  },
+
+  download: function (params) {
+    return request({
+      url: '/file/download',
+      method: 'get',
+      params: params
+    })
+  },
+
+  uploadFile: function (filePath, config = {}) {
+	return upload('/file/uploadFile?uploadPath=userdir',filePath)      
+  },
+  downloadFile: function (params) {
+    return request({
+      url: '/file/downloadFile',
+      method: 'get',
+      params: params
+    })
+  }
+}

+ 43 - 0
api/flowable/actCategoryService.js

@@ -0,0 +1,43 @@
+import request from "../../common/request"
+
+export default {
+	treeData: function (extId) {
+		return request({
+			url: "/extension/actCategory/treeData",
+			method: "get",
+			params: { extId: extId },
+		});
+	},
+
+	save: function (inputForm) {
+		return request({
+			url: "/extension/actCategory/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	drag: function (inputForm) {
+		return request({
+			url: "/extension/actCategory/drag",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/actCategory/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/extension/actCategory/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+};

+ 19 - 0
api/flowable/appModelsService.js

@@ -0,0 +1,19 @@
+import request from "../../common/request"
+
+export default {
+	models: function (data) {
+		return request({
+			url: "/rest/models",
+			// url: '/flowable/model/rest/models',
+			method: "post",
+			data: data,
+		});
+	},
+
+	editorJson: function (modelId) {
+		return request({
+			url: `/rest/models/${modelId}/editor/json?version=${new Date().getTime()}`,
+			method: "get",
+		});
+	},
+};

+ 50 - 0
api/flowable/buttonService.js

@@ -0,0 +1,50 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/extension/button/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/button/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/extension/button/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+	validateCodeNoExist: function (params) {
+		return request({
+			url: "/extension/button/validateCodeNoExist",
+			method: "get",
+			params: params,
+		});
+	},
+
+	validateNameNoExist: function (params) {
+		return request({
+			url: "/extension/button/validateNameNoExist",
+			method: "get",
+			params: params,
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/extension/button/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 35 - 0
api/flowable/conditionService.js

@@ -0,0 +1,35 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/extension/condition/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/condition/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/extension/condition/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/extension/condition/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 31 - 0
api/flowable/flowCopyService.js

@@ -0,0 +1,31 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/extension/flowCopy/save",
+			method: "post",
+			header: {
+				"Content-Type":
+					"application/x-www-form-urlencoded; charset=utf-8",
+			},
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/flowCopy/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/extension/flowCopy/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 41 - 0
api/flowable/formCategoryService.js

@@ -0,0 +1,41 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/extension/formCategory/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/formCategory/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+	drag: function (inputForm) {
+		return request({
+			url: "/extension/formCategory/drag",
+			method: "post",
+			data: inputForm,
+		});
+	},
+	queryById: function (id) {
+		return request({
+			url: "/extension/formCategory/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	treeData: function (extId) {
+		return request({
+			url: "/extension/formCategory/treeData",
+			method: "get",
+			params: { extId: extId },
+		});
+	},
+};

+ 43 - 0
api/flowable/formDefinitionJsonService.js

@@ -0,0 +1,43 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/extension/formDefinitionJson/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	updatePrimary: function (id) {
+		return request({
+			url: "/extension/formDefinitionJson/updatePrimary",
+			method: "put",
+			params: { id: id },
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/formDefinitionJson/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/extension/formDefinitionJson/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/extension/formDefinitionJson/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 42 - 0
api/flowable/formDefinitionService.js

@@ -0,0 +1,42 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/extension/formDefinition/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/formDefinition/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/extension/formDefinition/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+	queryByJsonId: function (jsonId) {
+		return request({
+			url: "/extension/formDefinition/queryByJsonId",
+			method: "get",
+			params: { jsonId: jsonId },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/extension/formDefinition/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 52 - 0
api/flowable/formService.js

@@ -0,0 +1,52 @@
+import request from "../../common/request"
+
+export default {
+	submitStartFormData: function (inputForm) {
+		return request({
+			url: "/flowable/form/submitStartFormData",
+			method: "post",
+			header: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' },
+			data: inputForm,
+		});
+	},
+
+	submitTaskFormData: function (inputForm) {
+		return request({
+			url: "/flowable/form/submitTaskFormData",
+			method: "post",
+			header: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' },
+			data: inputForm,
+		});
+	},
+
+	getStartFormData: function (params) {
+		return request({
+			url: "/flowable/form/getStartFormData",
+			method: "get",
+			params: params,
+		});
+	},
+	getHistoryTaskFormData: function (params) {
+		return request({
+			url: "/flowable/form/getHistoryTaskFormData",
+			method: "get",
+			params: params,
+		});
+	},
+
+	getTaskFormData: function (params) {
+		return request({
+			url: "/flowable/form/getTaskFormData",
+			method: "get",
+			params: params,
+		});
+	},
+  
+  getMobileForm: function (formDefinitionJsonId) {
+    return request({
+      url: '/flowable/form/getMobileForm',
+      method: 'get',
+      params: {formDefinitionJsonId: formDefinitionJsonId}
+    })
+  }
+}

+ 35 - 0
api/flowable/listenerService.js

@@ -0,0 +1,35 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/extension/listener/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/listener/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/extension/listener/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/extension/listener/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 70 - 0
api/flowable/modelService.js

@@ -0,0 +1,70 @@
+import request from "../../common/request"
+
+export default {
+	deploy: function (params) {
+		return request({
+			url: "/flowable/model/deploy",
+			method: "put",
+			params: params,
+		});
+	},
+	updateCategory: function (params) {
+		return request({
+			url: "/flowable/model/updateCategory",
+			method: "put",
+			params: params,
+		});
+	},
+	copy: function (id) {
+		return request({
+			url: "/flowable/model/copy",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	getBpmnXml: function (id) {
+		return request({
+			url: "/flowable/model/getBpmnXml",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	exportBpmnXml: function (id) {
+		return request({
+			url: "/flowable/model/exportBpmnXml",
+			method: "get",
+			params: { id: id },
+			responseType: "blob",
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/flowable/model/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	saveModel: function (modelId, data) {
+		return request({
+			url: `/flowable/model/saveModel/${modelId}`,
+			method: "post",
+			header: {
+				"Content-Type":
+					"application/x-www-form-urlencoded; charset=utf-8",
+			},
+			data: data,
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/flowable/model/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 43 - 0
api/flowable/nodeSettingService.js

@@ -0,0 +1,43 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/extension/nodeSetting/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/nodeSetting/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryValueByKey: function (params) {
+		return request({
+			url: "/extension/nodeSetting/queryValueByKey",
+			method: "get",
+			params: params,
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/extension/nodeSetting/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/extension/nodeSetting/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 102 - 0
api/flowable/processService.js

@@ -0,0 +1,102 @@
+import request from "../../common/request"
+
+export default {
+	list: function (params) {
+		return request({
+			url: "/flowable/process/list",
+			method: "get",
+			params: params,
+		});
+	},
+
+	runningDataList: function (params) {
+		return request({
+			url: "/flowable/process/runningData",
+			method: "get",
+			params: params,
+		});
+	},
+
+	historyListData: function (params) {
+		return request({
+			url: "/flowable/process/historyListData",
+			method: "get",
+			params: params,
+		});
+	},
+
+	revokeProcIns: function (id) {
+		return request({
+			url: "/flowable/process/revokeProcIns",
+			method: "put",
+			params: { id: id },
+		});
+	},
+
+	deleteProcIns: function (ids, reason) {
+		return request({
+			url: "/flowable/process/deleteProcIns",
+			method: "delete",
+			params: {
+				ids: ids,
+				reason: reason,
+			},
+		});
+	},
+
+	deleteAllProcIns: function (ids) {
+		return request({
+			url: "/flowable/process/deleteAllProcIns",
+			method: "delete",
+			params: { procInsIds: ids },
+		});
+	},
+
+	suspend: function (procDefId) {
+		return request({
+			url: "/flowable/process/update/suspend",
+			method: "put",
+			params: { procDefId: procDefId },
+		});
+	},
+
+	active: function (procDefId) {
+		return request({
+			url: "/flowable/process/update/active",
+			method: "put",
+			params: { procDefId: procDefId },
+		});
+	},
+
+	stop: function (id, message) {
+		return request({
+			url: "/flowable/process/stop",
+			method: "put",
+			params: { id: id, message: message },
+		});
+	},
+
+	getFlowChart: function (processDefId) {
+		return request({
+			url: "/flowable/process/getFlowChart",
+			method: "get",
+			params: { processDefId: processDefId },
+		});
+	},
+
+	queryProcessStatus: function (procDefId, procInsId) {
+		return request({
+			url: "/flowable/process/queryProcessStatus",
+			method: "get",
+			params: { procDefId: procDefId, procInsId: procInsId },
+		});
+	},
+
+	exist: function (key) {
+		return request({
+			url: "/flowable/process/exist",
+			method: "get",
+			params: { key: key },
+		});
+	},
+};

+ 43 - 0
api/flowable/taskDefExtensionService.js

@@ -0,0 +1,43 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/extension/taskDefExtension/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/extension/taskDefExtension/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/extension/taskDefExtension/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	queryByDefIdAndTaskId: function (params) {
+		return request({
+			url: "/extension/taskDefExtension/queryByDefIdAndTaskId",
+			method: "get",
+			params: params,
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/extension/taskDefExtension/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 131 - 0
api/flowable/taskService.js

@@ -0,0 +1,131 @@
+import request from "../../common/request"
+
+export default {
+  start (params) {
+		return request({
+			url: "/flowable/task/start",
+			method: "post",
+			params: params
+		});
+	},
+
+	todoList: function (params) {
+		return request({
+			url: "/flowable/task/todo",
+			method: "get",
+			params: params,
+		});
+	},
+
+	historicList: function (params) {
+		return request({
+			url: "/flowable/task/historic",
+			method: "get",
+			params: params,
+		});
+	},
+
+	historicTaskList: function (procInsId) {
+		return request({
+			url: "/flowable/task/historicTaskList",
+			method: "get",
+			params: { procInsId: procInsId },
+		});
+	},
+
+	myApplyedList: function (params) {
+		return request({
+			url: "/flowable/task/myApplyed",
+			method: "get",
+			params: params,
+		});
+	},
+
+	getTaskDef: function (params) {
+		return request({
+			url: "/flowable/task/getTaskDef",
+			method: "get",
+			params: params,
+		});
+	},
+
+	delegate: function (taskId, userId) {
+		return request({
+			url: "/flowable/task/delegate",
+			method: "put",
+			params: { taskId: taskId, userId: userId },
+		});
+	},
+
+	callback: function (params) {
+		return request({
+			url: "/flowable/task/callback",
+			method: "put",
+			params: params,
+		});
+	},
+
+	audit: function (data) {
+		return request({
+			url: "/flowable/task/audit",
+			method: "post",
+			header: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' },
+			data: data,
+		});
+	},
+
+	backNodes: function (taskId) {
+		return request({
+			url: "/flowable/task/backNodes",
+			method: "put",
+			params: { taskId: taskId },
+		});
+	},
+
+	back: function (params) {
+		return request({
+			url: "/flowable/task/back",
+			method: "put",
+			params: params,
+		});
+	},
+
+	transfer: function (taskId, userId) {
+		return request({
+			url: "/flowable/task/transfer",
+			method: "put",
+			params: { taskId: taskId, userId: userId },
+		});
+	},
+
+	addSignTask: function (data) {
+		return request({
+			url: "/flowable/task/addSignTask",
+			method: "post",
+			header: {
+				"Content-Type":
+					"application/x-www-form-urlencoded; charset=utf-8",
+			},
+			data: data,
+		});
+	},
+	getFlowChart: function (processInstanceId) {
+		return request({
+			url: "/flowable/task/getFlowChart",
+			method: "get",
+			params: { processInstanceId: processInstanceId },
+		});
+	},
+
+	urge: function (data) {
+		return request({
+			url: "/flowable/task/urge",
+			method: "post",
+			header: {
+				"Content-Type":
+					"application/x-www-form-urlencoded; charset=utf-8",
+			},
+			data: data,
+		});
+	},
+};

+ 39 - 0
api/form/generateFormService.js

@@ -0,0 +1,39 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/form/generate/save",
+			method: "post",
+			header: {
+				"Content-Type":
+					"application/x-www-form-urlencoded; charset=utf-8",
+			},
+			data: inputForm,
+		});
+	},
+
+	queryById: function (params) {
+		return request({
+			url: "/form/generate/queryById",
+			method: "get",
+			params: params,
+		});
+	},
+
+	delete: function (params) {
+		return request({
+			url: "/form/generate/delete",
+			method: "delete",
+			params: params,
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/form/generate/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 95 - 0
api/form/makeFormService.js

@@ -0,0 +1,95 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/form/make/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	saveFormSource: function (inputForm) {
+		return request({
+			url: "/form/make/saveFormSource",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	saveBasicInfo: function (inputForm) {
+		return request({
+			url: "/form/make/saveBasicInfo",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/form/make/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/form/make/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	getTableColumnList: function (params) {
+		return request({
+			url: "/form/make/getTableColumnList",
+			method: "get",
+			params: params,
+		});
+	},
+
+	getTableList: function (params) {
+		return request({
+			url: "/form/make/getTableList",
+			method: "get",
+			params: params,
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/form/make/list",
+			method: "get",
+			params: params,
+		});
+	},
+
+	validateTableNoExist: function (params) {
+		return request({
+			url: "/form/make/validateTableNoExist",
+			method: "get",
+			params: params,
+		});
+	},
+
+	validateKeyNoExist: function (params) {
+		return request({
+			url: "/form/make/validateKeyNoExist",
+			method: "get",
+			params: params,
+		});
+	},
+
+	createMenu: function (inputForm) {
+		return request({
+			url: "/form/make/createMenu",
+			method: "post",
+			header: {
+				"Content-Type":
+					"application/x-www-form-urlencoded; charset=utf-8",
+			},
+			data: inputForm,
+		});
+	},
+};

+ 33 - 0
api/mail/mailBoxService.js

@@ -0,0 +1,33 @@
+import request from "../../common/request"
+
+export default {
+	delete: function (ids) {
+		return request({
+			url: "/mail/box/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/mail/box/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+	queryStatus: function () {
+		return request({
+			url: "/mail/box/queryStatus",
+			method: "get",
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/mail/box/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 35 - 0
api/mail/mailComposeService.js

@@ -0,0 +1,35 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/mail/compose/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/mail/compose/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/mail/compose/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/mail/compose/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 27 - 0
api/mail/mailTrashService.js

@@ -0,0 +1,27 @@
+import request from "../../common/request"
+
+export default {
+	delete: function (ids) {
+		return request({
+			url: "/mail/trash/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/mail/trash/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/mail/trash/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 42 - 0
api/notify/notifyService.js

@@ -0,0 +1,42 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/notify/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/notify/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/notify/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+	query: function (params) {
+		return request({
+			url: "/notify/queryById",
+			method: "get",
+			params: params,
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/notify/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 43 - 0
api/sys/areaService.js

@@ -0,0 +1,43 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/sys/area/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	drag: function (inputForm) {
+		return request({
+			url: "/sys/area/drag",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/sys/area/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/sys/area/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	treeData: function (extId) {
+		return request({
+			url: "/sys/area/treeData",
+			method: "get",
+			params: { extId: extId },
+		});
+	},
+};

+ 25 - 0
api/sys/configService.js

@@ -0,0 +1,25 @@
+import request from "../../common/request"
+
+export default {
+	getConfig: function () {
+		return request({
+			url: "/sys/sysConfig/getConfig",
+			method: "get",
+		});
+	},
+
+	queryById: function () {
+		return request({
+			url: "/sys/sysConfig/queryById",
+			method: "get",
+		});
+	},
+
+	save: function (inputForm) {
+		return request({
+			url: "/sys/sysConfig/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+};

+ 41 - 0
api/sys/dataRuleService.js

@@ -0,0 +1,41 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/sys/dataRule/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (id) {
+		return request({
+			url: "/sys/dataRule/delete",
+			method: "delete",
+			params: { id: id },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/sys/dataRule/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/sys/dataRule/list",
+			method: "get",
+			params: params,
+		});
+	},
+	treeData: function () {
+		return request({
+			url: "/sys/dataRule/treeData",
+			method: "get",
+		});
+	},
+};

+ 80 - 0
api/sys/dictService.js

@@ -0,0 +1,80 @@
+import request from "../../common/request"
+
+export default {
+	queryById: function (id) {
+		return request({
+			url: "/sys/dict/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	save: function (inputForm) {
+		return request({
+			url: "/sys/dict/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/sys/dict/type/list",
+			method: "get",
+			params: params,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/sys/dict/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryDictValue: function (id) {
+		return request({
+			url: "/sys/dict/queryDictValue",
+			method: "get",
+			params: { dictValueId: id },
+			loading: false,
+		});
+	},
+
+	saveDictValue: function (inputForm) {
+		return request({
+			url: "/sys/dict/saveDictValue",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	getDictValue: function (dictTypeId) {
+		return request({
+			url: "/sys/dict/getDictValue",
+			method: "get",
+			params: {
+				dictTypeId: dictTypeId,
+			},
+		});
+	},
+
+	getDictMap: function (dictTypeId) {
+		return request({
+			url: "/sys/dict/getDictMap",
+			method: "get",
+			params: {
+				dictTypeId: dictTypeId,
+			},
+		});
+	},
+
+	deleteDictValue: function (ids) {
+		return request({
+			url: "/sys/dict/deleteDictValue",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+};

+ 34 - 0
api/sys/logService.js

@@ -0,0 +1,34 @@
+import request from "../../common/request"
+
+export default {
+	list: function (params) {
+		return request({
+			url: "/sys/log/list",
+			method: "get",
+			params: params,
+		});
+	},
+
+	mine: function (params) {
+		return request({
+			url: "/sys/log/data/mine",
+			method: "get",
+			params: params,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/sys/log/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	empty: function () {
+		return request({
+			url: "/sys/log/empty",
+			method: "delete",
+		});
+	},
+};

+ 43 - 0
api/sys/menuService.js

@@ -0,0 +1,43 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/sys/menu/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	drag: function (inputForm) {
+		return request({
+			url: "/sys/menu/drag",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/sys/menu/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/sys/menu/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	treeData: function (params) {
+		return request({
+			url: "/sys/menu/treeData",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 43 - 0
api/sys/officeService.js

@@ -0,0 +1,43 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/sys/office/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	drag: function (inputForm) {
+		return request({
+			url: "/sys/office/drag",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/sys/office/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/sys/office/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	treeData: function (params) {
+		return request({
+			url: "/sys/office/treeData",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 35 - 0
api/sys/postService.js

@@ -0,0 +1,35 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/sys/post/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/sys/post/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/sys/post/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/sys/post/list",
+			method: "get",
+			params: params,
+		});
+	},
+};

+ 77 - 0
api/sys/roleService.js

@@ -0,0 +1,77 @@
+import request from "../../common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/sys/role/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/sys/role/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/sys/role/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	validateNotExist: function (obj) {
+		return request({
+			url: "/sys/role/validateNotExist",
+			method: "get",
+			params: obj,
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/sys/role/list",
+			method: "get",
+			params: params,
+		});
+	},
+	assign: function (params) {
+		return request({
+			url: "/sys/role/assign",
+			method: "get",
+			params: params,
+		});
+	},
+
+	assignAuthorityToRole: function (inputForm) {
+		return request({
+			url: "/sys/role/assignAuthorityToRole",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	removeUserFromRole: function (userId, roleId) {
+		return request({
+			url: "/sys/role/removeUserFromRole",
+			method: "delete",
+			params: { userId: userId, roleId: roleId },
+		});
+	},
+
+	addUserToRole: function (roleId, userIds) {
+		return request({
+			url: "/sys/role/addUserToRole",
+			method: "put",
+			params: {
+				roleId: roleId,
+				userIds: userIds,
+			},
+		});
+	},
+};

+ 59 - 0
api/sys/userService.js

@@ -0,0 +1,59 @@
+import request from "../../common/request"
+
+export default {
+
+	saveInfo: function (inputForm) {
+		return request({
+			url: "/sys/user/saveInfo",
+			method: "post",
+			header: { arrayFormat: "repeat" },
+			data: inputForm,
+		});
+	},
+
+	savePwd: function (inputForm) {
+		return request({
+			url: "/sys/user/savePwd",
+			method: "put",
+			params: inputForm,
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/sys/user/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	getMenus: function () {
+		return request({
+			url: "/sys/user/getMenus",
+			method: "get",
+		});
+	},
+
+	info: function () {
+		return request({
+			url: "/sys/user/info",
+			method: "get",
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/sys/user/list",
+			method: "get",
+			params: params,
+		});
+	},
+
+	treeData: function (params) {
+		return request({
+			url: "/sys/user/treeData",
+			method: "get",
+			params: params,
+		});
+	}
+}

BIN
api/test/.DS_Store


+ 35 - 0
api/test/activiti/testActivitiLeaveService.js

@@ -0,0 +1,35 @@
+import request from "../../../common/request"
+
+export default {
+  save: function (inputForm) {
+    return request({
+      url: '/test/activiti/testActivitiLeave/save',
+      method: 'post',
+      data: inputForm
+    })
+  },
+
+  delete: function (ids) {
+    return request({
+      url: '/test/activiti/testActivitiLeave/delete',
+      method: 'delete',
+      params: {ids: ids}
+    })
+  },
+
+  queryById: function (id) {
+    return request({
+      url: '/test/activiti/testActivitiLeave/queryById',
+      method: 'get',
+      params: {id: id}
+    })
+  },
+
+  list: function (params) {
+    return request({
+      url: '/test/activiti/testActivitiLeave/list',
+      method: 'get',
+      params: params
+    })
+  }
+}

+ 60 - 0
api/test/mobile/testMobileService.js

@@ -0,0 +1,60 @@
+import request from "@/common/request"
+
+export default {
+	save: function (inputForm) {
+		return request({
+			url: "/test/mobile/testMobile/save",
+			method: "post",
+			data: inputForm,
+		});
+	},
+
+	delete: function (ids) {
+		return request({
+			url: "/test/mobile/testMobile/delete",
+			method: "delete",
+			params: { ids: ids },
+		});
+	},
+
+	queryById: function (id) {
+		return request({
+			url: "/test/mobile/testMobile/queryById",
+			method: "get",
+			params: { id: id },
+		});
+	},
+
+	list: function (params) {
+		return request({
+			url: "/test/mobile/testMobile/list",
+			method: "get",
+			params: params,
+		});
+	},
+
+	exportTemplate: function () {
+		return request({
+			url: "/test/mobile/testMobile/import/template",
+			method: "get",
+			responseType: "blob",
+		});
+	},
+
+	exportExcel: function (params) {
+		return request({
+			url: "/test/mobile/testMobile/export",
+			method: "get",
+			params: params,
+			responseType: "blob",
+		});
+	},
+
+	importExcel: function (data) {
+		return request({
+			url: "/test/mobile/testMobile/import",
+			method: "post",
+			data: data,
+		});
+	},
+};

+ 111 - 0
common/auth.js

@@ -0,0 +1,111 @@
+
+const tokenKey = 'token'
+const usernameKey = 'WMS-username'
+const userInfoKey = 'WMS-userinfo'
+const permissionsKey = 'WMS-permission'
+import store from '@/store'
+
+// 获取token值
+function getUserToken(){
+	return uni.getStorageSync(tokenKey);
+}
+
+function setUserToken(token){
+	uni.setStorageSync(tokenKey,token);
+}
+
+function removeUserToken(){
+	uni.removeStorageSync(tokenKey);
+}
+
+
+// 获取用户名
+function getUsername(){
+	return uni.getStorageSync(usernameKey);
+}
+
+function setUsername(username){
+	uni.setStorageSync(usernameKey,username);
+}
+
+function removeUsername(){
+	uni.removeStorageSync(usernameKey);
+}
+
+// 获取用户信息
+function getUserInfo(){
+	return uni.getStorageSync(userInfoKey);
+}
+
+function setUserInfo(userinfo){
+	uni.setStorageSync(userInfoKey,userinfo);
+}
+
+function removeUserInfo(){
+	uni.removeStorageSync(userInfoKey);
+}
+
+// 获取用户权限
+function getPermissions(){
+	return uni.getStorageSync(permissionsKey);
+}
+
+function setPermissions(permissions){
+	uni.setStorageSync(permissionsKey,permissions);
+}
+
+function removePermissions(){
+	uni.removeStorageSync(permissionsKey);
+}
+function hasPermission (key) {
+  return uni.getStorageSync(permissionsKey).indexOf(key) !== -1 || false
+}
+
+function checkLogin () {
+	if (!store.state.user.token) {
+		uni.showModal({
+			title: '未登录',
+			content: '您未登录,需要登录后才能继续',
+			/**
+			 * 如果需要强制登录,不显示取消按钮
+			 */
+			showCancel: !store.state.user.forcedLogin,
+			success: (res) => {
+				if (res.confirm) {
+					/**
+					 * 如果需要强制登录,使用reLaunch方式
+					 */
+					if (store.state.user.forcedLogin) {
+						uni.reLaunch({
+							url: '/pages/login/login'
+						});
+					} else {
+						uni.navigateTo({
+							url: '/pages/login/login'
+						});
+					}
+				}
+			}
+		});
+	}
+}
+
+export {
+	getUserToken,
+	setUserToken,
+	removeUserToken,
+	
+	getUsername,
+	setUsername,
+	removeUsername,
+	
+	getUserInfo,
+	setUserInfo,
+	removeUserInfo,
+	
+	getPermissions,
+	setPermissions,
+	removePermissions,
+	hasPermission,
+	checkLogin
+}

+ 64 - 0
common/dictUtils.js

@@ -0,0 +1,64 @@
+import $http from './request.js'
+const dictListKey = 'dictList'
+
+export function getDictLabel (type, value, defaultLabel) {
+  if ((!value && value !== 0) || (!type && type !== 0)) {
+    if (defaultLabel !== undefined) {
+      return defaultLabel
+    } else {
+      return '--'
+    }
+  }
+  let dictList = uni.getStorageSync(dictListKey)
+  let dicts = dictList[type]
+  if (dicts) {
+    for (let i = 0; i < dicts.length; i++) {
+      if (dicts[i].value && dicts[i].value.toString() === value.toString()) {
+        return dicts[i].label
+      }
+    }
+  }
+  if (defaultLabel !== undefined) {
+    return defaultLabel
+  } else {
+    return '--'
+  }
+}
+
+export function getDictValue (type, label, defaultValue) {
+  if ((!label && label !== 0) || (!type && type !== 0)) {
+    if (defaultValue !== undefined) {
+      return defaultValue
+    } else {
+      return '--'
+    }
+  }
+  let dictList = uni.getStorageSync(dictListKey)
+  let dicts = dictList[type]
+  if (dicts) {
+    for (let i = 0; i < dicts.length; i++) {
+      if (dicts[i].label && dicts[i].label.toString() === label.toString()) {
+        return dicts[i].value
+      }
+    }
+  }
+  if (defaultValue !== undefined) {
+    return defaultValue
+  } else {
+    return '--'
+  }
+}
+
+export function getDictList (type) {
+  let dictList = uni.getStorageSync(dictListKey)
+  if (!type && type !== 0) { // 不传参 返回全部字典
+    return  dictList
+  }
+  let dicts = dictList[type]
+  return dicts || []
+}
+export function setDictList(dictList){
+	uni.setStorageSync(dictListKey,dictList);
+}
+
+export default {getDictLabel, getDictValue, getDictList, setDictList}

+ 11 - 0
common/filter.js

@@ -0,0 +1,11 @@
+import Vue from 'vue'
+import moment from 'moment'
+
+Vue.filter('formatDate', function (value, formatString) {
+  formatString = formatString || 'YYYY-MM-DD HH:mm:ss'
+  if (value) {
+    return moment(value).format(formatString)
+  } else {
+    return '--'
+  }
+})

+ 167 - 0
common/graceChecker.js

@@ -0,0 +1,167 @@
+/**
+数据验证(表单验证)
+来自 grace.hcoder.net 
+作者 hcoder 深海
+*/
+module.exports = {
+	error:'',
+	check : function (data, rule){
+		for(var i = 0; i < rule.length; i++){
+			if (!rule[i].checkType){return true;}
+			if (!rule[i].name) {return true;}
+			if (!rule[i].errorMsg) {return true;}
+			let value = data
+			
+			rule[i].name.split('.').forEach((key)=>{
+				value = value[key]
+			})
+			if (!value) {this.error = rule[i].errorMsg; return false;}
+			switch (rule[i].checkType){
+				case 'string':
+					var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
+					if(!reg.test(value)) {this.error = rule[i].errorMsg; return false;}
+				break;
+				case 'int':
+					var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$');
+					if(!reg.test(value)) {this.error = rule[i].errorMsg; return false;}
+					break;
+				break;
+				case 'between':
+					if (!this.isNumber(value)){
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+					var minMax = rule[i].checkRule.split(',');
+					minMax[0] = Number(minMax[0]);
+					minMax[1] = Number(minMax[1]);
+					if (value > minMax[1] || value < minMax[0]) {
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+				break;
+				case 'betweenD':
+					var reg = /^-?[1-9][0-9]?$/;
+					if (!reg.test(value)) { this.error = rule[i].errorMsg; return false; }
+					var minMax = rule[i].checkRule.split(',');
+					minMax[0] = Number(minMax[0]);
+					minMax[1] = Number(minMax[1]);
+					if (value > minMax[1] || value < minMax[0]) {
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+				break;
+				case 'betweenF': 
+					var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
+					if (!reg.test(value)){this.error = rule[i].errorMsg; return false;}
+					var minMax = rule[i].checkRule.split(',');
+					minMax[0] = Number(minMax[0]);
+					minMax[1] = Number(minMax[1]);
+					if (value > minMax[1] || value < minMax[0]) {
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+				break;
+				case 'same':
+					if (value != rule[i].checkRule) { this.error = rule[i].errorMsg; return false;}
+				break;
+				case 'notsame':
+					if (value == rule[i].checkRule) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'isEmail':
+					var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
+					if (!reg.test(value)) { this.error = rule[i].errorMsg || rule[i].name + '不是合法的邮箱格式!'; return false; }
+				break;
+				case 'isMobile':
+					var reg = /^1[0-9]{10,10}$/;
+					if (!reg.test(value)) { this.error = rule[i].errorMsg || rule[i].name + '不是合法的手机号码!'; return false; }
+				break;
+				case 'isUrl':
+					var reg = /^http[s]?:\/\/.*/
+					if (!reg.test(value)) { this.error = rule[i].errorMsg|| rule[i].name + '不是合法的URL!'; return false; }
+				break;
+				case 'zipcode':
+					var reg = /^[0-9]{6}$/;
+					if (!reg.test(value)) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'reg':
+					var reg = new RegExp(rule[i].checkRule);
+					if (!reg.test(value)) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'in':
+					if(rule[i].checkRule.indexOf(value) == -1){
+						this.error = rule[i].errorMsg; return false;
+					}
+				break;
+				case 'notnull':
+					if(value == null || value.length < 1){this.error = rule[i].errorMsg; return false;}
+				break;
+			}
+		}
+		return true;
+	},
+
+	checkFormData : function (data){
+		for(i=0; i<data.length; i++){
+			let item = data[i]
+			let name = item.name
+			let value = item.value
+			if(!(item.readable && item.writable)){
+				continue
+			}
+			if(item.options.required){
+				if(value == null || value.length < 1){
+					return name+": "+ (item.options.requiredMessage || '必填项不能为空!')
+				}
+			}
+			if(item.options.dataType  && item.options.dataTypeCheck){
+				switch (item.options.dataType ){
+					case 'number':
+						var reg = /^-?[0-9]+(\.\d+)?$/
+						if (!reg.test(value)) {
+							return name+": "+ item.options.dataTypeMessage
+						}
+					break;
+					case 'integer':
+						if (!(/^0$/.test(value) || /^(-[1-9]|[1-9])[0-9]*$/.test(value))) { 
+							return name+": "+ item.options.dataTypeMessage
+						}
+					break;
+					case 'float':
+						if (!(/^\d+(\.\d+)?$/.test(value) || /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/)) {
+							return name+": "+ item.options.dataTypeMessage
+						}
+					break;
+					case 'url':
+						var reg = /^http[s]?:\/\/.*/
+						if (!reg.test(value)) {
+							return name+": "+ item.options.dataTypeMessage
+						}
+					break;
+					case 'email':
+						var reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/
+						if (!reg.test(value)) {
+							return name+": "+ item.options.dataTypeMessage
+						}
+					break;
+					case 'hex':
+						var reg = /^[0-9a-fA-F]{1,3}$/
+						if (!reg.test(value)) {
+							return name+": "+ item.options.dataTypeMessage
+						}
+					break;
+				}
+			};
+			if(item.options.pattern && item.options.patternMessage && item.options.patternCheck){
+				var reg = new RegExp(item.options.pattern)
+				if (!reg.test(value)) {
+					return name+": "+ item.options.patternMessage
+				}
+			}
+		}
+		return ''
+	},
+	isNumber : function (checkVal){
+		var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
+		return reg.test(checkVal);
+	}
+}

+ 114 - 0
common/helper.js

@@ -0,0 +1,114 @@
+/**
+ * 用于定义公用的方法,定义全局参数
+ * 
+ * 
+ */
+// 全局变量
+const globalData = {
+	
+}
+
+// 格式化时间
+const formatDate = function(time, cFormat) {
+	if (arguments.length === 0) {
+		return null
+	}
+	if (!time) {
+		return '';
+	}
+
+	let fmt = cFormat || 'yyyy-MM-dd HH:mm:ss';
+
+	let date;
+	if (typeof time === 'object') {
+		date = time;
+	} else if (typeof time === 'string') {
+		time = time.replace(/-/g,'/');			// 为了兼容ios,ios只能转换2019/12/12这种时间格式
+		date = new Date(time);
+	} else {
+		date = new Date(parseInt(time));
+	}
+
+	var o = {
+		"M+": date.getMonth() + 1, //月份
+		"d+": date.getDate(), //日
+		"h+": date.getHours() % 12 == 0 ? 12 : date.getHours() % 12, //小时
+		"H+": date.getHours(), //小时
+		"m+": date.getMinutes(), //分
+		"s+": date.getSeconds(), //秒
+		"q+": Math.floor((date.getMonth() + 3) / 3), //季度
+		"S": date.getMilliseconds() //毫秒
+	};
+	var week = {
+		"0": "\u65e5",
+		"1": "\u4e00",
+		"2": "\u4e8c",
+		"3": "\u4e09",
+		"4": "\u56db",
+		"5": "\u4e94",
+		"6": "\u516d"
+	};
+	if (/(y+)/.test(fmt)) {
+		fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
+	}
+	if (/(E+)/.test(fmt)) {
+		fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "\u661f\u671f" : "\u5468") : "") +
+			week[date.getDay() + ""]);
+	}
+	for (var k in o) {
+		if (new RegExp("(" + k + ")").test(fmt)) {
+			fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
+		}
+	}
+	return fmt;
+}
+
+// 获取随机数
+const getUuid = function() {
+    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
+        return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
+    })
+}
+
+// ajax错误处理
+const catchError = function(error) {
+    let _this = this;
+    if (error.response) {
+      switch (error.response.status) {
+        case 400:
+          _this.$message({
+            message: error.response.data.msg || '请求参数异常',
+            type: 'error'
+          });
+          break;
+        case 401:
+        //   sessionStorage.removeItem('user');
+          _this.$message({
+            message: error.response.data.msg || '密码错误或账号不存在!',
+            type: 'warning',
+            onClose: function(){
+              location.reload();
+            }
+          });
+          break;
+        case 403:
+          _this.$message({
+            message: error.response.data.msg || '无访问权限,请联系企业管理员',
+            type: 'warning'
+          });
+          break;
+        default:
+          _this.$message({
+            message: error.response.data.msg || '服务端异常,请联系技术支持',
+            type: 'error'
+          });
+      }
+    };
+}
+
+export default {
+	globalData,			// 全局变量
+	formatDate,			// 格式化时间
+	getUuid,			// 获取uuid
+	catchError,			// ajax错误处理
+}

+ 7 - 0
common/mixin.js

@@ -0,0 +1,7 @@
+export default {
+    data() {
+        return {
+
+        }
+    }
+}

+ 143 - 0
common/request.js

@@ -0,0 +1,143 @@
+import * as $auth from "./auth"
+import BASE_URL from './../config.js'
+import qs from 'qs'
+
+function error(res){
+	if (res.statusCode === 408 || res.statusCode === 401) {// 需要重新登录
+		$auth.removeUserToken();
+		$auth.checkLogin()
+	}else if(res.statusCode === 404){
+		uni.showToast({
+			title:"404,路径找不到:"+res.data.path,
+			icon:"none"
+		})
+	}else if(res.statusCode === 503){
+		uni.showToast({
+			title:"服务不可用",
+			icon:"none"
+		})
+	}else if(res.statusCode === 504){
+		uni.showToast({
+			title:"网络连接错误",
+			icon:"none"
+		})
+	}else{
+		uni.showToast({
+			title:res.data,
+			icon:"none"
+		})
+	}
+}
+export function request(body){
+	let {url,method,data,header, params, responseType} = body
+	data = data || params || {};
+	header = header || {'Content-Type': 'application/json; charset=utf-8'}
+	method = method.toUpperCase() || "GET";
+	responseType = responseType || "text"
+	let token = $auth.getUserToken();
+	if(token){
+		header.token = token;			// 获取token值
+	}
+	if(method === 'POST' && header['Content-Type'] === 'application/x-www-form-urlencoded; charset=utf-8'){
+		data = qs.stringify(data,  { allowDots: true, arrayFormat: 'indices' })
+	}else if(method === 'GET' || method === 'DELETE' || method === 'PUT'){
+		url = url + '?' +  qs.stringify(data, { allowDots: true, arrayFormat: 'indices' }) 
+		data = null
+
+	}
+	
+	let promise = new Promise((resolve,reject)=>{
+		uni.request({
+			url: BASE_URL + url,
+			header:header,
+			data: data,
+			method: method,
+			responseType: responseType,
+			success: res => {
+				if(res && res.statusCode !== 200){
+					error(res);
+					reject(res)
+				}
+				resolve(res.data);
+			},
+			fail: (res) => {
+				uni.hideLoading();
+				error(res);
+				reject(res);
+			},
+			complete: () => {	
+			}
+		});
+	})
+	return promise;
+}
+
+// 单文件上传
+export function upload(url, filePath,filename, formData,header,success,fail){
+	let name = filename || 'file';
+	header = header || {};
+	let token = $auth.getUserToken();
+	if(token){
+		header.token = token;			// 获取token值
+	}
+	
+	let promise = new Promise((resolve,reject)=>{
+		uni.uploadFile({
+			url: BASE_URL + url,
+			filePath:filePath,
+			name: 'file', 
+			formData: formData || {},
+			header:header,
+			success: res => {
+				resolve(res.data);
+			},
+			fail: (res) => {
+				uni.hideLoading();
+				let err = JSON.parse(res);
+				error(err);
+				reject(err);
+			},
+			complete: () => {	
+			}
+		});
+	})
+	return promise;
+}
+
+export function download(url,header,success,fail){
+	header = header || {};
+	let token = $auth.getUserToken();
+	if(token){
+		header.token = token;			// 获取token值
+	}
+	if(!url){
+		return;
+	}
+	let downloadTask = uni.downloadFile({
+		url: url,
+		success: (res) => {
+			if(res.statusCode===200){
+				if(success){
+					success.call(null,res);
+				}
+			}else{
+				if(fail){
+					fail.call(null,res);
+				}
+			}
+		},
+		fail:(res) => {
+			let err = JSON.parse(res);
+			error(err);
+			if(fail){
+				fail.call(null,err)
+			}
+		},
+		complete: () => {
+			
+		}
+	});
+	return downloadTask;
+}
+
+export default request

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 88 - 0
common/util.js


BIN
components/.DS_Store


+ 75 - 0
components/cu-navbar/cu-navbar.vue

@@ -0,0 +1,75 @@
+<template>
+	<view>
+		<view class="cu-custom" :style="[{height:CustomBar + 'px'}]">
+			<view class="cu-bar fixed" :style="style" :class="[bgImage!=''?'none-bg text-white bg-img':'',bgColor]">
+				<view class="action" @tap="BackPage" v-if="isBack">
+					<text class="cuIcon-back"></text>
+					<slot name="backText"></slot>
+				</view>
+				<view class="content" :style="[{top:StatusBar + 'px'}]">
+					<slot name="content"></slot>
+				</view>
+				<slot name="right"></slot>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				StatusBar: this.StatusBar,
+				CustomBar: this.CustomBar
+			};
+		},
+		name: 'cu-custom',
+		computed: {
+			style() {
+				var StatusBar= this.StatusBar;
+				var CustomBar= this.CustomBar;
+				var bgImage = this.bgImage;
+				var style = `height:${CustomBar}px;padding-top:${StatusBar}px;`;
+				if (this.bgImage) {
+					style = `${style}background-image:url(${bgImage});`;
+				}
+				return style
+			}
+		},
+		props: {
+			bgColor: {
+				type: String,
+				default: ''
+			},
+			isBack: {
+				type: [Boolean, String],
+				default: false
+			},
+			backUrl: {
+				type: String,
+				default: ''
+			},
+			bgImage: {
+				type: String,
+				default: ''
+			},
+		},
+		methods: {
+			BackPage() {
+				if(this.backUrl){
+					uni.navigateTo({
+						url: this.backUrl
+					})
+				}else{
+					uni.navigateBack({
+						delta: 1
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 236 - 0
components/generate-form/generate-form.vue

@@ -0,0 +1,236 @@
+<template>
+	<view>
+		<u--form labelWidth="100px" class="u-form" labelPosition="left" >
+			
+			<u-form-item :label="item.name" borderBottom v-if="item.readable" v-for="(item,index) in formData" :key="index">
+			<!-- 	<view class="title">
+					<text class="red-color " v-if="item.options.required">* </text> {{item.name}}
+				</view> -->
+				<template v-if="item.type=='input'">				
+					<!-- 普通输入框 -->
+					 <u--input :placeholder='item.placeholder'  :disabled="!item.writable"  v-model="item.value" border="none"></u--input>
+				</template>	
+				<template v-if="item.type=='textarea' || item.type=='editor'">
+					<!-- 多行文本输入框 -->
+					<u--textarea :placeholder='item.placeholder' :disabled="!item.writable"   v-model="item.value" border="none"></u--textarea>
+				</template>	
+				<template v-if="item.type=='number'">
+					<!-- 计数器 -->
+					<u-number-box :placeholder='item.placeholder' :disabled="!item.writable"   v-model="item.value"></u-number-box>
+				</template>	
+				<template v-if="item.type=='radio'">
+					<!-- 单选框 -->
+				<u-radio-group
+					v-if="item.options.remote === 3" 
+				    v-model="item.value"
+					:disabled="!item.writable"
+				    placement="column"
+				  >
+				    <u-radio
+				      :customStyle="{margin: '8px'}"
+				      v-for="(option, index) in $dictUtils.getDictList(item.options.dictType)"
+				      :key="index"
+				      :label="option.label"
+				      :name="option.value"
+				    >
+				    </u-radio>
+				  </u-radio-group>
+				  <u-radio-group
+				  	 v-else-if="item.options.showLabel"
+				     v-model="item.value"
+				  	 :disabled="!item.writable"
+				     placement="column"
+				    >
+				      <u-radio
+				        :customStyle="{margin:'8px'}"
+				        v-for="(option, index) in item.options.options"
+				        :key="index"
+				        :label="option.label"
+				        :name="option.value"
+				      >
+				      </u-radio>
+				    </u-radio-group>
+					<u-radio-group
+					   v-else
+					   v-model="item.value"
+					   :disabled="!item.writable"
+					   placement="column"
+					  >
+					    <u-radio
+					      :customStyle="{margin:'8px'}"
+					      v-for="(option, index) in item.options.options"
+					      :key="index"
+					      :label="option.value"
+					      :name="option.value"
+					    >
+					    </u-radio>
+					  </u-radio-group>
+				</template>	
+				<template v-if="item.type=='checkbox'">
+					 <u-checkbox-group
+								v-if="item.options.remote === 3"
+					            v-model="item.value"
+					            :disabled="!item.writable"
+					            placement="column"
+					        >
+						<u-checkbox
+							:customStyle="{margin: '8px'}"
+							v-for="(option, index) in $dictUtils.getDictList(item.options.dictType)"
+							:key="index"
+							:label="option.label || option.value"
+							:name="option.value"
+						>
+						</u-checkbox>
+					</u-checkbox-group>
+					<u-checkbox-group
+								v-else-if="item.options.showLabel"
+					            v-model="item.value"
+					            :disabled="!item.writable"
+					            placement="column"
+					        >
+						<u-checkbox
+							:customStyle="{margin: '8px'}"
+							v-for="(option, index) in item.options.options"
+							:key="index"
+							:label="option.label"
+							:name="option.value"
+						>
+						</u-checkbox>
+					</u-checkbox-group>
+					<u-checkbox-group
+								v-else
+					            v-model="item.value"
+					            :disabled="!item.writable"
+					            placement="column"
+					        >
+						<u-checkbox
+							:customStyle="{margin: '8px'}"
+							v-for="(option, index) in item.options.options"
+							:key="index"
+							:label="option.value"
+							:name="option.value"
+						>
+						</u-checkbox>
+					</u-checkbox-group>
+				</template>	
+				<template v-if="item.type=='time'">
+					<!-- 时间控件 -->
+					<jp-datetime-picker  v-model="item.value" :placeholder='item.placeholder' :disabled="!item.writable" mode="time"></jp-datetime-picker>
+				</template>	
+				<template v-if="item.type=='date'">
+					<!-- 日期控件 -->
+					<jp-datetime-picker  v-model="item.value" :placeholder='item.placeholder' :disabled="!item.writable" mode="date"></jp-datetime-picker>
+				</template>	
+				<template v-if="item.type=='rate'">
+					<!-- 评分 -->
+					<u-rate :disabled="!item.writable" :count="item.options.max" v-model="item.value"></u-rate>
+				</template>	
+				<template v-if="item.type=='color'">
+					<!-- 颜色选择框 -->
+					<jp-color-picker :disabled="!item.writable" v-model="item.value" ></jp-color-picker>
+				</template>	
+				<template v-if="item.type=='select'">
+					<!-- 选择框 -->
+					<jp-picker :disabled="!item.writable" v-if="item.options.remote === 3" v-model="item.value" :range="$dictUtils.getDictList(item.options.dictType)">
+					</jp-picker>
+					<jp-picker :disabled="!item.writable" v-else-if="item.options.showLabel" v-model="item.value" :range="item.options.options">
+					</jp-picker>
+					<jp-picker :disabled="!item.writable" v-else v-model="item.value" rangeKey="value" :range="item.options.options">
+					</jp-picker>
+				</template>	
+				<template v-if="item.type=='switch'">
+					<!-- 开关 -->
+					<u-switch :placeholder="item.placeholder" :disabled="!item.writable"   v-model="item.value"></u-switch>
+				</template>	
+				<template v-if="item.type=='cascader'">
+					<!-- 开关 -->
+					<uni-data-picker :localdata="item.options.options" v-model="item.value" :map="{text:'label', value: 'value'}" :popup-title="item.placeholder" ></uni-data-picker>
+				</template>	
+				<template v-if="item.type=='slider'">
+					<!-- 滑块 -->
+					<u-slider :placeholder='item.placeholder' :disabled="!item.writable" step="20" min="30" max="100"   v-model="item.value"></u-slider>
+				</template>	
+				<template v-if="item.type=='text'">
+					<!-- 普通输入框 -->
+					<text>{{item.value}}</text>
+				</template>	
+				<template v-if="item.type=='html'">
+					<!-- 普通输入框 -->
+					<view v-html="item.value"></view>
+				</template>	
+				<!--步骤条-->
+				<template v-if="item.type == 'steps'">
+					<u-steps :current="item.value">
+						<u-steps-item v-for="(item, index) in item.options.steps" :title="item.title"></u-steps-item>
+					</u-steps>
+				</template>
+				<template v-if="item.type=='imgupload' || item.type=='fileupload'">
+					<!-- 图片上传 -->
+					<jp-form-upload :disabled="!item.writable"   v-model="item.value"></jp-form-upload>
+				</template>	
+				<template v-if="item.type=='user'">
+					<!-- 用户选择框 -->
+					<user-select :placeholder='item.placeholder' :disabled="!item.writable"   v-model="item.value"></user-select>
+				</template>	
+				<template v-if="item.type=='office'">
+					<!-- 机构选择框 -->
+					<jp-office-select :placeholder='item.placeholder' :disabled="!item.writable"   v-model="item.value"></jp-office-select>
+				</template>	
+				<template v-if="item.type=='area'">
+					<!-- 普通输入框 -->
+					<jp-area-select  :disabled="!item.writable"  v-model="item.value"></jp-area-select>
+				</template>	
+				<template v-if="item.type=='dict'">
+					<!-- 字典 -->
+					<jp-picker :disabled="!item.writable"  v-model="item.value" :range="$dictUtils.getDictList(item.options.dictType)"></jp-picker>
+				</template>	
+			</u-form-item>							
+		</u--form>
+	</view>
+</template>
+
+<script>
+	export default {
+		watch:{
+			formData:{
+				handler (val) {
+					console.log(this.formData)
+				},
+				immediate: true,
+				deep: false
+			}
+		},
+		props: {
+			formData:{
+				type:Array,
+				default:function(){
+					return []
+				}
+			}
+		},
+		methods: {	
+
+		}
+	}
+</script>
+
+<style lang="scss">
+.uni-list-cell {
+    justify-content: flex-start
+}
+.cu-form-group{
+
+    uni-checkbox-group{
+		text-align: right;
+	}
+	uni-radio-group {
+		text-align: right;
+	}
+	uni-checkbox, uni-radio {
+	    position: relative;
+	    margin-top: 7px;
+		margin-left:7px;
+		margin-bottom: 7px;
+	}
+}
+</style>

+ 33 - 0
components/jp-area-select/jp-area-select.vue

@@ -0,0 +1,33 @@
+<template>
+
+    <uni-data-picker :localdata="treeList" v-model="labels" :map="{text:'name', value: 'name'}" popup-title="请选择区域" @change="onchange"></uni-data-picker>
+
+</template>
+
+<script>
+  import areaService from "@/api/sys/areaService"
+  export default {
+    props: {
+	  value: String
+	},
+    data() {
+      return {
+		  labels: '',
+		  treeList: []
+      }
+    },
+	mounted() {
+		areaService.treeData().then((data)=>{
+			this.treeList = data
+			this.labels = this.value
+		}).catch((e)=>{
+			 throw e
+		})
+	},
+    methods: {
+      onchange(e) {
+		this.$emit('input', this.labels)
+      }
+    }
+  }
+  </script>

+ 37 - 0
components/jp-checkbox-group/jp-checkbox-group.vue

@@ -0,0 +1,37 @@
+<template>
+	<u-checkbox-group v-model="ckList"  placement="column" @change="CheckboxChange">
+			<slot></slot>
+	</u-checkbox-group>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				ckList: []
+			}
+		},
+		props: {
+		    value: String,
+			disabled: {
+				type: Boolean,
+				default: false
+			}
+		},
+		watch:{
+			value:{
+				handler (val) {
+					this.ckList = val.split(',')	
+				},
+				immediate: true,
+				deep: false
+			}
+		}, 
+		methods:{
+			CheckboxChange(evt) {
+				this.$emit('input', this.ckList.join(','))
+			},
+		}
+	}
+</script>
+

+ 52 - 0
components/jp-color-picker/README.md

@@ -0,0 +1,52 @@
+支持初始化颜色、自适应容器大小方便自定义开发、返回hex、rgba/rgb两种颜色格式。
+
+## 属性/事件列表:
+
+| 属性/事件 | 必填 |  默认  |  功能  |
+| :-----:  | :-----:  | :-----:  | :-----  |
+| color  | 否 |  ''     | 初始化picker的颜色 |
+| show  | 否 |   true    | 控制picker显示隐藏 |
+| @pickerColor |   否   |   null   | 取色器发生取色动作触发,返回两种颜色格式:`{hex: '#ff0000', rgb: 'rgb(255, 0, 0)'}` |
+
+
+
+## Demo:
+
+```
+
+// 这里演示在uni-modal中显示color-picker,color-picker支持自适应容器
+<uni-modal>
+    <div class="uni-mask"></div>
+    <div class="uni-modal" style="padding: 20rpx;">
+    <color-picker :show='true' :color="color" @pickerColor="pickerColor"></color-picker>
+    <div class="actions">
+        <i class="iconfont icon-del"></i>
+        <i class="iconfont icon-yes"></i>
+    </div>
+    </div>
+</uni-modal>
+
+```
+
+```
+
+import colorPicker from "../../components/colorPicker";
+
+export default {
+  components: { colorPicker },
+  data() {
+    return {
+      color: '#123456f0'
+    };
+  },
+  methods: {
+    pickerColor(color) {
+      this.color = color.hex
+    }
+  }
+};
+
+```
+
+
+

+ 320 - 0
components/jp-color-picker/colorPicker.vue

@@ -0,0 +1,320 @@
+<template>
+    <div class="color-picker" v-if="show">
+      <div ref="slider" class="sv-picker" @touchstart="setSlider($event, 'sv')" @touchmove="moveSlide($event, 'sv')">
+        <div class="sv-picker-background" :style="{backgroundColor: svBackgroundColor}"></div>
+        <div class="sv-picker-background" :style="{background: 'linear-gradient(to right, white, #ffffff00)'}"></div>
+        <div class="sv-picker-background" :style="{background: 'linear-gradient(to top, black, #ffffff00)'}"></div>
+        <view class="sv-slider" :style="svSliderStyle" @touchstart="touchSlider($event, 'sv')" @touchmove="moveSlide($event, 'sv')"></view>
+      </div>
+      <div class="result">
+        <div class="result-color alpha-background-image">
+          <div class="alpha-background" :style="{background: pickedColor.rgb}"></div>
+        </div>
+        <div class="result-text">
+          <p>{{pickedColor.rgb}}</p>
+          <p>{{pickedColor.hex}}</p>
+        </div>
+      </div>
+      <div class="hue-slider" @touchstart="setSlider($event, 'hue')" @touchmove="moveSlide($event, 'hue')">
+        <view class="slider" :style="hueSliderStyle" @touchstart="touchSlider($event, 'hue')" @touchmove="moveSlide($event, 'hue')"></view>
+      </div>
+      <div class="alpha-slider alpha-background-image" @touchstart="setSlider($event, 'alpha')" @touchmove="moveSlide($event, 'alpha')">
+        <div class="alpha-background" :style="{background: alphaBackground}"></div>
+        <view class="slider" :style="alphaSliderStyle" @touchstart="touchSlider($event, 'alpha')" @touchmove="moveSlide($event, 'alpha')"></view>
+      </div>
+    </div>
+</template>
+
+<script>
+export default {
+  props: {
+    color: {
+      value: String,
+      default: ''
+    },
+    show: {
+      value: Boolean,
+      default: ''
+    },
+  },
+  data() {
+    return {
+      hueSlider: 0,
+      alphaSlider: 0,
+      saturationSlider: 0,
+      valueSlider: 0,
+      pickerWidth: 0,
+      pickerOffsetX: 0,
+      halfSilder: uni.getSystemInfoSync().windowWidth / 750 * 15,
+    }
+  },
+  mounted() {
+    const sliderInfo = this.$refs.slider.getBoundingClientRect()
+    
+    this.pickerWidth = sliderInfo.width
+    this.pickerOffsetX = sliderInfo.x
+    this.pickerOffsetY = sliderInfo.y
+
+    this.alphaSlider = sliderInfo.width
+    this.saturationSlider = sliderInfo.width
+  },
+  watch: {
+    color: {
+      handler() {
+        if (this.color && this.color !== this.pickedColor.hex) {
+          this.$nextTick(() => {
+            const {r,g,b,a} = hexToRgba(this.color)
+            const {h, s, v} = rgbToHsv(r, g, b)
+            this.hueSlider = h * this.pickerWidth
+            this.alphaSlider = a * this.pickerWidth
+            this.saturationSlider = s * this.pickerWidth
+            this.valueSlider = this.pickerWidth - v * this.pickerWidth
+          })
+        }
+      },
+      immediate: true
+    }
+  },
+  computed: {
+    pickedHueColor() {
+      const hue = this.hueSlider / this.pickerWidth
+      return hsvToRgb(hue, 1, 1)
+    },
+    pickedColor() {
+      if (!this.pickerWidth) {
+        return {r: 0, g: 0, b: 0, a: 0}
+      }
+      const hue = this.hueSlider / this.pickerWidth
+      const saturation = this.saturationSlider / this.pickerWidth
+      const value = (this.pickerWidth - this.valueSlider) / this.pickerWidth
+      const alpha = this.alphaSlider / this.pickerWidth
+      
+      const rgb = this.pickedHueColor
+      let color
+      if (alpha === 1) {
+        color = {...rgb, a: alpha, rgb: `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`, hex: rgbaToHex(rgb.r, rgb.g, rgb.b, 255)}
+      } else {
+        color = {...rgb, a: alpha, rgb: `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${Math.round(alpha * 100) / 100})`, hex: rgbaToHex(rgb.r, rgb.g, rgb.b, Math.round(alpha * 255))}
+      }
+
+      return color
+    },
+    svBackgroundColor() {
+      return `rgb(${this.pickedHueColor.r}, ${this.pickedHueColor.g}, ${this.pickedHueColor.b})`
+    },
+    alphaBackground() {
+      return `linear-gradient(to right, 
+      rgba(${this.pickedHueColor.r}, ${this.pickedHueColor.g}, ${this.pickedHueColor.b}, 0), 
+      rgba(${this.pickedHueColor.r}, ${this.pickedHueColor.g}, ${this.pickedHueColor.b}, 1))`
+    },
+    hueSliderStyle() {
+      return {transform: `translate(${this.hueSlider - this.halfSilder}px, -50%)`}
+    },
+    alphaSliderStyle() {
+      return {transform: `translate(${this.alphaSlider - this.halfSilder}px, -50%)`}
+    },
+    svSliderStyle() {
+      return {transform: `translate(${this.saturationSlider - this.halfSilder}px, ${this.valueSlider - this.halfSilder}px)`}
+    },
+  },
+  methods: {
+    touchSlider(e, component) {
+      if (component === 'sv') {
+        this.startLeft = this.saturationSlider
+        this.startPageX = e.touches[0].pageX
+        this.startTop = this.valueSlider
+        this.startPageY = e.touches[0].pageY
+      } else {
+        this.startLeft = this[component + 'Slider']
+        this.startPageX = e.touches[0].pageX
+      }
+    },
+    moveSlide(e, component) {
+      if (component === 'sv') {
+        this.setSliderValue('saturation', this.startLeft + e.touches[0].pageX - this.startPageX)
+        this.setSliderValue('value', this.startTop + e.touches[0].pageY - this.startPageY)
+      } else {
+        this.setSliderValue(component, this.startLeft + e.touches[0].pageX - this.startPageX)
+      }
+
+      this.emitPickedColor()
+    },
+    setSlider(e, component) {
+      if (component === 'sv') {
+        this.setSliderValue('saturation', e.touches[0].pageX - this.pickerOffsetX)
+        this.setSliderValue('value', e.touches[0].pageY - this.pickerOffsetY)
+      } else {
+        this.setSliderValue(component, e.touches[0].pageX - this.pickerOffsetX)
+      }
+      this.touchSlider(e, component)
+
+      this.emitPickedColor()
+    },
+    setSliderValue(component, value) {
+      this[component + 'Slider'] = Math.min(Math.max(value, 0), this.pickerWidth)
+    },
+    emitPickedColor() {
+      clearTimeout(this.emitTimer)
+      this.emitTimer = setTimeout(() => {
+        this.$emit('pickerColor', {rgb: this.pickedColor.rgb, hex: this.pickedColor.hex})
+      }, 100);
+    }
+  }
+}
+
+function hsvToRgb(h, s, v) {
+  var r, g, b, i, f, p, q, t;
+  if (arguments.length === 1) {
+      s = h.s, v = h.v, h = h.h;
+  }
+  i = Math.floor(h * 6);
+  f = h * 6 - i;
+  p = v * (1 - s);
+  q = v * (1 - f * s);
+  t = v * (1 - (1 - f) * s);
+  switch (i % 6) {
+      case 0: r = v, g = t, b = p; break;
+      case 1: r = q, g = v, b = p; break;
+      case 2: r = p, g = v, b = t; break;
+      case 3: r = p, g = q, b = v; break;
+      case 4: r = t, g = p, b = v; break;
+      case 5: r = v, g = p, b = q; break;
+  }
+  return {
+      r: Math.round(r * 255),
+      g: Math.round(g * 255),
+      b: Math.round(b * 255)
+  }
+}
+
+function rgbToHsv(r, g, b) {
+    if (arguments.length === 1) {
+        g = r.g, b = r.b, r = r.r;
+    }
+    var max = Math.max(r, g, b), min = Math.min(r, g, b),
+        d = max - min,
+        h,
+        s = (max === 0 ? 0 : d / max),
+        v = max / 255;
+    switch (max) {
+        case min: h = 0; break;
+        case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break;
+        case g: h = (b - r) + d * 2; h /= 6 * d; break;
+        case b: h = (r - g) + d * 4; h /= 6 * d; break;
+    }
+    return { h, s, v };
+}
+
+function rgbaToHex(r, g, b, a) {
+  let hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
+  if (a !== 255) {
+    hex += ((1 << 8) + a).toString(16).slice(1)
+  }
+  return hex
+}
+
+function hexToRgba(hex) {
+  // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
+  var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+  hex = hex.replace(shorthandRegex, function(m, r, g, b) {
+    return r + r + g + g + b + b;
+  });
+
+  var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(hex);
+  return result ? {
+    r: parseInt(result[1], 16),
+    g: parseInt(result[2], 16),
+    b: parseInt(result[3], 16),
+    a: result[4] ? parseInt(result[4], 16)  / 255 : 1,
+  } : null;
+}
+</script>
+
+<style lang="scss" scoped>
+.color-picker {
+  position: relative;
+  width: 100%;
+}
+.sv-picker {
+  position: relative;
+  width: 100%;
+  padding-top: 100%;
+  .sv-slider {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 30rpx;
+    height: 30rpx;
+    border: 1px solid #FFF;
+    background-color: rgba(73, 73, 73, 0.5);
+    border-radius: 50rpx;
+  }
+  
+  .sv-picker-background {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+  }
+}
+
+.hue-slider, .alpha-slider {
+  margin-top: 20rpx;
+  position: relative;
+  width: 100%;
+  height: 35rpx;
+}
+.hue-slider {
+  background: linear-gradient(90deg, red 0, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, red);
+}
+.alpha-background-image {
+  background-size: 35rpx;
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAWElEQVRIiWM8fubkfwYygKWJOSM5+mCAhRLNoxaPWjxq8ajFoxbTyeL/DAfJ0Xjs3Cl7Siwmu4Yht1aDgZEYx6MWj1o8avGoxaMWD3qLya5X//4nqx6HAQC7RBGFzolqTAAAAABJRU5ErkJggg==");
+}
+
+.slider {
+  position: absolute;
+  left: 0;
+  top: 50%;
+  transform: translateY(-50%);
+  height: 50rpx;
+  width: 30rpx;
+  border: 1px solid #FFF;
+  box-sizing: border-box;
+  background-color: rgba(199, 199, 199, .7);
+}
+.alpha-background {
+  width: 100%;
+  height: 100%;
+}
+
+.result {
+  margin-top: 20rpx;
+  display: flex;
+  align-items: center;
+
+  .result-color {
+    width: 100rpx;
+    height: 100rpx;
+    border-radius: 100rpx;
+    overflow: hidden;
+  }
+  .result-text {
+    margin-left: 20rpx;
+    flex: 1;
+    padding: 10rpx 20rpx;
+    border: 1px solid #CCC;
+    border-radius: 10rpx;
+    color: #333;
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+
+    p {
+      width: 100%;
+    }
+  }
+}
+
+</style>

+ 86 - 0
components/jp-color-picker/jp-color-picker.vue

@@ -0,0 +1,86 @@
+<template>
+<view>
+<view class="action">
+	<button class="cu-btn  shadow round" :disabled="disabled" :style="'color:white;background-color:'+color" @tap="showModal" data-target="DialogModal1">{{color}}</button>
+</view>
+ <view class="cu-modal" :class="modalName=='DialogModal1'?'show':''">
+ 	<view class="cu-dialog">
+ 		<view class="padding-xl">
+ 			 <color-picker :show='true' :color="color" @pickerColor="pickerColor"></color-picker>
+ 		</view>
+ 		<view class="cu-bar bg-white justify-end">
+ 			<view class="action">
+ 				<button class="cu-btn line-green text-green" @tap="hideModal">取消</button>
+ 				<button class="cu-btn bg-green margin-left" @tap="confirm">确定</button>
+ 
+ 			</view>
+ 		</view>
+ 	</view>
+ </view>
+ </view>
+</template>
+<script>
+import colorPicker from "./colorPicker.vue";
+
+export default {
+  components: { colorPicker },
+  props: {
+    value: String,
+  	disabled: {
+  		type: Boolean,
+  		default: false
+  	}
+  },
+  data() {
+    return {
+	  modalName: null,
+	  color: null,
+	  colorRgb: ''
+    };
+  },
+  watch:{
+  	value:{
+  		handler (val) {
+  			this.color = val
+  		},
+  		immediate: true,
+  		deep: false
+  	}
+  },
+  methods: {
+    pickerColor(color) {
+      this.color = color.rgb
+    },
+	showModal(e) {
+		this.modalName = e.currentTarget.dataset.target
+	},
+	hideModal(e) {
+		this.modalName = null
+	},
+	confirm () {
+		this.$emit('input', this.color)
+		this.modalName = null
+	}
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+#container {
+  width: 100vw;
+  height: 100vh;
+}
+.actions {
+  margin-top: 20rpx;
+  display: flex;
+  justify-content: space-between;
+  .iconfont {
+    color: #777;
+    font-size: 56rpx;
+  }
+  .icon-yes {
+    color: rgb(14, 165, 0)
+  }
+}
+
+</style>

+ 88 - 0
components/jp-datetime-picker/jp-datetime-picker.vue

@@ -0,0 +1,88 @@
+<template>
+		<view style="width: 100%;"
+			@tap="show=true"
+			:disabled="disabled"
+		>
+			<u-datetime-picker
+			        :show="show"
+			        v-model="value1"
+			        :mode="mode"
+					@cancel="show=false"
+					@confirm="TimeChange"
+			></u-datetime-picker>
+			<u--input
+				v-model="label"
+				suffixIcon="arrow-right"
+				suffixIconStyle="color: #909399"
+				disabled
+				disabledColor="#ffffff"
+				:placeholder="placeholder"
+				border="none"
+			></u--input>
+		</view>
+		       
+</template>
+
+<script>
+	import moment from 'moment'
+	export default {
+		data () {
+			return {
+				show: false,
+				value1: '',
+				label: ''
+			}
+		},
+		props: {
+		    value: {
+				type: String,
+				default: null
+			},
+			mode: String,
+			placeholder: String,
+			disabled: {
+				type: Boolean,
+				default: false
+			}
+		},
+		watch:{
+			value:{
+				handler (val) {
+					if(val === 0) {
+						this.label = ''
+						return
+					}
+					const timeFormat = uni.$u.timeFormat
+					if(this.mode === 'date') {
+						this.label = val
+						this.value1 = Number(val);
+					}else if(this.mode === 'time'){
+						this.label = val
+						this.value1 = val;
+					}else if(this.mode === 'datetime'){
+						this.label = val
+						this.value1 = Number(val)
+					}
+					
+				},
+				immediate: true,
+				deep: false
+			}
+		},
+		methods:{
+			TimeChange(e) {
+				const timeFormat = uni.$u.timeFormat
+				if(this.mode === 'date') {
+					this.label = timeFormat(e.value, 'yyyy-mm-dd')
+				}else if(this.mode === 'time'){
+					this.label = e.value
+				}else if(this.mode === 'datetime'){
+					this.label = timeFormat(e.value, 'yyyy-mm-dd hh:MM:ss')
+				}
+				this.$emit('input', this.label)
+				this.show = false
+			}
+		}
+	}
+</script>
+

+ 104 - 0
components/jp-form-upload/jp-form-upload.vue

@@ -0,0 +1,104 @@
+<template>
+		<view class="margin-top grid col-4 grid-square flex-sub">
+			<view class="bg-img"  v-for="(item,index) in imgList" :key="index" @tap="ViewImage" :data-url="item.url">
+				<view class="cu-avatar lg margin-left-sm"  v-if="!disabled" @tap.stop="DelImg" :data-index="index" :style="`background-image:url('${item.url}')`" >
+					<text class='cuIcon-close'></text>
+				</view>
+			</view>
+			<view class="solids" v-if="!disabled" @tap="ChooseImage">
+				<text class='cuIcon-cameraadd'></text>
+			</view>
+		</view>
+</template>
+
+<script>
+	import fileService from "@/api/file/fileService"
+	export default {
+		data() {
+			return {
+				imgList: []
+			}
+		},
+		props: {
+		    value: {
+				type: Array,
+				default: function () {
+					return []
+				}
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			}
+		},
+		watch:{
+			value:{
+				handler (val) {
+					this.imgList = val
+				},
+				immediate: true,
+				deep: false
+			}
+		}, 
+		methods: {
+			ChooseImage() {
+				uni.chooseImage({
+					count: 4, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择
+					success: (res) => {
+						this.upload(res.tempFilePaths[0])
+					}
+				});
+			},
+			ViewImage(e) {
+				let urls = this.imgList.map((img)=>{
+					return img.url
+				})
+				uni.previewImage({
+					urls: urls,
+					current: e.currentTarget.dataset.url
+				});
+			},
+			DelImg(e) {
+				uni.showModal({
+					title: '提示',
+					content: '确定要删除图片吗?',
+					cancelText: '取消',
+					confirmText: '确定',
+					success: res => {
+						if (res.confirm) {
+							this.imgList.splice(e.currentTarget.dataset.index, 1)
+							this.$emit('input', this.imgList)
+						}
+					}
+				})
+			},
+			upload(img) {
+				fileService.upload(img).then((res)=>{
+					this.imgList.push({url:res, keys:''})
+					this.$emit('input',this.imgList)
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+  .btn-logout {
+    margin-top: 100upx;
+    width: 80%;
+    border-radius: 50upx;
+    font-size: 16px;
+    color: #fff;
+    background: linear-gradient(to right, #365fff, #36bbff);
+  }
+
+  .btn-logout-hover {
+    background: linear-gradient(to right, #365fdd, #36bbfa);
+  }
+  uni-image>div, uni-image>img {
+      width: 100upx !important;
+      height: 100upx !important;
+  }
+</style>

+ 106 - 0
components/jp-image-upload/jp-image-upload.vue

@@ -0,0 +1,106 @@
+<template>
+		<view class="margin-top grid col-4 grid-square flex-sub">
+			<view class="bg-img"  v-for="(item,index) in imgList" :key="index" @tap="ViewImage" :data-url="item">
+				<view class="cu-avatar lg margin-left-sm"  v-if="!disabled" @tap.stop="DelImg" :data-index="index" :style="`background-image:url('${item}')`" >
+					<text class='cuIcon-close'></text>
+				</view>
+			</view>
+			<view class="solids" v-if="!disabled" @tap="ChooseImage">
+				<text class='cuIcon-cameraadd'></text>
+			</view>
+		</view>
+</template>
+
+<script>
+	import fileService from "@/api/file/fileService"
+	export default {
+		data() {
+			return {
+				imgList: []
+			}
+		},
+		watch:{
+			value:{
+				handler (val) {
+					if(val){
+						this.imgList = val.split(',')
+					}
+				},
+				immediate: true,
+				deep: false
+			}
+		},
+		props: {
+		    value: {
+				type: String,
+				default: function () {
+					return ''
+				}
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			}
+		},
+		methods: {
+			ChooseImage() {
+				uni.chooseImage({
+					count: 4, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择
+					success: (res) => {
+						this.upload(res.tempFilePaths[0])
+					}
+				});
+			},
+			ViewImage(e) {
+				let urls = this.imgList.map((img)=>{
+					return img.url
+				})
+				uni.previewImage({
+					urls: urls,
+					current: e.currentTarget.dataset.url
+				});
+			},
+			DelImg(e) {
+				uni.showModal({
+					title: '提示',
+					content: '确定要删除图片吗?',
+					cancelText: '取消',
+					confirmText: '确定',
+					success: res => {
+						if (res.confirm) {
+							this.imgList.splice(e.currentTarget.dataset.index, 1)
+							this.$emit('input', this.imgList.join(','))
+						}
+					}
+				})
+			},
+			upload(img) {
+				fileService.upload(img).then((res)=>{
+					this.imgList.push(res)
+					this.$emit('input', this.imgList.join(','))
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+  .btn-logout {
+    margin-top: 100upx;
+    width: 80%;
+    border-radius: 50upx;
+    font-size: 16px;
+    color: #fff;
+    background: linear-gradient(to right, #365fff, #36bbff);
+  }
+
+  .btn-logout-hover {
+    background: linear-gradient(to right, #365fdd, #36bbfa);
+  }
+  uni-image>div, uni-image>img {
+      width: 100upx !important;
+      height: 100upx !important;
+  }
+</style>

+ 127 - 0
components/jp-office-select/jp-office-select.vue

@@ -0,0 +1,127 @@
+<template>
+	<view style="width: 100%;"
+		@tap="open"
+	>
+		<u--input
+			v-model="labels"
+			suffixIcon="arrow-right"
+			suffixIconStyle="color: #909399"
+			disabled
+			disabledColor="#ffffff"
+			:placeholder="placeholder"
+			border="none"
+		></u--input>
+	
+		<u-action-sheet
+			:show="show"
+			@close="show = false"
+		>
+		<view class="cu-bar bg-white">
+			<view class="action text-blue" @tap="show=false">取消</view>
+			<view class="action text-green" @tap="selectOffice">确定</view>
+		</view>
+		<view>
+		  <ly-tree :tree-data="data"
+			:props="props" 
+			node-key="id" 
+			:checkOnClickNode ="true"
+			:showRadio="true"
+			:show-checkbox ="false"
+			:checkOnlyLeaf = "false"
+			ref="officeTree" />
+		</view>
+		</u-action-sheet>
+	</view>
+</template>
+
+<script>
+	import officeService from "@/api/sys/officeService"
+	export default {
+		data() {
+			return {
+				labels: '',
+				show: false,
+				data: [],
+				treeList: []
+			};
+		},
+		props: {
+		    limit: Number,
+		    value: String,
+		    size: String,
+			placeholder: String,
+		    readonly: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			checkOnlyLeaf: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			showRadio: {
+		      type: Boolean,
+		      default: () => { return true }
+		    },
+			showCheckBox: {
+			  type: Boolean,
+			  default: () => { return false }
+			},
+		    disabled: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			props: {
+				type: Object,
+				default: () => {
+					return {
+						children: 'children',
+						label: 'name'
+					}
+				}
+			}
+		  },
+		mounted() {
+			officeService.treeData().then((data)=>{
+				this.data = data
+				this.setTreeList(this.data)
+				if(this.value){
+					this.treeList.forEach((node) => {
+					  if (this.value === node.id) {
+						this.labels = node.name
+					  }
+					})
+				}
+			})
+		},
+		methods:{
+			open () {
+				this.show = true;
+				if(this.value){
+					this.$nextTick(()=>{
+						this.$refs.officeTree.setCheckedKeys( this.value.split(','));
+					})
+				}
+			},
+			setTreeList (datas) { // 遍历树  获取id数组
+			      for (var i in datas) {
+			        this.treeList.push(datas[i])
+			        if (datas[i].children) {
+			          this.setTreeList(datas[i].children)
+			        }
+			      }
+			},
+			selectOffice () {
+				let ids = this.$refs.officeTree.getCheckedNodes().map((item)=>{
+					return item.id
+				}).join(",");
+				let names = this.$refs.officeTree.getCheckedNodes().map((item)=>{
+					return item.name
+				}).join(",");
+				this.labels = names
+				this.$emit('input', ids)
+				this.show = false
+			}
+		}
+	}
+</script>
+

+ 84 - 0
components/jp-picker/jp-picker.vue

@@ -0,0 +1,84 @@
+<template>
+	<view style="width: 100%;">
+		<picker style="width: 100%;" @change="PickerChange" :value="index" :disabled="disabled" :range-value="rangeValue"  :range-key="rangeKey" :range="range">
+		<u--input
+			v-model="label"
+			suffixIcon="arrow-right"
+			suffixIconStyle="color: #909399"
+			disabled
+			disabledColor="#ffffff"
+			placeholder="请选择"
+			border="none"
+		></u--input>
+		</picker>
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				index: -1,
+				label: '请选择'
+			};
+		},
+		props: {
+		    value: String,
+			rangeKey: {
+				type: String,
+				default: 'label'
+			},
+			rangeValue: {
+				type: String,
+				default: 'value'
+			},
+			range: {
+				type: Array,
+				default: []
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			}
+		},
+		mounted() {
+			
+		},
+		watch:{
+			value: {
+				handler (val) {
+					if(val) {
+						let options = this.range.filter((option)=>{
+							return option.value === val
+						})
+						if(options.length === 0){
+							this.label = '请选择'
+						} else {
+							this.label = options[0][this.rangeKey]
+						}
+					}
+				},
+				immediate: true,
+				deep: false
+			}
+		},
+		methods:{
+			PickerChange(e) {
+				this.index = e.detail.value;
+				if(this.index !== -1){
+					this.label = this.range[this.index][this.rangeKey]
+					this.$emit('input', this.range[this.index][this.rangeValue])
+				}else{
+					this.label = '请选择'
+					this.$emit('input', null)
+				}
+				
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 31 - 0
components/jp-slider/jp-slider.vue

@@ -0,0 +1,31 @@
+<template>
+	 <view class="uni-padding-wrap uni-common-mt">
+		 <slider value="0" :disabled="disabled" @change="sliderChange" step="5" />
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				valueStr: ''+this.value
+			};
+		},
+		props: {
+		    value: Number,
+			disabled: {
+				type: Boolean,
+				default: false
+			}
+		},
+		methods:{
+			 sliderChange(e) {
+				this.$emit('input', e.detail.value)
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 200 - 0
components/ly-tree/components/ly-checkbox.vue

@@ -0,0 +1,200 @@
+<template>
+	<text :class="classObj.wrapper" @click.stop="handleClick">
+		<text :class="[classObj.input, {'is-indeterminate': indeterminate, 'is-checked': checked, 'is-disabled': disabled}]">
+			<text :class="classObj.inner"></text>
+		</text>
+	</text>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				classObj: {}
+			}
+		},
+		
+		props: {
+			type: {
+				type: String,
+				validator(t) {
+					return t === 'radio' || t === 'checkbox'
+				}
+			},
+			checked: Boolean,
+			disabled: Boolean,
+			indeterminate: Boolean
+		},
+		
+		created() {
+			this.classObj = {
+				wrapper: `ly-${this.type}`,
+				input: `ly-${this.type}__input`,
+				inner: `ly-${this.type}__inner`
+			}
+		},
+		
+		methods: {
+			handleClick() {
+				this.$emit('check', this.checked);
+			}
+		}
+	}
+</script>
+
+<style>
+	/* lyRadio/lyCheckbox-start */
+	.ly-checkbox,
+	.ly-radio {
+		color: #606266;
+		font-weight: 500;
+		font-size: 28rpx;
+		cursor: pointer;
+		user-select: none;
+		padding-right: 16rpx
+	}
+	
+	.ly-checkbox__input,
+	.ly-radio__input {
+		cursor: pointer;
+		outline: 0;
+		line-height: 1;
+		vertical-align: middle
+	}
+	
+	.ly-checkbox__input.is-disabled .ly-checkbox__inner,
+	.ly-radio__input.is-disabled .ly-radio__inner {
+		background-color: #edf2fc;
+		border-color: #DCDFE6;
+		cursor: not-allowed
+	}
+	
+	.ly-checkbox__input.is-disabled .ly-checkbox__inner::after,
+	.ly-radio__input.is-disabled .ly-radio__inner::after {
+		cursor: not-allowed;
+		border-color: #C0C4CC
+	}
+	
+	.ly-checkbox__input.is-disabled .ly-checkbox__inner+.ly-checkbox__label,
+	.ly-radio__input.is-disabled .ly-radio__inner+.ly-radio__label {
+		cursor: not-allowed
+	}
+	
+	.ly-checkbox__input.is-disabled.is-checked .ly-checkbox__inner,
+	.ly-radio__input.is-disabled.is-checked .ly-radio__inner {
+		background-color: #F2F6FC;
+		border-color: #DCDFE6
+	}
+	
+	.ly-checkbox__input.is-disabled.is-checked .ly-checkbox__inner::after,
+	.ly-radio__input.is-disabled.is-checked .ly-radio__inner::after {
+		border-color: #C0C4CC
+	}
+	
+	.ly-checkbox__input.is-disabled.is-indeterminate .ly-checkbox__inner {
+		background-color: #F2F6FC;
+		border-color: #DCDFE6
+	}
+	
+	.ly-checkbox__input.is-disabled.is-indeterminate .ly-checkbox__inner::before {
+		background-color: #C0C4CC;
+		border-color: #C0C4CC
+	}
+	
+	.ly-checkbox__input.is-checked .ly-checkbox__inner,
+	.ly-radio__input.is-checked .ly-radio__inner,
+	.ly-checkbox__input.is-indeterminate .ly-checkbox__inner {
+		background-color: #409EFF;
+		border-color: #409EFF
+	}
+	
+	.ly-checkbox__input.is-disabled+text.ly-checkbox__label,
+	.ly-radio__input.is-disabled+text.ly-radio__label {
+		color: #C0C4CC;
+		cursor: not-allowed
+	}
+	
+	.ly-checkbox__input.is-checked .ly-checkbox__inner::after,
+	.ly-radio__input.is-checked .ly-radio__inner::after {
+		-webkit-transform: rotate(45deg) scaleY(1);
+		transform: rotate(45deg) scaleY(1)
+	}
+	
+	.ly-checkbox__input.is-checked+.ly-checkbox__label,
+	.ly-radio__input.is-checked+.ly-radio__label {
+		color: #409EFF
+	}
+	
+	.ly-checkbox__input.is-focus .ly-checkbox__inner,
+	.ly-radio__input.is-focus .ly-radio__inner {
+		border-color: #409EFF
+	}
+	
+	.ly-checkbox__input.is-indeterminate .ly-checkbox__inner::before {
+		content: '';
+		position: absolute;
+		display: block;
+		background-color: #FFF;
+		height: 6rpx;
+		-webkit-transform: scale(.5);
+		transform: scale(.5);
+		left: 0;
+		right: 0;
+		top: 10rpx
+	}
+	
+	.ly-checkbox__input.is-indeterminate .ly-checkbox__inner::after {
+		display: none
+	}
+	
+	.ly-checkbox__inner,
+	.ly-radio__inner {
+		display: inline-block;
+		position: relative;
+		border: 2rpx solid #DCDFE6;
+		border-radius: 4rpx;
+		-webkit-box-sizing: border-box;
+		box-sizing: border-box;
+		width: 28rpx;
+		height: 28rpx;
+		background-color: #FFF;
+		z-index: 1;
+		-webkit-transition: border-color .25s cubic-bezier(.71, -.46, .29, 1.46), background-color .25s cubic-bezier(.71, -.46, .29, 1.46);
+		transition: border-color .25s cubic-bezier(.71, -.46, .29, 1.46), background-color .25s cubic-bezier(.71, -.46, .29, 1.46)
+	}
+	
+	.ly-radio__inner {
+		border-radius: 50%;
+		width: 34rpx !important;
+		height: 34rpx !important;
+	}
+	
+	.ly-checkbox__inner::after,
+	.ly-radio__inner::after {
+		-webkit-box-sizing: content-box;
+		box-sizing: content-box;
+		content: "";
+		border: 2rpx solid #FFF;
+		border-left: 0;
+		border-top: 0;
+		height: 14rpx;
+		left: 10rpx;
+		position: absolute;
+		top: 2rpx;
+		-webkit-transform: rotate(45deg) scaleY(0);
+		transform: rotate(45deg) scaleY(0);
+		width: 6rpx;
+		-webkit-transition: -webkit-transform .15s ease-in .05s;
+		transition: -webkit-transform .15s ease-in .05s;
+		transition: transform .15s ease-in .05s;
+		transition: transform .15s ease-in .05s, -webkit-transform .15s ease-in .05s;
+		-webkit-transform-origin: center;
+		transform-origin: center
+	}
+	
+	.ly-radio__inner::after {
+		left: 12rpx !important;
+		top: 6rpx !important;
+	}
+	/* lyRadio/lyCheckbox-end */
+</style>

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 382 - 0
components/ly-tree/ly-tree-node.vue


+ 588 - 0
components/ly-tree/ly-tree.vue

@@ -0,0 +1,588 @@
+<template>
+	<view>
+		<template v-if="showLoading">
+			<view class="ly-loader ly-flex-center">
+				<view class="ly-loader-inner">加载中...</view>
+			</view>
+		</template>
+		<template v-else>
+			<view v-if="isEmpty || !visible" class="ly-empty">{{emptyText}}</view>
+				<view class="ly-tree" :class="{'is-empty': isEmpty || !visible}" role="tree" name="LyTreeExpand">
+					<ly-tree-node v-for="nodeId in childNodesId" 
+						:nodeId="nodeId" 
+						:render-after-expand="renderAfterExpand"
+						:show-checkbox="showCheckbox" 
+						:show-radio="showRadio" 
+						:check-only-leaf="checkOnlyLeaf"
+						:key="getNodeKey(nodeId)" 
+						:indent="indent" 
+						:icon-class="iconClass">
+					</ly-tree-node>
+				</view>
+		</template>
+	</view>
+</template>
+
+<script>
+	import Vue from 'vue'
+	import TreeStore from './model/tree-store.js';
+	import {getNodeKey} from './tool/util.js';
+	import LyTreeNode from './ly-tree-node.vue';
+
+	export default {
+		name: 'LyTree',
+		
+		componentName: 'LyTree',
+		
+		components: {
+			LyTreeNode
+		},
+		
+		data() {
+			return {
+				elId: `ly_${Math.ceil(Math.random() * 10e5).toString(36)}`,
+				visible: true,
+				store: {
+					ready: false
+				},
+				currentNode: null,
+				childNodesId: []
+			};
+		},
+		
+		provide() {
+		    return {
+		       tree: this
+		    }
+		},
+		
+		props: {
+			// 展示数据
+			treeData: Array,
+			
+			// 自主控制loading加载,避免数据还没获取到的空档出现“暂无数据”字样
+			ready: {
+				type: Boolean,
+				default: true
+			},
+			
+			// 内容为空的时候展示的文本
+			emptyText: {
+				type: String,
+				default: '暂无数据'
+			},
+			
+			// 是否在第一次展开某个树节点后才渲染其子节点
+			renderAfterExpand: {
+				type: Boolean,
+				default: true
+			},
+			
+			// 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
+			nodeKey: String,
+			
+			// 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false
+			checkStrictly: Boolean,
+			
+			// 是否默认展开所有节点
+			defaultExpandAll: Boolean,
+			
+			// 切换全部展开、全部折叠
+			toggleExpendAll: Boolean,
+			
+			// 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点
+			expandOnClickNode: {
+				type: Boolean,
+				default: true
+			},
+			
+			// 选中的时候展开节点
+			expandOnCheckNode: {
+				type: Boolean,
+				default: true
+			},
+			
+			// 是否在点击节点的时候选中节点,默认值为 false,即只有在点击复选框时才会选中节点
+			checkOnClickNode: Boolean,
+			checkDescendants: {
+				type: Boolean,
+				default: false
+			},
+			
+			// 展开子节点的时候是否自动展开父节点
+			autoExpandParent: {
+				type: Boolean,
+				default: true
+			},
+			
+			// 默认勾选的节点的 key 的数组
+			defaultCheckedKeys: Array,
+			
+			// 默认展开的节点的 key 的数组
+			defaultExpandedKeys: Array,
+			
+			// 是否展开当前节点的父节点
+			expandCurrentNodeParent: Boolean,
+			
+			// 当前选中的节点
+			currentNodeKey: [String, Number],
+			
+			// 是否最后一层叶子节点才显示单选/多选框
+			checkOnlyLeaf: {
+				type: Boolean,
+				default: false
+			},
+			
+			// 节点是否可被选择
+			showCheckbox: {
+				type: Boolean,
+				default: false
+			},
+			
+			// 节点单选
+			showRadio: {
+				type: Boolean,
+				default: false
+			},
+			
+			// 配置选项
+			props: {
+				type: [Object, Function],
+				default () {
+					return {
+						children: 'children', // 指定子树为节点对象的某个属性值
+						label: 'label', // 指定节点标签为节点对象的某个属性值
+						disabled: 'disabled' //	指定节点选择框是否禁用为节点对象的某个属性值
+					};
+				}
+			},
+			
+			// 是否懒加载子节点,需与 load 方法结合使用
+			lazy: {
+				type: Boolean,
+				default: false
+			},
+			
+			// 是否高亮当前选中节点,默认值是 false
+			highlightCurrent: Boolean,
+			
+			// 加载子树数据的方法,仅当 lazy 属性为true 时生效
+			load: Function,
+			
+			// 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏
+			filterNodeMethod: Function,
+			
+			// 搜索时是否展示匹配项的所有子节点
+			childVisibleForFilterNode: {
+				type: Boolean,
+				default: false
+			},
+			
+			// 是否每次只打开一个同级树节点展开
+			accordion: Boolean,
+			
+			// 相邻级节点间的水平缩进,单位为像素
+			indent: {
+				type: Number,
+				default: 18
+			},
+			
+			// 自定义树节点的展开图标
+			iconClass: String,
+			
+			// 是否显示节点图标,如果配置为true,需要配置props中对应的图标属性名称
+			showNodeIcon: {
+				type: Boolean,
+				default: false
+			},
+			
+			// 如果数据量较大,建议不要在node节点中添加parent属性,会造成性能损耗
+			isInjectParentInNode: {
+				type: Boolean,
+				default: false
+			}
+		},
+		
+		computed: {
+			isEmpty() {
+				if (this.store.root) {
+					const childNodes = this.store.root.getChildNodes(this.childNodesId);
+					
+					return !childNodes || childNodes.length === 0 || childNodes.every(({visible}) => !visible);
+				}
+				
+				return true;
+			},
+			showLoading() {
+				return !(this.store.ready && this.ready);
+			}
+		},
+		
+		watch: {
+			toggleExpendAll(newVal) {
+				this.store.toggleExpendAll(newVal);
+			},
+			defaultCheckedKeys(newVal) {
+				this.store.setDefaultCheckedKey(newVal);
+			},
+			defaultExpandedKeys(newVal) {
+				this.store.defaultExpandedKeys = newVal;
+				this.store.setDefaultExpandedKeys(newVal);
+			},
+			treeData(newVal) {
+				this.store.setData(newVal);
+			},
+			checkStrictly(newVal) {
+				this.store.checkStrictly = newVal || this.checkOnlyLeaf;
+			},
+			'store.root.childNodesId'(newVal) {
+				this.childNodesId = newVal;
+			},
+			'store.root.visible'(newVal) {
+				this.visible = newVal;
+			},
+			childNodesId(){
+				this.$nextTick(() => {
+					this.$emit('ly-tree-render-completed');
+				});
+			}
+		},
+		
+		methods: {
+			/*
+			 * @description 对树节点进行筛选操作
+			 * @method filter
+			 * @param {all} value 在 filter-node-method 中作为第一个参数
+			 * @param {Object} data 搜索指定节点的节点数据,不传代表搜索所有节点,假如要搜索A节点下面的数据,那么nodeData代表treeData中A节点的数据
+			*/
+			filter(value, data) {
+				if (!this.filterNodeMethod) throw new Error('[Tree] filterNodeMethod is required when filter');
+				this.store.filter(value, data);
+			},
+			
+			/*
+			 * @description 获取节点的唯一标识符
+			 * @method getNodeKey
+			 * @param {String, Number} nodeId
+			 * @return {String, Number} 匹配到的数据中的某一项数据
+			*/
+			getNodeKey(nodeId) {
+				let node = this.store.root.getChildNodes([nodeId])[0];
+				return getNodeKey(this.nodeKey, node.data);
+			},
+			
+		   /*
+		    * @description 获取节点路径
+		    * @method getNodePath
+		    * @param {Object} data 节点数据
+		    * @return {Array} 路径数组
+		   */
+			getNodePath(data) {
+				return this.store.getNodePath(data);
+			},
+			
+			/*
+			 * @description 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点所组成的数组
+			 * @method getCheckedNodes
+			 * @param {Boolean} leafOnly 是否只是叶子节点,默认false
+			 * @param {Boolean} includeHalfChecked 是否包含半选节点,默认false
+			 * @return {Array} 目前被选中的节点所组成的数组
+			*/
+			getCheckedNodes(leafOnly, includeHalfChecked) {
+				return this.store.getCheckedNodes(leafOnly, includeHalfChecked);
+			},
+			
+			/*
+			 * @description 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组
+			 * @method getCheckedKeys
+			 * @param {Boolean} leafOnly 是否只是叶子节点,默认false,若为 true 则仅返回被选中的叶子节点的 keys
+			 * @param {Boolean} includeHalfChecked 是否返回indeterminate为true的节点,默认false
+			 * @return {Array} 目前被选中的节点所组成的数组
+			*/
+			getCheckedKeys(leafOnly, includeHalfChecked) {
+				return this.store.getCheckedKeys(leafOnly, includeHalfChecked);
+			},
+			
+			/*
+			 * @description 获取当前被选中节点的 data,若没有节点被选中则返回 null
+			 * @method getCurrentNode
+			 * @return {Object} 当前被选中节点的 data,若没有节点被选中则返回 null
+			*/
+			getCurrentNode() {
+				const currentNode = this.store.getCurrentNode();
+				return currentNode ? currentNode.data : null;
+			},
+			
+			/*
+			 * @description 获取当前被选中节点的 key,若没有节点被选中则返回 null
+			 * @method getCurrentKey
+			 * @return {all} 当前被选中节点的 key, 若没有节点被选中则返回 null
+			*/
+			getCurrentKey() {
+				const currentNode = this.getCurrentNode();
+				return currentNode ? currentNode[this.nodeKey] : null;
+			},
+			
+			/*
+			 * @description 设置全选/取消全选
+			 * @method setCheckAll
+			 * @param {Boolean} isCheckAll 选中状态,默认为true
+			*/
+			setCheckAll(isCheckAll = true) {
+				if (this.showRadio) throw new Error('You set the "show-radio" property, so you cannot select all nodes');
+				
+				if (!this.showCheckbox) console.warn('You have not set the property "show-checkbox". Please check your settings');
+				
+				this.store.setCheckAll(isCheckAll);
+			},
+			
+			/*
+			 * @description 设置目前勾选的节点
+			 * @method setCheckedNodes
+			 * @param {Array} nodes 接收勾选节点数据的数组
+			 * @param {Boolean} leafOnly 是否只是叶子节点, 若为 true 则仅设置叶子节点的选中状态,默认值为 false
+			*/
+			setCheckedNodes(nodes, leafOnly) {
+				this.store.setCheckedNodes(nodes, leafOnly);
+			},
+			
+			/*
+			 * @description 通过 keys 设置目前勾选的节点
+			 * @method setCheckedKeys
+			 * @param {Array} keys 勾选节点的 key 的数组 
+			 * @param {Boolean} leafOnly 是否只是叶子节点, 若为 true 则仅设置叶子节点的选中状态,默认值为 false
+			*/
+			setCheckedKeys(keys, leafOnly) {
+				if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in setCheckedKeys');
+				this.store.setCheckedKeys(keys, leafOnly);
+			},
+			
+			/*
+			 * @description 通过 key / data 设置某个节点的勾选状态
+			 * @method setChecked
+			 * @param {all} data 勾选节点的 key 或者 data 
+			 * @param {Boolean} checked 节点是否选中
+			 * @param {Boolean} deep 是否设置子节点 ,默认为 false
+			*/
+			setChecked(data, checked, deep) {
+				this.store.setChecked(data, checked, deep);
+			},
+			
+			/*
+			 * @description 若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点所组成的数组
+			 * @method getHalfCheckedNodes
+			 * @return {Array} 目前半选中的节点所组成的数组
+			*/
+			getHalfCheckedNodes() {
+				return this.store.getHalfCheckedNodes();
+			},
+			
+			/*
+			 * @description 若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点的 key 所组成的数组
+			 * @method getHalfCheckedKeys
+			 * @return {Array} 目前半选中的节点的 key 所组成的数组
+			*/
+			getHalfCheckedKeys() {
+				return this.store.getHalfCheckedKeys();
+			},
+			
+			/*
+			 * @description 通过 node 设置某个节点的当前选中状态
+			 * @method setCurrentNode
+			 * @param {Object} node 待被选节点的 node
+			*/
+			setCurrentNode(node) {
+				if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in setCurrentNode');
+				this.store.setUserCurrentNode(node);
+			},
+			
+			/*
+			 * @description 通过 key 设置某个节点的当前选中状态
+			 * @method setCurrentKey
+			 * @param {all} key 待被选节点的 key,若为 null 则取消当前高亮的节点
+			*/
+			setCurrentKey(key) {
+				if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in setCurrentKey');
+				this.store.setCurrentNodeKey(key);
+			},
+			
+			/*
+			 * @description 根据 data 或者 key 拿到 Tree 组件中的 node
+			 * @method getNode
+			 * @param {all} data 要获得 node 的 key 或者 data
+			*/
+			getNode(data) {
+				return this.store.getNode(data);
+			},
+			
+			/*
+			 * @description 删除 Tree 中的一个节点
+			 * @method remove
+			 * @param {all} data 要删除的节点的 data 或者 node
+			*/
+			remove(data) {
+				this.store.remove(data);
+			},
+			
+			/*
+			 * @description 为 Tree 中的一个节点追加一个子节点
+			 * @method append
+			 * @param {Object} data 要追加的子节点的 data 
+			 * @param {Object} parentNode 子节点的 parent 的 data、key 或者 node
+			*/
+			append(data, parentNode) {
+				this.store.append(data, parentNode);
+			},
+			
+			/*
+			 * @description 为 Tree 的一个节点的前面增加一个节点
+			 * @method insertBefore
+			 * @param {Object} data 要增加的节点的 data 
+			 * @param {all} refNode 要增加的节点的后一个节点的 data、key 或者 node
+			*/
+			insertBefore(data, refNode) {
+				this.store.insertBefore(data, refNode);
+			},
+			
+			/*
+			 * @description 为 Tree 的一个节点的后面增加一个节点
+			 * @method insertAfter
+			 * @param {Object} data 要增加的节点的 data 
+			 * @param {all} refNode 要增加的节点的前一个节点的 data、key 或者 node
+			*/
+			insertAfter(data, refNode) {
+				this.store.insertAfter(data, refNode);
+			},
+			
+			/*
+			 * @description 通过 keys 设置节点子元素
+			 * @method updateKeyChildren
+			 * @param {String, Number} key 节点 key 
+			 * @param {Object} data 节点数据的数组
+			*/
+			updateKeyChildren(key, data) {
+				if (!this.nodeKey) throw new Error('[Tree] nodeKey is required in updateKeyChild');
+				this.store.updateChildren(key, data);
+			}
+		},
+		
+		created() {
+			this.isTree = true;
+			
+			let props = this.props;
+			if (typeof this.props === 'function') props = this.props();
+			if (typeof props !== 'object') throw new Error('props must be of object type.');
+			
+			this.store = new TreeStore({
+				key: this.nodeKey,
+				data: this.treeData,
+				lazy: this.lazy,
+				props: props,
+				load: this.load,
+				showCheckbox: this.showCheckbox,
+				showRadio: this.showRadio,
+				currentNodeKey: this.currentNodeKey,
+				checkStrictly: this.checkStrictly || this.checkOnlyLeaf,
+				checkDescendants: this.checkDescendants,
+				expandOnCheckNode: this.expandOnCheckNode,
+				defaultCheckedKeys: this.defaultCheckedKeys,
+				defaultExpandedKeys: this.defaultExpandedKeys,
+				expandCurrentNodeParent: this.expandCurrentNodeParent,
+				autoExpandParent: this.autoExpandParent,
+				defaultExpandAll: this.defaultExpandAll,
+				filterNodeMethod: this.filterNodeMethod,
+				childVisibleForFilterNode: this.childVisibleForFilterNode,
+				showNodeIcon: this.showNodeIcon,
+				isInjectParentInNode: this.isInjectParentInNode
+			});
+
+			this.childNodesId = this.store.root.childNodesId;
+		},
+		
+		beforeDestroy() {
+			if (this.accordion) {
+				uni.$off(`${this.elId}-tree-node-expand`)
+			}
+		}
+	};
+</script>
+
+<style>
+	.ly-tree {
+		position: relative;
+		cursor: default;
+		background: #FFF;
+		color: #606266;
+		padding: 30rpx;
+		max-height: 600rpx;
+		overflow-y: scroll;
+	}
+	
+	.ly-tree.is-empty {
+		background: transparent;
+	}
+	
+	/* lyEmpty-start */
+	.ly-empty {
+		width: 100%;
+		display: flex;
+		justify-content: center;
+		margin-top: 100rpx;
+	}
+	/* lyEmpty-end */
+	
+	/* lyLoader-start */
+	.ly-loader {
+		margin-top: 100rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+	
+	.ly-loader-inner,
+	.ly-loader-inner:before,
+	.ly-loader-inner:after {
+		background: #efefef;
+		animation: load 1s infinite ease-in-out;
+		width: .5em;
+		height: 1em;
+	}
+	
+	.ly-loader-inner:before,
+	.ly-loader-inner:after {
+		position: absolute;
+		top: 0;
+		content: '';
+	}
+	
+	.ly-loader-inner:before {
+		left: -1em;
+	}
+	
+	.ly-loader-inner {
+		text-indent: -9999em;
+		position: relative;
+		font-size: 22rpx;
+		animation-delay: 0.16s;
+	}
+	
+	.ly-loader-inner:after {
+		left: 1em;
+		animation-delay: 0.32s;
+	}
+	/* lyLoader-end */
+	
+	@keyframes load {
+		0%,
+		80%,
+		100% {
+			box-shadow: 0 0 #efefef;
+			height: 1em;
+		}
+	
+		40% {
+			box-shadow: 0 -1.5em #efefef;
+			height: 1.5em;
+		}
+	}
+</style>

+ 498 - 0
components/ly-tree/model/node.js

@@ -0,0 +1,498 @@
+import {
+	markNodeData,
+	objectAssign,
+	arrayFindIndex,
+	getChildState,
+	reInitChecked,
+	getPropertyFromData,
+	isNull,
+	NODE_KEY
+} from '../tool/util';
+
+const getStore = function(store) {
+	let thisStore = store;
+	
+	return function() {
+		return thisStore;
+	}
+}
+
+let nodeIdSeed = 0;
+
+export default class Node {
+	constructor(options) {
+		this.time = new Date().getTime();
+		this.id = nodeIdSeed++;
+		this.text = null;
+		this.checked = false;
+		this.indeterminate = false;
+		this.data = null;
+		this.expanded = false;
+		this.parentId = null;
+		this.visible = true;
+		this.isCurrent = false;
+
+		for (let name in options) {
+			if (options.hasOwnProperty(name)) {
+				if (name === 'store') {
+					this.store = getStore(options[name]);
+				} else {
+					this[name] = options[name];
+				}
+			}
+		}
+
+		// internal
+		this.level = 0;
+		this.loaded = false;
+		this.childNodesId = [];
+		this.loading = false;
+		this.label = getPropertyFromData(this, 'label');
+		this.key = this.data ? this.data[this.store().key] : null;
+		this.disabled = getPropertyFromData(this, 'disabled');
+		this.nextSibling = null;
+		this.previousSibling = null;
+		this.icon = '';
+
+		if (this.parentId !== null) {
+			let parent = this.getParent(this.parentId);
+			
+			if (this.store().isInjectParentInNode) {
+				this.parent = parent;
+			}
+			
+			// 由于这里做了修改,默认第一个对象不会被注册到nodesMap中,所以找不到parent会报错,所以默认parent的level是0
+			if (!parent) {
+				parent = {
+					level: 0
+				}
+			} else {
+				const parentChildNodes = parent.getChildNodes(parent.childNodesId);
+				const index = parent.childNodesId.indexOf(this.key);
+				this.nextSibling = index > -1 ? parentChildNodes[index + 1] : null;
+				this.previousSibling = index > 0 ? parentChildNodes[index - 1] : null;
+			}
+			this.level = parent.level + 1;
+		}
+
+		if (!this.store()) {
+			throw new Error('[Node]store is required!');
+		}
+		
+		const props = this.store().props;
+		
+		if (this.store().showNodeIcon && props && typeof props.icon !== 'undefined') {
+			this.icon = getPropertyFromData(this, props.icon);
+		}
+		
+		this.store().registerNode(this);
+		
+		if (props && typeof props.isLeaf !== 'undefined') {
+			const isLeaf = getPropertyFromData(this, 'isLeaf');
+			if (typeof isLeaf === 'boolean') {
+				this.isLeafByUser = isLeaf;
+			}
+		}
+
+		if (this.store().lazy !== true && this.data) {
+			this.setData(this.data);
+
+			if (this.store().defaultExpandAll) {
+				this.expanded = true;
+			}
+		} else if (this.level > 0 && this.store().lazy && this.store().defaultExpandAll) {
+			this.expand();
+		}
+		
+		if (!Array.isArray(this.data)) {
+			markNodeData(this, this.data);
+		}
+		
+		if (!this.data) return;
+		
+		const defaultExpandedKeys = this.store().defaultExpandedKeys;
+		const key = this.store().key;
+		if (key && defaultExpandedKeys && defaultExpandedKeys.indexOf(this.key) !== -1) {
+			this.expand(null, this.store().autoExpandparent);
+		}
+
+		if (key && this.store().currentNodeKey !== undefined && this.key === this.store().currentNodeKey) {
+			this.store().currentNode = this;
+			this.store().currentNode.isCurrent = true;
+		}
+
+		if (this.store().lazy) {
+			this.store()._initDefaultCheckedNode(this);
+		}
+
+		this.updateLeafState();
+	}
+	
+	destroyStore() {
+		getStore(null)
+	}
+
+	setData(data) {
+		if (!Array.isArray(data)) {
+			markNodeData(this, data);
+		}
+
+		this.data = data;
+		this.childNodesId = [];
+
+		let children;
+		if (this.level === 0 && Array.isArray(this.data)) {
+			children = this.data;
+		} else {
+			children = getPropertyFromData(this, 'children') || [];
+		}
+
+		for (let i = 0, j = children.length; i < j; i++) {
+			this.insertChild({
+				data: children[i]
+			});
+		}
+	}
+
+	contains(target, deep = true) {
+		const walk = function(parent) {
+			const children = parent.getChildNodes(parent.childNodesId) || [];
+			let result = false;
+			for (let i = 0, j = children.length; i < j; i++) {
+				const child = children[i];
+				if (child === target || (deep && walk(child))) {
+					result = true;
+					break;
+				}
+			}
+			return result;
+		};
+
+		return walk(this);
+	}
+
+	remove() {
+		if (this.parentId !== null) {
+			const parent = this.getParent(this.parentId);
+			parent.removeChild(this);
+		}
+	}
+
+	insertChild(child, index, batch) {
+		if (!child) throw new Error('insertChild error: child is required.');
+
+		if (!(child instanceof Node)) {
+			if (!batch) {
+				const children = this.getChildren(true);
+				if (children.indexOf(child.data) === -1) {
+					if (typeof index === 'undefined' || index < 0) {
+						children.push(child.data);
+					} else {
+						children.splice(index, 0, child.data);
+					}
+				}
+			}
+			
+			objectAssign(child, {
+				parentId: isNull(this.key) ? '' : this.key,
+				store: this.store()
+			});
+			child = new Node(child);
+		}
+
+		child.level = this.level + 1;
+
+		if (typeof index === 'undefined' || index < 0) {
+			this.childNodesId.push(child.key);
+		} else {
+			this.childNodesId.splice(index, 0, child.key);
+		}
+
+		this.updateLeafState();
+	}
+
+	insertBefore(child, ref) {
+		let index;
+		if (ref) {
+			index = this.childNodesId.indexOf(ref.id);
+		}
+		this.insertChild(child, index);
+	}
+
+	insertAfter(child, ref) {
+		let index;
+		if (ref) {
+			index = this.childNodesId.indexOf(ref.id);
+			if (index !== -1) index += 1;
+		}
+		this.insertChild(child, index);
+	}
+
+	removeChild(child) {
+		const children = this.getChildren() || [];
+		const dataIndex = children.indexOf(child.data);
+		if (dataIndex > -1) {
+			children.splice(dataIndex, 1);
+		}
+		
+		const index = this.childNodesId.indexOf(child.key);
+		
+		if (index > -1) {
+			this.store() && this.store().deregisterNode(child);
+			child.parentId = null;
+			this.childNodesId.splice(index, 1);
+		}
+		
+		this.updateLeafState();
+	}
+
+	removeChildByData(data) {
+		let targetNode = null;
+
+		for (let i = 0; i < this.childNodesId.length; i++) {
+			let node = this.getChildNodes(this.childNodesId);
+			if (node[i].data === data) {
+				targetNode = node[i];
+				break;
+			}
+		}
+
+		if (targetNode) {
+			this.removeChild(targetNode);
+		}
+	}
+
+	// 为了避免APP端parent嵌套结构导致报错,这里parent需要从nodesMap中获取
+	getParent(parentId) {
+		if (!parentId.toString()) return null;
+		return this.store().nodesMap[parentId];
+	}
+
+	// 为了避免APP端childNodes嵌套结构导致报错,这里childNodes需要从nodesMap中获取
+	getChildNodes(childNodesId) {
+		let childNodes = [];
+		if (childNodesId.length === 0) return childNodes;
+		childNodesId.forEach((key) => {
+			childNodes.push(this.store().nodesMap[key]);
+		})
+		return childNodes;
+	}
+
+	expand(callback, expandparent) {
+		const done = () => {
+			if (expandparent) {
+				let parent = this.getParent(this.parentId);
+				while (parent && parent.level > 0) {
+					parent.expanded = true;
+					parent = this.getParent(parent.parentId);
+				}
+			}
+			this.expanded = true;
+			if (callback) callback();
+		};
+
+		if (this.shouldLoadData()) {
+			this.loadData(function(data) {
+				if (Array.isArray(data)) {
+					if (this.checked) {
+						this.setChecked(true, true);
+					} else if (!this.store().checkStrictly) {
+						reInitChecked(this);
+					}
+					done();
+				}
+			});
+		} else {
+			done();
+		}
+	}
+
+	doCreateChildren(array, defaultProps = {}) {
+		array.forEach((item) => {
+			this.insertChild(objectAssign({
+				data: item
+			}, defaultProps), undefined, true);
+		});
+	}
+
+	collapse() {
+		this.expanded = false;
+	}
+
+	shouldLoadData() {
+		return this.store().lazy === true && this.store().load && !this.loaded;
+	}
+
+	updateLeafState() {
+		if (this.store().lazy === true && this.loaded !== true && typeof this.isLeafByUser !== 'undefined') {
+			this.isLeaf = this.isLeafByUser;
+			return;
+		}
+		const childNodesId = this.childNodesId;
+		if (!this.store().lazy || (this.store().lazy === true && this.loaded === true)) {
+			this.isLeaf = !childNodesId || childNodesId.length === 0;
+			return;
+		}
+		this.isLeaf = false;
+	}
+
+	setChecked(value, deep, recursion, passValue) {
+		this.indeterminate = value === 'half';
+		this.checked = value === true;
+		
+		if (this.checked && this.store().expandOnCheckNode) {
+			this.expand(null, true)
+		}
+		
+		if (this.store().checkStrictly) return;
+		if (this.store().showRadio) return;
+
+		if (!(this.shouldLoadData() && !this.store().checkDescendants)) {
+			let childNodes = this.getChildNodes(this.childNodesId);
+			let {
+				all,
+				allWithoutDisable
+			} = getChildState(childNodes);
+
+			if (!this.isLeaf && (!all && allWithoutDisable)) {
+				this.checked = false;
+				value = false;
+			}
+
+			const handleDescendants = () => {
+				if (deep) {
+					let childNodes = this.getChildNodes(this.childNodesId)
+					for (let i = 0, j = childNodes.length; i < j; i++) {
+						const child = childNodes[i];
+						passValue = passValue || value !== false;
+						const isCheck = child.disabled ? child.checked : passValue;
+						child.setChecked(isCheck, deep, true, passValue);
+					}
+					const {
+						half,
+						all
+					} = getChildState(childNodes);
+					
+					if (!all) {
+						this.checked = all;
+						this.indeterminate = half;
+					}
+				}
+			};
+
+			if (this.shouldLoadData()) {
+				this.loadData(() => {
+					handleDescendants();
+					reInitChecked(this);
+				}, {
+					checked: value !== false
+				});
+				return;
+			} else {
+				handleDescendants();
+			}
+		}
+
+		if (!this.parentId) return;
+
+		let parent = this.getParent(this.parentId);
+		if (parent && parent.level === 0) return;
+
+		if (!recursion) {
+			reInitChecked(parent);
+		}
+	}
+
+	setRadioChecked(value) {
+		const allNodes = this.store()._getAllNodes().sort((a, b) => b.level - a.level);
+		allNodes.forEach(node => node.setChecked(false, false));
+		this.checked = value === true;
+	}
+
+	getChildren(forceInit = false) {
+		if (this.level === 0) return this.data;
+		const data = this.data;
+		if (!data) return null;
+
+		const props = this.store().props;
+		let children = 'children';
+		if (props) {
+			children = props.children || 'children';
+		}
+
+		if (data[children] === undefined) {
+			data[children] = null;
+		}
+
+		if (forceInit && !data[children]) {
+			data[children] = [];
+		}
+
+		return data[children];
+	}
+
+	updateChildren() {
+		let childNodes = this.getChildNodes(this.childNodesId);
+		const newData = this.getChildren() || [];
+		const oldData = childNodes.map((node) => node.data);
+
+		const newDataMap = {};
+		const newNodes = [];
+
+		newData.forEach((item, index) => {
+			const key = item[NODE_KEY];
+			const isNodeExists = !!key && arrayFindIndex(oldData, data => data[NODE_KEY] === key) >= 0;
+			if (isNodeExists) {
+				newDataMap[key] = {
+					index,
+					data: item
+				};
+			} else {
+				newNodes.push({
+					index,
+					data: item
+				});
+			}
+		});
+
+		if (!this.store().lazy) {
+			oldData.forEach((item) => {
+				if (!newDataMap[item[NODE_KEY]]) this.removeChildByData(item);
+			});
+		}
+
+		newNodes.forEach(({
+			index,
+			data
+		}) => {
+			this.insertChild({
+				data
+			}, index);
+		});
+
+		this.updateLeafState();
+	}
+
+	loadData(callback, defaultProps = {}) {
+		if (this.store().lazy === true && 
+			this.store().load && !this.loaded && 
+			(!this.loading || Object.keys(defaultProps).length)
+		) {
+			this.loading = true;
+
+			const resolve = (children) => {
+				this.loaded = true;
+				this.loading = false;
+				this.childNodesId = [];
+				this.doCreateChildren(children, defaultProps);
+				this.updateLeafState();
+				
+				callback && callback.call(this,children);
+			};
+
+			this.store().load(this, resolve);
+		} else {
+			callback && callback.call(this);
+		}
+	}
+}

+ 414 - 0
components/ly-tree/model/tree-store.js

@@ -0,0 +1,414 @@
+import Node from './node';
+import {
+	getNodeKey,
+	getPropertyFromData
+} from '../tool/util';
+
+export default class TreeStore {
+	constructor(options) {
+		this.ready = false;
+		this.currentNode = null;
+		this.currentNodeKey = null;
+
+		Object.assign(this, options);
+
+		if (!this.key) {
+			throw new Error('[Tree] nodeKey is required');
+		}
+
+		this.nodesMap = {};
+		this.root = new Node({
+			data: this.data,
+			store: this
+		});
+
+		if (this.lazy && this.load) {
+			const loadFn = this.load;
+			loadFn(this.root, (data) => {
+				this.root.doCreateChildren(data);
+				this._initDefaultCheckedNodes();
+				this.ready = true;
+			});
+		} else {
+			this._initDefaultCheckedNodes();
+			this.ready = true;
+		}
+	}
+
+	filter(value, data) {
+		const filterNodeMethod = this.filterNodeMethod;
+		const lazy = this.lazy;
+		const _self = this;
+		const traverse = function(node) {
+			const childNodes = node.root ? node.root.getChildNodes(node.root.childNodesId) : node.getChildNodes(node.childNodesId);
+
+			childNodes.forEach((child) => {
+				if (data && typeof data === 'object') {
+					let nodePath = _self.getNodePath(child.data);
+					if (!nodePath.some(pathItem => pathItem[_self.key] === data[_self.key])) {
+						child.visible = false;
+						traverse(child);
+						return;
+					}
+				}
+				
+				if (_self.childVisibleForFilterNode) {
+					let parent = child.getParent(child.parentId);
+					child.visible = filterNodeMethod.call(child, value, child.data, child) || (parent && parent.visible);
+				} else {
+					child.visible = filterNodeMethod.call(child, value, child.data, child);
+				}
+				
+				traverse(child);
+			});
+
+			if (!node.visible && childNodes.length) {
+				let allHidden = true;
+				allHidden = !childNodes.some(child => child.visible);
+
+				if (node.root) {
+					node.root.visible = allHidden === false;
+				} else {
+					node.visible = allHidden === false;
+				}
+			}
+			
+			if (!value) return;
+
+			if (node.visible && !node.isLeaf && !lazy) node.expand();
+		};
+
+		traverse(this);
+	}
+
+	setData(newVal) {
+		const instanceChanged = newVal !== this.root.data;
+		if (instanceChanged) {
+			this.root.setData(newVal);
+			this._initDefaultCheckedNodes();
+		} else {
+			this.root.updateChildren();
+		}
+	}
+
+	getNode(data) {
+		if (data instanceof Node) return data;
+		const key = typeof data !== 'object' ? data : getNodeKey(this.key, data);
+		return this.nodesMap[key] || null;
+	}
+
+	insertBefore(data, refData) {
+		const refNode = this.getNode(refData);
+		let parent = refNode.getParent(refNode.parentId);
+		parent.insertBefore({
+			data
+		}, refNode);
+	}
+
+	insertAfter(data, refData) {
+		const refNode = this.getNode(refData);
+		let parent = refNode.getParent(refNode.parentId);
+		parent.insertAfter({
+			data
+		}, refNode);
+	}
+
+	remove(data) {
+		const node = this.getNode(data);
+
+		if (node && node.parentId !== null) {
+			let parent = node.getParent(node.parentId);
+			if (node === this.currentNode) {
+				this.currentNode = null;
+			}
+			parent.removeChild(node);
+		}
+	}
+
+	append(data, parentData) {
+		const parentNode = parentData ? this.getNode(parentData) : this.root;
+
+		if (parentNode) {
+			parentNode.insertChild({
+				data
+			});
+		}
+	}
+
+	_initDefaultCheckedNodes() {
+		const defaultCheckedKeys = this.defaultCheckedKeys || [];
+		const nodesMap = this.nodesMap;
+		let checkedKeyfromData = [];
+		let totalCheckedKeys = []
+		
+		for (let key in nodesMap) {
+			let checked = getPropertyFromData(nodesMap[key], 'checked') || false;
+			checked && checkedKeyfromData.push(key);
+		}
+		
+		totalCheckedKeys = Array.from(new Set([...defaultCheckedKeys, ...checkedKeyfromData]));
+		totalCheckedKeys.forEach((checkedKey) => {
+			const node = nodesMap[checkedKey];
+			
+			if (node) {
+				node.setChecked(true, !this.checkStrictly);
+			}
+		});
+	}
+
+	_initDefaultCheckedNode(node) {
+		const defaultCheckedKeys = this.defaultCheckedKeys || [];
+
+		if (defaultCheckedKeys.indexOf(node.key) !== -1) {
+			node.setChecked(true, !this.checkStrictly);
+		}
+	}
+	
+	toggleExpendAll(isExpandAll) {
+		const allNodes = this._getAllNodes();
+		
+		allNodes.forEach(item => {
+			const node = this.getNode(item.key); 
+			
+			if (node) isExpandAll ? node.expand() : node.collapse();
+		});
+	}
+	
+	setCheckAll(isCkeckAll) {
+		const allNodes = this._getAllNodes();
+		
+		allNodes.forEach(item => {
+			item.setChecked(isCkeckAll, false);
+		}); 
+	}
+
+	setDefaultCheckedKey(newVal) {
+		if (newVal !== this.defaultCheckedKeys) {
+			this.defaultCheckedKeys = newVal;
+			this._initDefaultCheckedNodes();
+		}
+	}
+
+	registerNode(node) {
+
+		const key = this.key;
+		if (!key || !node || !node.data) return;
+
+		const nodeKey = node.key;
+		if (nodeKey !== undefined) this.nodesMap[node.key] = node;
+	}
+
+	deregisterNode(node) {
+		const key = this.key;
+		if (!key || !node || !node.data) return;
+
+		let childNodes = node.getChildNodes(node.childNodesId);
+		childNodes.forEach(child => {
+			this.deregisterNode(child);
+		});
+
+		delete this.nodesMap[node.key];
+	}
+	
+	getNodePath(data) {
+		if (!this.key) throw new Error('[Tree] nodeKey is required in getNodePath');
+		const node = this.getNode(data);
+		if (!node) return [];
+		
+		const path = [node.data];
+		let parent = node.getParent(node.parentId);
+		while (parent && parent !== this.root) {
+			path.push(parent.data);
+			parent = parent.getParent(parent.parentId);
+		}
+		return path.reverse();
+	}
+
+	getCheckedNodes(leafOnly = false, includeHalfChecked = false) {
+		const checkedNodes = [];
+		const traverse = function(node) {
+			const childNodes = node.root ? node.root.getChildNodes(node.root.childNodesId) : node.getChildNodes(node.childNodesId);
+
+			childNodes.forEach((child) => {
+				if ((child.checked || (includeHalfChecked && child.indeterminate)) && (!leafOnly || (leafOnly && child.isLeaf))) {
+					checkedNodes.push(child.data);
+				}
+
+				traverse(child);
+			});
+		};
+
+		traverse(this);
+
+		return checkedNodes;
+	}
+
+	getCheckedKeys(leafOnly = false, includeHalfChecked = false) {
+		return this.getCheckedNodes(leafOnly, includeHalfChecked).map((data) => (data || {})[this.key]);
+	}
+
+	getHalfCheckedNodes() {
+		const nodes = [];
+		const traverse = function(node) {
+			const childNodes = node.root ? node.root.getChildNodes(node.root.childNodesId) : node.getChildNodes(node.childNodesId);
+
+			childNodes.forEach((child) => {
+				if (child.indeterminate) {
+					nodes.push(child.data);
+				}
+
+				traverse(child);
+			});
+		};
+
+		traverse(this);
+
+		return nodes;
+	}
+
+	getHalfCheckedKeys() {
+		return this.getHalfCheckedNodes().map((data) => (data || {})[this.key]);
+	}
+
+	_getAllNodes() {
+		const allNodes = [];
+		const nodesMap = this.nodesMap;
+		for (let nodeKey in nodesMap) {
+			if (nodesMap.hasOwnProperty(nodeKey)) {
+				allNodes.push(nodesMap[nodeKey]);
+			}
+		}
+
+		return allNodes;
+	}
+
+	updateChildren(key, data) {
+		const node = this.nodesMap[key];
+		if (!node) return;
+		const childNodes = node.getChildNodes(node.childNodesId);
+		for (let i = childNodes.length - 1; i >= 0; i--) {
+			const child = childNodes[i];
+			this.remove(child.data);
+		}
+		for (let i = 0, j = data.length; i < j; i++) {
+			const child = data[i];
+			this.append(child, node.data);
+		}
+	}
+
+	_setCheckedKeys(key, leafOnly = false, checkedKeys) {
+		const allNodes = this._getAllNodes().sort((a, b) => b.level - a.level);
+		const cache = Object.create(null);
+		const keys = Object.keys(checkedKeys);
+		allNodes.forEach(node => node.setChecked(false, false));
+		for (let i = 0, j = allNodes.length; i < j; i++) {
+			const node = allNodes[i];
+			const nodeKey = node.data[key].toString();
+			let checked = keys.indexOf(nodeKey) > -1;
+			if (!checked) {
+				if (node.checked && !cache[nodeKey]) {
+					node.setChecked(false, false);
+				}
+				continue;
+			}
+
+			let parent = node.getParent(node.parentId);
+			while (parent && parent.level > 0) {
+				cache[parent.data[key]] = true;
+				parent = parent.getParent(parent.parentId);
+			}
+
+			if (node.isLeaf || this.checkStrictly) {
+				node.setChecked(true, false);
+				continue;
+			}
+			node.setChecked(true, true);
+
+			if (leafOnly) {
+				node.setChecked(false, false);
+				const traverse = function(node) {
+					const childNodes = node.getChildNodes(node.childNodesId);
+					childNodes.forEach((child) => {
+						if (!child.isLeaf) {
+							child.setChecked(false, false);
+						}
+						traverse(child);
+					});
+				};
+				traverse(node);
+			}
+		}
+	}
+
+	setCheckedNodes(array, leafOnly = false) {
+		const key = this.key;
+		const checkedKeys = {};
+		array.forEach((item) => {
+			checkedKeys[(item || {})[key]] = true;
+		});
+
+		this._setCheckedKeys(key, leafOnly, checkedKeys);
+	}
+
+	setCheckedKeys(keys, leafOnly = false) {
+		this.defaultCheckedKeys = keys;
+		const key = this.key;
+		const checkedKeys = {};
+		keys.forEach((key) => {
+			checkedKeys[key] = true;
+		});
+
+		this._setCheckedKeys(key, leafOnly, checkedKeys);
+	}
+
+	setDefaultExpandedKeys(keys) {
+		keys = keys || [];
+		this.defaultExpandedKeys = keys;
+
+		keys.forEach((key) => {
+			const node = this.getNode(key);
+			if (node) node.expand(null, this.autoExpandParent);
+		});
+	}
+
+	setChecked(data, checked, deep) {
+		const node = this.getNode(data);
+
+		if (node) {
+			node.setChecked(!!checked, deep);
+		}
+	}
+
+	getCurrentNode() {
+		return this.currentNode;
+	}
+
+	setCurrentNode(currentNode) {
+		const prevCurrentNode = this.currentNode;
+		if (prevCurrentNode) {
+			prevCurrentNode.isCurrent = false;
+		}
+		this.currentNode = currentNode;
+		this.currentNode.isCurrent = true;
+		
+		this.expandCurrentNodeParent && this.currentNode.expand(null, true)
+	}
+
+	setUserCurrentNode(node) {
+		const key = node[this.key];
+		const currNode = this.nodesMap[key];
+		this.setCurrentNode(currNode);
+	}
+
+	setCurrentNodeKey(key) {
+		if (key === null || key === undefined) {
+			this.currentNode && (this.currentNode.isCurrent = false);
+			this.currentNode = null;
+			return;
+		}
+		const node = this.getNode(key);
+		if (node) {
+			this.setCurrentNode(node);
+		}
+	}
+};

+ 114 - 0
components/ly-tree/tool/util.js

@@ -0,0 +1,114 @@
+export const NODE_KEY = '$treeNodeId';
+
+export const markNodeData = function(node, data) {
+	if (!data || data[NODE_KEY]) return;
+	Object.defineProperty(data, NODE_KEY, {
+		value: node.id,
+		enumerable: false,
+		configurable: false,
+		writable: false
+	});
+};
+
+export const getNodeKey = function(key, data) {
+	if (!key) return data[NODE_KEY];
+	return data[key];
+};
+
+export const objectAssign = function(target) {
+	for (let i = 1, j = arguments.length; i < j; i++) {
+		let source = arguments[i] || {};
+		for (let prop in source) {
+			if (source.hasOwnProperty(prop)) {
+				let value = source[prop];
+				if (value !== undefined) {
+					target[prop] = value;
+				}
+			}
+		}
+	}
+
+	return target;
+};
+
+// TODO: use native Array.find, Array.findIndex when IE support is dropped
+export const arrayFindIndex = function(arr, pred) {
+	for (let i = 0; i !== arr.length; ++i) {
+		if (pred(arr[i])) {
+			return i;
+		}
+	}
+	return -1;
+};
+
+export const getChildState = function(node) {
+	let all = true;
+	let none = true;
+	let allWithoutDisable = true;
+	for (let i = 0, j = node.length; i < j; i++) {
+		const n = node[i];
+		if (n.checked !== true || n.indeterminate) {
+			all = false;
+			if (!n.disabled) {
+				allWithoutDisable = false;
+			}
+		}
+		if (n.checked !== false || n.indeterminate) {
+			none = false;
+		}
+	}
+
+	return {
+		all,
+		none,
+		allWithoutDisable,
+		half: !all && !none
+	};
+};
+
+export const reInitChecked = function(node) {
+	if (!node || node.childNodesId.length === 0) return;
+
+	let childNodes = node.getChildNodes(node.childNodesId);
+	const {
+		all,
+		none,
+		half
+	} = getChildState(childNodes);
+	if (all) {
+		node.checked = true;
+		node.indeterminate = false;
+	} else if (half) {
+		node.checked = false;
+		node.indeterminate = true;
+	} else if (none) {
+		node.checked = false;
+		node.indeterminate = false;
+	}
+
+	let parent = node.getParent(node.parentId);
+	if (!parent || parent.level === 0) return;
+
+	if (!node.store().checkStrictly) {
+		reInitChecked(parent);
+	}
+};
+
+export const getPropertyFromData = function(node, prop) {
+	const props = node.store().props;
+	const data = node.data || {};
+	const config = props[prop];
+
+	if (typeof config === 'function') {
+		return config(data, node);
+	} else if (typeof config === 'string') {
+		return data[config];
+	} else if (typeof config === 'undefined') {
+		const dataProp = data[prop];
+		return dataProp === undefined ? '' : dataProp;
+	}
+};
+
+export const isNull = function(v) {
+	return v === undefined || v === null || v === '';
+}

+ 119 - 0
components/user-select/user-select-dialog.vue

@@ -0,0 +1,119 @@
+<template>
+	<view>
+		<view class="cu-modal bottom-modal" style="min-height: 200upx;" :class="modalName=='bottomModal'?'show':''">
+			<view class="cu-dialog">
+				<view class="cu-bar bg-white">
+					<view class="action text-blue" @tap="hideModal">取消</view>
+					<view class="action text-green" @tap="selectUsers">确定</view>
+				</view>
+				<view>
+					  <ly-tree :tree-data="data"
+						:props="props" 
+						node-key="id" 
+						:checkOnClickNode ="true"
+						:showRadio="showRadio"
+						:show-checkbox ="showCheckBox"
+						:checkOnlyLeaf = "true"
+						ref="userTree" />
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import userService from "@/api/sys/userService"
+	export default {
+		data() {
+			return {
+				data: [],
+				modalName: null,
+				labels: null,
+				treeList: []
+			};
+		},
+		props: {
+		    limit: Number,
+		    value: String,
+		    size: String,
+		    readonly: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			checkOnlyLeaf: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			showRadio: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			showCheckBox: {
+			  type: Boolean,
+			  default: () => { return true }
+			},
+		    disabled: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			props: {
+				type: Object,
+				default: () => {
+					return {
+						children: 'children',
+						label: 'label'
+					}
+				}
+			}
+		  },
+		mounted() {
+			userService.treeData().then((data)=>{
+				this.data = data
+				this.setTreeList(this.data)
+				let labelArra = []
+				if(this.value){
+					let keys = this.value.split(',')
+					keys.forEach((id) => {
+						this.treeList.forEach((node) => {
+						  if (id === node.id) {
+							labelArra.push(node.label)
+						  }
+						})
+					 })
+					this.labels = labelArra.join(',')
+				}
+			})
+		},
+		methods:{
+			setTreeList (datas) { // 遍历树  获取id数组
+			      for (var i in datas) {
+			        this.treeList.push(datas[i])
+			        if (datas[i].children) {
+			          this.setTreeList(datas[i].children)
+			        }
+			      }
+			    },
+			selectUsers () {
+				let ids = this.$refs.userTree.getCheckedNodes().filter((item)=>{
+					return item.type === 'user'
+				}).map((item)=>{
+					return item.id
+				}).join(",");
+				let names = this.$refs.userTree.getCheckedNodes().filter((item)=>{
+					return item.type === 'user'
+				}).map((item)=>{
+					return item.label
+				}).join(",");
+				this.labels = names
+				this.$emit('doSubmit', ids)
+				this.hideModal()
+			},
+			showModal() {
+				this.modalName = "bottomModal"
+			},
+			hideModal() {
+				this.modalName = null
+			}
+		}
+	}
+</script>

+ 139 - 0
components/user-select/user-select.vue

@@ -0,0 +1,139 @@
+<template>
+		<view style="width: 100%;"
+			@tap="open"
+		>
+			<u--input
+				v-model="labels"
+				suffixIcon="arrow-right"
+				suffixIconStyle="color: #909399"
+				disabled
+				disabledColor="#ffffff"
+				:placeholder="placeholder"
+				border="none"
+			></u--input>
+
+			<u-action-sheet
+				:show="show"
+				@close="show = false"
+			>
+			<view class="cu-bar bg-white">
+				<view class="action text-blue" @tap="show=false">取消</view>
+				<view class="action text-green" @tap="selectUsers">确定</view>
+			</view>
+			<view>
+				  <ly-tree :tree-data="data"
+					:props="props" 
+					node-key="id" 
+					:checkOnClickNode ="true"
+					:showRadio="showRadio"
+					:show-checkbox ="showCheckBox"
+					:checkOnlyLeaf = "checkOnlyLeaf"
+					ref="userTree" />
+			</view>
+		</u-action-sheet>
+	</view>
+</template>
+
+<script>
+	import userService from "@/api/sys/userService"
+	export default {
+		data() {
+			return {
+				show: false,
+				labels:'',
+				data: [],
+				treeList: []
+			};
+		},
+		props: {
+		    limit: Number,
+		    value: String,
+		    size: String,
+			placeholder: {
+			  type: String,
+			  default: () => { return '请选择用户' }
+			},
+		    readonly: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			checkOnlyLeaf: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			showRadio: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			showCheckBox: {
+			  type: Boolean,
+			  default: () => { return true }
+			},
+		    disabled: {
+		      type: Boolean,
+		      default: () => { return false }
+		    },
+			props: {
+				type: Object,
+				default: () => {
+					return {
+						children: 'children',
+						label: 'label'
+					}
+				}
+			}
+		  },
+		mounted() {
+			userService.treeData().then((data)=>{
+				this.data = data
+				this.setTreeList(this.data)
+				let labelArra = []
+				if(this.value){
+					let keys = this.value.split(',')
+					keys.forEach((id) => {
+						this.treeList.forEach((node) => {
+						  if (id === node.id) {
+							labelArra.push(node.label)
+						  }
+						})
+					 })
+					this.labels = labelArra.join(',')
+				}
+			})
+		},
+		methods:{
+			open () {
+				this.show = true;
+				if(this.value){
+					this.$nextTick(()=>{
+						let keys = this.value.split(',')
+						this.$refs.userTree.setCheckedKeys(keys);
+					})
+				}
+			},
+			setTreeList (datas) { // 遍历树  获取id数组
+			      for (var i in datas) {
+			        this.treeList.push(datas[i])
+			        if (datas[i].children) {
+			          this.setTreeList(datas[i].children)
+			        }
+			      }
+			    },
+			selectUsers () {
+				let ids = this.$refs.userTree.getCheckedNodes().filter((item)=>{
+					return item.type === 'user'
+				}).map((item)=>{
+					return item.id
+				}).join(",");
+				let names = this.$refs.userTree.getCheckedNodes().filter((item)=>{
+					return item.type === 'user'
+				}).map((item)=>{
+					return item.label
+				}).join(",");
+				this.labels = names
+				this.$emit('input', ids)
+				this.show = false
+			}
+		}
+	}
+</script>

+ 13 - 0
config.js

@@ -0,0 +1,13 @@
+let APP_SERVER_URL = ""
+
+if(process.env.NODE_ENV === 'development'){
+    // 开发环境
+    APP_SERVER_URL = '/api'
+}else{
+    // 生产环境
+    APP_SERVER_URL = 'http://vue3.jeeplus.org/jeeplus-v3/api'
+}
+
+APP_SERVER_URL = APP_SERVER_URL + '/app'
+
+export default APP_SERVER_URL

+ 52 - 0
main.js

@@ -0,0 +1,52 @@
+import Vue from 'vue'
+import App from './App'
+
+import store from './store'
+import request from './common/request.js'
+import dictUtils from '@/common/dictUtils.js'
+import * as auth from "@/common/auth.js"
+import * as utils from "@/common/util.js"
+import cuCustom from '@/components/cu-navbar/cu-navbar.vue'
+import BASE_URL from './config.js'
+import '@/common/filter'
+// 引入全局uView
+import uView from '@/uni_modules/uview-ui'
+import mixin from './common/mixin'
+
+
+Vue.component('cu-custom',cuCustom)
+Vue.config.productionTip = false
+Vue.prototype.$store = store
+Vue.prototype.$http = request
+Vue.prototype.$auth = auth
+Vue.prototype.$dictUtils = dictUtils
+Vue.prototype.$utils = utils
+Vue.prototype.recover = utils.recover
+Vue.prototype.BASE_URL = BASE_URL
+
+// 注册全局组件
+import LyTree from '@/components/ly-tree/ly-tree.vue'
+Vue.component('ly-tree', LyTree)
+
+
+
+App.mpType = 'app'
+Vue.use(uView)
+
+// #ifdef MP
+// 引入uView对小程序分享的mixin封装
+const mpShare = require('@/uni_modules/uview-ui/libs/mixin/mpShare.js')
+Vue.mixin(mpShare)
+// #endif
+
+Vue.mixin(mixin)
+
+const app = new Vue({
+    ...App
+})
+app.$mount()
+
+ 
+
+
+

+ 93 - 0
manifest.json

@@ -0,0 +1,93 @@
+{
+    "name" : "jeeplus",
+    "appid" : "__UNI__8E0DC6F",
+    "description" : "jeeplus移动审批平台",
+    "versionName" : "jeeplus mobile 1.0",
+    "versionCode" : 1,
+    "transformPx" : false,
+    "app-plus" : {
+        /* 5+App特有相关 */
+        "modules" : {},
+        /* 模块配置 */
+        "distribute" : {
+            /* 应用发布信息 */
+            "android" : {
+                /* android打包配置 */
+                "permissions" : [
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            "ios" : {},
+            /* ios打包配置 */
+            "sdkConfigs" : {
+                "ad" : {}
+            }
+        }
+    },
+    /* SDK配置 */
+    "quickapp" : {},
+    /* 快应用特有相关 */
+    "mp-weixin" : {
+        /* 小程序特有相关 */
+        "appid" : "",
+        "setting" : {
+            "urlCheck" : false,
+            "es6" : true
+        }
+    },
+    "h5" : {
+        "title" : "jeeplus",
+        "domain" : "demo1.jeeplus.org",
+        "devServer" : {
+            "port" : 8000,
+            "disableHostCheck" : true,
+            "proxy" : {
+                "/api" : {
+                    "target" : "http://localhost:8082", // 需要跨域的域名
+                    "changeOrigin" : true,
+                    "secure" : false,
+                    "pathRewrite" : {
+                        "^/api" : "/"
+                    }
+                },
+                "/file" : {
+                    "target" : "http://localhost:8082", // 需要跨域的域名
+                    "changeOrigin" : true,
+                    "secure" : false,
+                    "pathRewrite" : {
+                        "^/file" : "/file"
+                    }
+                }
+            }
+        },
+        "router" : {
+            "base" : "/h5/"
+        },
+        "optimization" : {
+            "treeShaking" : {
+                "enable" : true
+            }
+        }
+    }
+}

+ 15 - 0
node_modules/.bin/prettier

@@ -0,0 +1,15 @@
+#!/bin/sh
+basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
+
+case `uname` in
+    *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
+esac
+
+if [ -x "$basedir/node" ]; then
+  "$basedir/node"  "$basedir/../prettier/bin-prettier.js" "$@"
+  ret=$?
+else 
+  node  "$basedir/../prettier/bin-prettier.js" "$@"
+  ret=$?
+fi
+exit $ret

+ 7 - 0
node_modules/.bin/prettier.cmd

@@ -0,0 +1,7 @@
+@IF EXIST "%~dp0\node.exe" (
+  "%~dp0\node.exe"  "%~dp0\..\prettier\bin-prettier.js" %*
+) ELSE (
+  @SETLOCAL
+  @SET PATHEXT=%PATHEXT:;.JS;=;%
+  node  "%~dp0\..\prettier\bin-prettier.js" %*
+)

+ 31 - 0
node_modules/.yarn-integrity

@@ -0,0 +1,31 @@
+{
+  "systemParams": "win32-x64-83",
+  "modulesFolders": [
+    "node_modules"
+  ],
+  "flags": [],
+  "linkedModules": [],
+  "topLevelPatterns": [
+    "lodash.pick@^4.4.0",
+    "lodash@^4.17.20",
+    "moment@^2.27.0",
+    "prettier@^1.12.1",
+    "qs@^6.9.4"
+  ],
+  "lockfileEntries": {
+    "call-bind@^1.0.0": "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c",
+    "function-bind@^1.1.1": "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d",
+    "get-intrinsic@^1.0.2": "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f",
+    "has-symbols@^1.0.3": "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8",
+    "has@^1.0.3": "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796",
+    "lodash.pick@^4.4.0": "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3",
+    "lodash@^4.17.20": "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c",
+    "moment@^2.27.0": "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108",
+    "object-inspect@^1.9.0": "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9",
+    "prettier@^1.12.1": "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb",
+    "qs@^6.9.4": "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a",
+    "side-channel@^1.0.4": "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
+  },
+  "files": [],
+  "artifacts": {}
+}

+ 1 - 0
node_modules/call-bind/.eslintignore

@@ -0,0 +1 @@
+coverage/

+ 17 - 0
node_modules/call-bind/.eslintrc

@@ -0,0 +1,17 @@
+{
+	"root": true,
+
+	"extends": "@ljharb",
+
+	"rules": {
+		"func-name-matching": 0,
+		"id-length": 0,
+		"new-cap": [2, {
+			"capIsNewExceptions": [
+				"GetIntrinsic",
+			],
+		}],
+		"no-magic-numbers": 0,
+		"operator-linebreak": [2, "before"],
+	},
+}

+ 12 - 0
node_modules/call-bind/.github/FUNDING.yml

@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: [ljharb]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: npm/call-bind
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

+ 13 - 0
node_modules/call-bind/.nycrc

@@ -0,0 +1,13 @@
+{
+	"all": true,
+	"check-coverage": false,
+	"reporter": ["text-summary", "text", "html", "json"],
+	"lines": 86,
+	"statements": 85.93,
+	"functions": 82.43,
+	"branches": 76.06,
+	"exclude": [
+		"coverage",
+		"test"
+	]
+}

+ 42 - 0
node_modules/call-bind/CHANGELOG.md

@@ -0,0 +1,42 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [v1.0.2](https://github.com/ljharb/call-bind/compare/v1.0.1...v1.0.2) - 2021-01-11
+
+### Commits
+
+- [Fix] properly include the receiver in the bound length [`dbae7bc`](https://github.com/ljharb/call-bind/commit/dbae7bc676c079a0d33c0a43e9ef92cb7b01345d)
+
+## [v1.0.1](https://github.com/ljharb/call-bind/compare/v1.0.0...v1.0.1) - 2021-01-08
+
+### Commits
+
+- [Tests] migrate tests to Github Actions [`b6db284`](https://github.com/ljharb/call-bind/commit/b6db284c36f8ccd195b88a6764fe84b7223a0da1)
+- [meta] do not publish github action workflow files [`ec7fe46`](https://github.com/ljharb/call-bind/commit/ec7fe46e60cfa4764ee943d2755f5e5a366e578e)
+- [Fix] preserve original function’s length when possible [`adbceaa`](https://github.com/ljharb/call-bind/commit/adbceaa3cac4b41ea78bb19d7ccdbaaf7e0bdadb)
+- [Tests] gather coverage data on every job [`d69e23c`](https://github.com/ljharb/call-bind/commit/d69e23cc65f101ba1d4c19bb07fa8eb0ec624be8)
+- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`2fd3586`](https://github.com/ljharb/call-bind/commit/2fd3586c5d47b335364c14293114c6b625ae1f71)
+- [Deps] update `get-intrinsic` [`f23e931`](https://github.com/ljharb/call-bind/commit/f23e9318cc271c2add8bb38cfded85ee7baf8eee)
+- [Deps] update `get-intrinsic` [`72d9f44`](https://github.com/ljharb/call-bind/commit/72d9f44e184465ba8dd3fb48260bbcff234985f2)
+- [meta] fix FUNDING.yml [`e723573`](https://github.com/ljharb/call-bind/commit/e723573438c5a68dcec31fb5d96ea6b7e4a93be8)
+- [eslint] ignore coverage output [`15e76d2`](https://github.com/ljharb/call-bind/commit/15e76d28a5f43e504696401e5b31ebb78ee1b532)
+- [meta] add Automatic Rebase and Require Allow Edits workflows [`8fa4dab`](https://github.com/ljharb/call-bind/commit/8fa4dabb23ba3dd7bb92c9571c1241c08b56e4b6)
+
+## v1.0.0 - 2020-10-30
+
+### Commits
+
+- Initial commit [`306cf98`](https://github.com/ljharb/call-bind/commit/306cf98c7ec9e7ef66b653ec152277ac1381eb50)
+- Tests [`e10d0bb`](https://github.com/ljharb/call-bind/commit/e10d0bbdadc7a10ecedc9a1c035112d3e368b8df)
+- Implementation [`43852ed`](https://github.com/ljharb/call-bind/commit/43852eda0f187327b7fad2423ca972149a52bd65)
+- npm init [`408f860`](https://github.com/ljharb/call-bind/commit/408f860b773a2f610805fd3613d0d71bac1b6249)
+- [meta] add Automatic Rebase and Require Allow Edits workflows [`fb349b2`](https://github.com/ljharb/call-bind/commit/fb349b2e48defbec8b5ec8a8395cc8f69f220b13)
+- [meta] add `auto-changelog` [`c4001fc`](https://github.com/ljharb/call-bind/commit/c4001fc43031799ef908211c98d3b0fb2b60fde4)
+- [meta] add "funding"; create `FUNDING.yml` [`d4d6d29`](https://github.com/ljharb/call-bind/commit/d4d6d2974a14bc2e98830468eda7fe6d6a776717)
+- [Tests] add `npm run lint` [`dedfb98`](https://github.com/ljharb/call-bind/commit/dedfb98bd0ecefb08ddb9a94061bd10cde4332af)
+- Only apps should have lockfiles [`54ac776`](https://github.com/ljharb/call-bind/commit/54ac77653db45a7361dc153d2f478e743f110650)
+- [meta] add `safe-publish-latest` [`9ea8e43`](https://github.com/ljharb/call-bind/commit/9ea8e435b950ce9b705559cd651039f9bf40140f)

+ 21 - 0
node_modules/call-bind/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Jordan Harband
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 2 - 0
node_modules/call-bind/README.md

@@ -0,0 +1,2 @@
+# call-bind
+Robustly `.call.bind()` a function.

+ 15 - 0
node_modules/call-bind/callBound.js

@@ -0,0 +1,15 @@
+'use strict';
+
+var GetIntrinsic = require('get-intrinsic');
+
+var callBind = require('./');
+
+var $indexOf = callBind(GetIntrinsic('String.prototype.indexOf'));
+
+module.exports = function callBoundIntrinsic(name, allowMissing) {
+	var intrinsic = GetIntrinsic(name, !!allowMissing);
+	if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {
+		return callBind(intrinsic);
+	}
+	return intrinsic;
+};

+ 47 - 0
node_modules/call-bind/index.js

@@ -0,0 +1,47 @@
+'use strict';
+
+var bind = require('function-bind');
+var GetIntrinsic = require('get-intrinsic');
+
+var $apply = GetIntrinsic('%Function.prototype.apply%');
+var $call = GetIntrinsic('%Function.prototype.call%');
+var $reflectApply = GetIntrinsic('%Reflect.apply%', true) || bind.call($call, $apply);
+
+var $gOPD = GetIntrinsic('%Object.getOwnPropertyDescriptor%', true);
+var $defineProperty = GetIntrinsic('%Object.defineProperty%', true);
+var $max = GetIntrinsic('%Math.max%');
+
+if ($defineProperty) {
+	try {
+		$defineProperty({}, 'a', { value: 1 });
+	} catch (e) {
+		// IE 8 has a broken defineProperty
+		$defineProperty = null;
+	}
+}
+
+module.exports = function callBind(originalFunction) {
+	var func = $reflectApply(bind, $call, arguments);
+	if ($gOPD && $defineProperty) {
+		var desc = $gOPD(func, 'length');
+		if (desc.configurable) {
+			// original length, plus the receiver, minus any additional arguments (after the receiver)
+			$defineProperty(
+				func,
+				'length',
+				{ value: 1 + $max(0, originalFunction.length - (arguments.length - 1)) }
+			);
+		}
+	}
+	return func;
+};
+
+var applyBind = function applyBind() {
+	return $reflectApply(bind, $apply, arguments);
+};
+
+if ($defineProperty) {
+	$defineProperty(module.exports, 'apply', { value: applyBind });
+} else {
+	module.exports.apply = applyBind;
+}

+ 80 - 0
node_modules/call-bind/package.json

@@ -0,0 +1,80 @@
+{
+	"name": "call-bind",
+	"version": "1.0.2",
+	"description": "Robustly `.call.bind()` a function",
+	"main": "index.js",
+	"exports": {
+		".": [
+			{
+				"default": "./index.js"
+			},
+			"./index.js"
+		],
+		"./callBound": [
+			{
+				"default": "./callBound.js"
+			},
+			"./callBound.js"
+		],
+		"./package.json": "./package.json"
+	},
+	"scripts": {
+		"prepublish": "safe-publish-latest",
+		"lint": "eslint --ext=.js,.mjs .",
+		"pretest": "npm run lint",
+		"tests-only": "nyc tape 'test/*'",
+		"test": "npm run tests-only",
+		"posttest": "aud --production",
+		"version": "auto-changelog && git add CHANGELOG.md",
+		"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
+	},
+	"repository": {
+		"type": "git",
+		"url": "git+https://github.com/ljharb/call-bind.git"
+	},
+	"keywords": [
+		"javascript",
+		"ecmascript",
+		"es",
+		"js",
+		"callbind",
+		"callbound",
+		"call",
+		"bind",
+		"bound",
+		"call-bind",
+		"call-bound",
+		"function",
+		"es-abstract"
+	],
+	"author": "Jordan Harband <ljharb@gmail.com>",
+	"funding": {
+		"url": "https://github.com/sponsors/ljharb"
+	},
+	"license": "MIT",
+	"bugs": {
+		"url": "https://github.com/ljharb/call-bind/issues"
+	},
+	"homepage": "https://github.com/ljharb/call-bind#readme",
+	"devDependencies": {
+		"@ljharb/eslint-config": "^17.3.0",
+		"aud": "^1.1.3",
+		"auto-changelog": "^2.2.1",
+		"eslint": "^7.17.0",
+		"nyc": "^10.3.2",
+		"safe-publish-latest": "^1.1.4",
+		"tape": "^5.1.1"
+	},
+	"dependencies": {
+		"function-bind": "^1.1.1",
+		"get-intrinsic": "^1.0.2"
+	},
+	"auto-changelog": {
+		"output": "CHANGELOG.md",
+		"template": "keepachangelog",
+		"unreleased": false,
+		"commitLimit": false,
+		"backfillLimit": false,
+		"hideCredit": true
+	}
+}

+ 55 - 0
node_modules/call-bind/test/callBound.js

@@ -0,0 +1,55 @@
+'use strict';
+
+var test = require('tape');
+
+var callBound = require('../callBound');
+
+test('callBound', function (t) {
+	// static primitive
+	t.equal(callBound('Array.length'), Array.length, 'Array.length yields itself');
+	t.equal(callBound('%Array.length%'), Array.length, '%Array.length% yields itself');
+
+	// static non-function object
+	t.equal(callBound('Array.prototype'), Array.prototype, 'Array.prototype yields itself');
+	t.equal(callBound('%Array.prototype%'), Array.prototype, '%Array.prototype% yields itself');
+	t.equal(callBound('Array.constructor'), Array.constructor, 'Array.constructor yields itself');
+	t.equal(callBound('%Array.constructor%'), Array.constructor, '%Array.constructor% yields itself');
+
+	// static function
+	t.equal(callBound('Date.parse'), Date.parse, 'Date.parse yields itself');
+	t.equal(callBound('%Date.parse%'), Date.parse, '%Date.parse% yields itself');
+
+	// prototype primitive
+	t.equal(callBound('Error.prototype.message'), Error.prototype.message, 'Error.prototype.message yields itself');
+	t.equal(callBound('%Error.prototype.message%'), Error.prototype.message, '%Error.prototype.message% yields itself');
+
+	// prototype function
+	t.notEqual(callBound('Object.prototype.toString'), Object.prototype.toString, 'Object.prototype.toString does not yield itself');
+	t.notEqual(callBound('%Object.prototype.toString%'), Object.prototype.toString, '%Object.prototype.toString% does not yield itself');
+	t.equal(callBound('Object.prototype.toString')(true), Object.prototype.toString.call(true), 'call-bound Object.prototype.toString calls into the original');
+	t.equal(callBound('%Object.prototype.toString%')(true), Object.prototype.toString.call(true), 'call-bound %Object.prototype.toString% calls into the original');
+
+	t['throws'](
+		function () { callBound('does not exist'); },
+		SyntaxError,
+		'nonexistent intrinsic throws'
+	);
+	t['throws'](
+		function () { callBound('does not exist', true); },
+		SyntaxError,
+		'allowMissing arg still throws for unknown intrinsic'
+	);
+
+	/* globals WeakRef: false */
+	t.test('real but absent intrinsic', { skip: typeof WeakRef !== 'undefined' }, function (st) {
+		st['throws'](
+			function () { callBound('WeakRef'); },
+			TypeError,
+			'real but absent intrinsic throws'
+		);
+		st.equal(callBound('WeakRef', true), undefined, 'allowMissing arg avoids exception');
+		st.end();
+	});
+
+	t.end();
+});

+ 66 - 0
node_modules/call-bind/test/index.js

@@ -0,0 +1,66 @@
+'use strict';
+
+var callBind = require('../');
+var bind = require('function-bind');
+
+var test = require('tape');
+
+/*
+ * older engines have length nonconfigurable
+ * in io.js v3, it is configurable except on bound functions, hence the .bind()
+ */
+var functionsHaveConfigurableLengths = !!(
+	Object.getOwnPropertyDescriptor
+	&& Object.getOwnPropertyDescriptor(bind.call(function () {}), 'length').configurable
+);
+
+test('callBind', function (t) {
+	var sentinel = { sentinel: true };
+	var func = function (a, b) {
+		// eslint-disable-next-line no-invalid-this
+		return [this, a, b];
+	};
+	t.equal(func.length, 2, 'original function length is 2');
+	t.deepEqual(func(), [undefined, undefined, undefined], 'unbound func with too few args');
+	t.deepEqual(func(1, 2), [undefined, 1, 2], 'unbound func with right args');
+	t.deepEqual(func(1, 2, 3), [undefined, 1, 2], 'unbound func with too many args');
+
+	var bound = callBind(func);
+	t.equal(bound.length, func.length + 1, 'function length is preserved', { skip: !functionsHaveConfigurableLengths });
+	t.deepEqual(bound(), [undefined, undefined, undefined], 'bound func with too few args');
+	t.deepEqual(bound(1, 2), [1, 2, undefined], 'bound func with right args');
+	t.deepEqual(bound(1, 2, 3), [1, 2, 3], 'bound func with too many args');
+
+	var boundR = callBind(func, sentinel);
+	t.equal(boundR.length, func.length, 'function length is preserved', { skip: !functionsHaveConfigurableLengths });
+	t.deepEqual(boundR(), [sentinel, undefined, undefined], 'bound func with receiver, with too few args');
+	t.deepEqual(boundR(1, 2), [sentinel, 1, 2], 'bound func with receiver, with right args');
+	t.deepEqual(boundR(1, 2, 3), [sentinel, 1, 2], 'bound func with receiver, with too many args');
+
+	var boundArg = callBind(func, sentinel, 1);
+	t.equal(boundArg.length, func.length - 1, 'function length is preserved', { skip: !functionsHaveConfigurableLengths });
+	t.deepEqual(boundArg(), [sentinel, 1, undefined], 'bound func with receiver and arg, with too few args');
+	t.deepEqual(boundArg(2), [sentinel, 1, 2], 'bound func with receiver and arg, with right arg');
+	t.deepEqual(boundArg(2, 3), [sentinel, 1, 2], 'bound func with receiver and arg, with too many args');
+
+	t.test('callBind.apply', function (st) {
+		var aBound = callBind.apply(func);
+		st.deepEqual(aBound(sentinel), [sentinel, undefined, undefined], 'apply-bound func with no args');
+		st.deepEqual(aBound(sentinel, [1], 4), [sentinel, 1, undefined], 'apply-bound func with too few args');
+		st.deepEqual(aBound(sentinel, [1, 2], 4), [sentinel, 1, 2], 'apply-bound func with right args');
+
+		var aBoundArg = callBind.apply(func);
+		st.deepEqual(aBoundArg(sentinel, [1, 2, 3], 4), [sentinel, 1, 2], 'apply-bound func with too many args');
+		st.deepEqual(aBoundArg(sentinel, [1, 2], 4), [sentinel, 1, 2], 'apply-bound func with right args');
+		st.deepEqual(aBoundArg(sentinel, [1], 4), [sentinel, 1, undefined], 'apply-bound func with too few args');
+
+		var aBoundR = callBind.apply(func, sentinel);
+		st.deepEqual(aBoundR([1, 2, 3], 4), [sentinel, 1, 2], 'apply-bound func with receiver and too many args');
+		st.deepEqual(aBoundR([1, 2], 4), [sentinel, 1, 2], 'apply-bound func with receiver and right args');
+		st.deepEqual(aBoundR([1], 4), [sentinel, 1, undefined], 'apply-bound func with receiver and too few args');
+
+		st.end();
+	});
+
+	t.end();
+});

+ 20 - 0
node_modules/function-bind/.editorconfig

@@ -0,0 +1,20 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+max_line_length = 120
+
+[CHANGELOG.md]
+indent_style = space
+indent_size = 2
+
+[*.json]
+max_line_length = off
+
+[Makefile]
+max_line_length = off

+ 15 - 0
node_modules/function-bind/.eslintrc

@@ -0,0 +1,15 @@
+{
+	"root": true,
+
+	"extends": "@ljharb",
+
+	"rules": {
+		"func-name-matching": 0,
+		"indent": [2, 4],
+		"max-nested-callbacks": [2, 3],
+		"max-params": [2, 3],
+		"max-statements": [2, 20],
+		"no-new-func": [1],
+		"strict": [0]
+	}
+}

+ 176 - 0
node_modules/function-bind/.jscs.json

@@ -0,0 +1,176 @@
+{
+	"es3": true,
+
+	"additionalRules": [],
+
+	"requireSemicolons": true,
+
+	"disallowMultipleSpaces": true,
+
+	"disallowIdentifierNames": [],
+
+	"requireCurlyBraces": {
+		"allExcept": [],
+		"keywords": ["if", "else", "for", "while", "do", "try", "catch"]
+	},
+
+	"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"],
+
+	"disallowSpaceAfterKeywords": [],
+
+	"disallowSpaceBeforeComma": true,
+	"disallowSpaceAfterComma": false,
+	"disallowSpaceBeforeSemicolon": true,
+
+	"disallowNodeTypes": [
+		"DebuggerStatement",
+		"ForInStatement",
+		"LabeledStatement",
+		"SwitchCase",
+		"SwitchStatement",
+		"WithStatement"
+	],
+
+	"requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] },
+
+	"requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true },
+	"requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true },
+	"disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true },
+	"requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true },
+	"disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true },
+
+	"requireSpaceBetweenArguments": true,
+
+	"disallowSpacesInsideParentheses": true,
+
+	"disallowSpacesInsideArrayBrackets": true,
+
+	"disallowQuotedKeysInObjects": { "allExcept": ["reserved"] },
+
+	"disallowSpaceAfterObjectKeys": true,
+
+	"requireCommaBeforeLineBreak": true,
+
+	"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
+	"requireSpaceAfterPrefixUnaryOperators": [],
+
+	"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
+	"requireSpaceBeforePostfixUnaryOperators": [],
+
+	"disallowSpaceBeforeBinaryOperators": [],
+	"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
+
+	"requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
+	"disallowSpaceAfterBinaryOperators": [],
+
+	"disallowImplicitTypeConversion": ["binary", "string"],
+
+	"disallowKeywords": ["with", "eval"],
+
+	"requireKeywordsOnNewLine": [],
+	"disallowKeywordsOnNewLine": ["else"],
+
+	"requireLineFeedAtFileEnd": true,
+
+	"disallowTrailingWhitespace": true,
+
+	"disallowTrailingComma": true,
+
+	"excludeFiles": ["node_modules/**", "vendor/**"],
+
+	"disallowMultipleLineStrings": true,
+
+	"requireDotNotation": { "allExcept": ["keywords"] },
+
+	"requireParenthesesAroundIIFE": true,
+
+	"validateLineBreaks": "LF",
+
+	"validateQuoteMarks": {
+		"escape": true,
+		"mark": "'"
+	},
+
+	"disallowOperatorBeforeLineBreak": [],
+
+	"requireSpaceBeforeKeywords": [
+		"do",
+		"for",
+		"if",
+		"else",
+		"switch",
+		"case",
+		"try",
+		"catch",
+		"finally",
+		"while",
+		"with",
+		"return"
+	],
+
+	"validateAlignedFunctionParameters": {
+		"lineBreakAfterOpeningBraces": true,
+		"lineBreakBeforeClosingBraces": true
+	},
+
+	"requirePaddingNewLinesBeforeExport": true,
+
+	"validateNewlineAfterArrayElements": {
+		"maximum": 8
+	},
+
+	"requirePaddingNewLinesAfterUseStrict": true,
+
+	"disallowArrowFunctions": true,
+
+	"disallowMultiLineTernary": true,
+
+	"validateOrderInObjectKeys": "asc-insensitive",
+
+	"disallowIdenticalDestructuringNames": true,
+
+	"disallowNestedTernaries": { "maxLevel": 1 },
+
+	"requireSpaceAfterComma": { "allExcept": ["trailing"] },
+	"requireAlignedMultilineParams": false,
+
+	"requireSpacesInGenerator": {
+		"afterStar": true
+	},
+
+	"disallowSpacesInGenerator": {
+		"beforeStar": true
+	},
+
+	"disallowVar": false,
+
+	"requireArrayDestructuring": false,
+
+	"requireEnhancedObjectLiterals": false,
+
+	"requireObjectDestructuring": false,
+
+	"requireEarlyReturn": false,
+
+	"requireCapitalizedConstructorsNew": {
+		"allExcept": ["Function", "String", "Object", "Symbol", "Number", "Date", "RegExp", "Error", "Boolean", "Array"]
+	},
+
+	"requireImportAlphabetized": false,
+
+    "requireSpaceBeforeObjectValues": true,
+    "requireSpaceBeforeDestructuredValues": true,
+
+	"disallowSpacesInsideTemplateStringPlaceholders": true,
+
+    "disallowArrayDestructuringReturn": false,
+
+    "requireNewlineBeforeSingleStatementsInIf": false,
+
+	"disallowUnusedVariables": true,
+
+	"requireSpacesInsideImportedObjectBraces": true,
+
+	"requireUseStrict": true
+}
+

+ 22 - 0
node_modules/function-bind/.npmignore

@@ -0,0 +1,22 @@
+# gitignore
+.DS_Store
+.monitor
+.*.swp
+.nodemonignore
+releases
+*.log
+*.err
+fleet.json
+public/browserify
+bin/*.json
+.bin
+build
+compile
+.lock-wscript
+coverage
+node_modules
+
+# Only apps should have lockfiles
+npm-shrinkwrap.json
+package-lock.json
+yarn.lock

+ 168 - 0
node_modules/function-bind/.travis.yml

@@ -0,0 +1,168 @@
+language: node_js
+os:
+ - linux
+node_js:
+  - "8.4"
+  - "7.10"
+  - "6.11"
+  - "5.12"
+  - "4.8"
+  - "iojs-v3.3"
+  - "iojs-v2.5"
+  - "iojs-v1.8"
+  - "0.12"
+  - "0.10"
+  - "0.8"
+before_install:
+  - 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ]; then npm install -g npm@1.3 ; elif [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then case "$(npm --version)" in 1.*) npm install -g npm@1.4.28 ;; 2.*) npm install -g npm@2 ;; esac ; fi'
+  - 'if [ "${TRAVIS_NODE_VERSION}" != "0.6" ] && [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then if [ "${TRAVIS_NODE_VERSION%${TRAVIS_NODE_VERSION#[0-9]}}" = "0" ] || [ "${TRAVIS_NODE_VERSION:0:4}" = "iojs" ]; then npm install -g npm@4.5 ; else npm install -g npm; fi; fi'
+install:
+  - 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ]; then nvm install 0.8 && npm install -g npm@1.3 && npm install -g npm@1.4.28 && npm install -g npm@2 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;'
+script:
+  - 'if [ -n "${PRETEST-}" ]; then npm run pretest ; fi'
+  - 'if [ -n "${POSTTEST-}" ]; then npm run posttest ; fi'
+  - 'if [ -n "${COVERAGE-}" ]; then npm run coverage ; fi'
+  - 'if [ -n "${TEST-}" ]; then npm run tests-only ; fi'
+sudo: false
+env:
+  - TEST=true
+matrix:
+  fast_finish: true
+  include:
+    - node_js: "node"
+      env: PRETEST=true
+    - node_js: "4"
+      env: COVERAGE=true
+    - node_js: "8.3"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "8.2"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "8.1"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "8.0"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.9"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.8"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.7"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.6"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.5"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.4"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.3"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.2"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.1"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "7.0"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.10"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.9"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.8"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.7"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.6"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.5"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.4"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.3"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.2"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.1"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "6.0"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.11"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.10"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.9"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.8"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.7"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.6"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.5"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.4"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.3"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.2"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.1"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "5.0"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "4.7"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "4.6"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "4.5"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "4.4"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "4.3"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "4.2"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "4.1"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "4.0"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v3.2"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v3.1"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v3.0"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v2.4"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v2.3"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v2.2"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v2.1"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v2.0"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v1.7"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v1.6"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v1.5"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v1.4"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v1.3"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v1.2"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v1.1"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "iojs-v1.0"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "0.11"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "0.9"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "0.6"
+      env: TEST=true ALLOW_FAILURE=true
+    - node_js: "0.4"
+      env: TEST=true ALLOW_FAILURE=true
+  allow_failures:
+    - os: osx
+    - env: TEST=true ALLOW_FAILURE=true

+ 0 - 0
node_modules/function-bind/LICENSE


Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott