Selaa lähdekoodia

🎉 feat(OA): 初始化基于 ThinkPHP 8 + PHP 8.2 的多模块 OA 管理系统

lxz 3 viikkoa sitten
commit
47e478eab5
100 muutettua tiedostoa jossa 11849 lisäystä ja 0 poistoa
  1. 22 0
      .gitignore
  2. 14 0
      DISCLAIMER.md
  3. 201 0
      LICENSE
  4. 37 0
      LICENSE.txt
  5. 201 0
      README.md
  6. 18 0
      app/adm/common.php
  7. 173 0
      app/adm/controller/Api.php
  8. 93 0
      app/adm/controller/Basic.php
  9. 501 0
      app/adm/controller/Car.php
  10. 353 0
      app/adm/controller/Flow.php
  11. 373 0
      app/adm/controller/Meeting.php
  12. 135 0
      app/adm/controller/News.php
  13. 140 0
      app/adm/controller/Note.php
  14. 141 0
      app/adm/controller/Notecate.php
  15. 206 0
      app/adm/controller/Official.php
  16. 282 0
      app/adm/controller/Property.php
  17. 87 0
      app/adm/controller/Propertybrand.php
  18. 112 0
      app/adm/controller/Propertycate.php
  19. 87 0
      app/adm/controller/Propertyunit.php
  20. 206 0
      app/adm/controller/Seal.php
  21. 111 0
      app/adm/controller/Sealcate.php
  22. 8 0
      app/adm/event.php
  23. 8 0
      app/adm/middleware.php
  24. 197 0
      app/adm/model/Car.php
  25. 143 0
      app/adm/model/MeetingOrder.php
  26. 131 0
      app/adm/model/MeetingRecords.php
  27. 114 0
      app/adm/model/News.php
  28. 129 0
      app/adm/model/Note.php
  29. 108 0
      app/adm/model/NoteCate.php
  30. 145 0
      app/adm/model/OfficialDocs.php
  31. 135 0
      app/adm/model/Property.php
  32. 154 0
      app/adm/model/Seal.php
  33. 34 0
      app/adm/validate/BasicAdmCheck.php
  34. 43 0
      app/adm/validate/CarValidate.php
  35. 35 0
      app/adm/validate/CateCheck.php
  36. 57 0
      app/adm/validate/FlowCateCheck.php
  37. 34 0
      app/adm/validate/FlowCheck.php
  38. 35 0
      app/adm/validate/MeetingCateCheck.php
  39. 43 0
      app/adm/validate/NewsValidate.php
  40. 43 0
      app/adm/validate/NoteValidate.php
  41. 43 0
      app/adm/validate/NotecateValidate.php
  42. 35 0
      app/adm/validate/PropertyCheck.php
  43. 35 0
      app/adm/validate/SealCateCheck.php
  44. 138 0
      app/adm/view/basic/datalist.html
  45. 120 0
      app/adm/view/car/add.html
  46. 110 0
      app/adm/view/car/datalist.html
  47. 126 0
      app/adm/view/car/edit.html
  48. 111 0
      app/adm/view/car/fee_add.html
  49. 95 0
      app/adm/view/car/fee_edit.html
  50. 94 0
      app/adm/view/car/fee_list.html
  51. 56 0
      app/adm/view/car/fee_view.html
  52. 95 0
      app/adm/view/car/protect_add.html
  53. 84 0
      app/adm/view/car/protect_edit.html
  54. 84 0
      app/adm/view/car/protect_list.html
  55. 52 0
      app/adm/view/car/protect_view.html
  56. 95 0
      app/adm/view/car/repair_add.html
  57. 84 0
      app/adm/view/car/repair_edit.html
  58. 84 0
      app/adm/view/car/repair_list.html
  59. 52 0
      app/adm/view/car/repair_view.html
  60. 390 0
      app/adm/view/car/view.html
  61. 373 0
      app/adm/view/flow/add.html
  62. 265 0
      app/adm/view/flow/cate_add.html
  63. 111 0
      app/adm/view/flow/catelist.html
  64. 113 0
      app/adm/view/flow/datalist.html
  65. 54 0
      app/adm/view/flow/module_add.html
  66. 92 0
      app/adm/view/flow/modulelist.html
  67. 513 0
      app/adm/view/flow/table.html
  68. 141 0
      app/adm/view/flow/work_flow.html
  69. 103 0
      app/adm/view/meeting/add.html
  70. 100 0
      app/adm/view/meeting/datalist.html
  71. 128 0
      app/adm/view/meeting/records.html
  72. 106 0
      app/adm/view/meeting/records_add.html
  73. 107 0
      app/adm/view/meeting/records_edit.html
  74. 67 0
      app/adm/view/meeting/records_view.html
  75. 114 0
      app/adm/view/meeting/room.html
  76. 71 0
      app/adm/view/meeting/room_add.html
  77. 72 0
      app/adm/view/meeting/room_edit.html
  78. 157 0
      app/adm/view/meeting/room_use.html
  79. 44 0
      app/adm/view/meeting/room_view.html
  80. 52 0
      app/adm/view/meeting/view.html
  81. 94 0
      app/adm/view/news/add.html
  82. 86 0
      app/adm/view/news/datalist.html
  83. 63 0
      app/adm/view/news/view.html
  84. 124 0
      app/adm/view/note/add.html
  85. 103 0
      app/adm/view/note/datalist.html
  86. 67 0
      app/adm/view/note/view.html
  87. 49 0
      app/adm/view/notecate/add.html
  88. 124 0
      app/adm/view/notecate/datalist.html
  89. 16 0
      app/adm/view/notecate/view.html
  90. 130 0
      app/adm/view/official/add.html
  91. 147 0
      app/adm/view/official/datalist.html
  92. 128 0
      app/adm/view/official/edit.html
  93. 64 0
      app/adm/view/official/pending.html
  94. 64 0
      app/adm/view/official/reviewed.html
  95. 110 0
      app/adm/view/official/view.html
  96. 184 0
      app/adm/view/property/add.html
  97. 164 0
      app/adm/view/property/datalist.html
  98. 190 0
      app/adm/view/property/edit.html
  99. 87 0
      app/adm/view/property/repair_add.html
  100. 0 0
      app/adm/view/property/repair_edit.html

+ 22 - 0
.gitignore

@@ -0,0 +1,22 @@
+# 系统文件
+.DS_Store
+Thumbs.db
+
+# IDE / 编辑器
+.idea
+.vscode
+*.swp
+*.swo
+
+# Composer 依赖
+/vendor/
+
+# 运行时缓存
+/runtime/
+
+# 环境配置
+.env
+*.env
+
+# 日志文件
+*.log

+ 14 - 0
DISCLAIMER.md

@@ -0,0 +1,14 @@
+# 勾股OA 《免责声明》
+
+> 任何用户在使用由勾股技术开发团队(以下简称「本团队」)研发的开源OA办公系统(以下简称「勾股OA」)前,请您仔细阅读并透彻理解本声明。您可以选择不使用勾股OA ,若您一旦使用勾股OA ,您的使用行为即被视为对本声明全部内容的认可和接受。
+
+1. 勾股OA是一款基于ThinkPHP + Layui + MySql打造的实用的开源的企业办公系统,本软件及所附带的文件是作为不提供任何明确的或隐含的赔偿或担保的形式提供的。
+2. 您是出于自愿而使用勾股OA的,您必须了解使用勾股OA的风险,本团队不承诺提供任何形式的技术支持、使用担保,也不承担任何因使用本软件而产生问题的相关责任。
+3. 您承诺秉着合法、合理的原则使用勾股OA,不利用勾股OA进行任何违法、侵害他人合法利益等恶意的行为,亦不将勾股OA运用于任何违反我国法律法规的Web平台。
+4. 任何单位或个人因下载使用勾股OA而产生的任何意外、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、附带或衍生的损失等),本团队不承担任何法律责任。
+5. 用户明确并同意本声明条款列举的全部内容,对使用勾股OA可能存在的风险和相关后果将完全由用户自行承担,本团队不承担任何法律责任。
+6. 任何单位或个人在阅读本免责声明后,应在《Apache License 2.0》所允许的范围内进行合法的发布、传播和使用勾股OA等行为,若违反本免责声明条款或违反法律法规所造成的法律责任(包括但不限于民事赔偿和刑事责任),由违约者自行承担。
+7. 本团队对勾股OA拥有知识产权(包括但不限于商标权、专利权、著作权、商业秘密等)。
+8. 任何单位或个人不得在未经本团队书面授权的情况下对勾股OA本身申请相关的知识产权。
+9. 如果本声明的任何部分被认为无效或不可执行,则该部分将被解释为反映本团队的初衷,其余部分仍具有完全效力。不可执行的部分声明,并不构成我们放弃执行该声明的权利。
+10. 本团队有权随时对本声明条款及附件内容进行单方面的变更,并以消息推送、网页公告等方式予以公布,公布后立即自动生效,无需另行单独通知;若您在本声明内容公告变更后继续使用的,表示您已充分阅读、理解并接受修改后的声明内容。

+ 201 - 0
LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2025 勾股开源工作室
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 37 - 0
LICENSE.txt

@@ -0,0 +1,37 @@
+
+ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
+版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
+All rights reserved。
+ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
+
+Apache Licence是著名的非盈利开源组织Apache采用的协议。
+该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
+允许代码修改,再作为开源或商业软件发布。需要满足
+的条件: 
+1. 需要给代码的用户一份Apache Licence ;
+2. 如果你修改了代码,需要在被修改的文件中说明;
+3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
+带有原来代码中的协议,商标,专利声明和其他原来作者规
+定需要包含的说明;
+4. 如果再发布的产品中包含一个Notice文件,则在Notice文
+件中需要带有本协议内容。你可以在Notice中增加自己的
+许可,但不可以表现为对Apache Licence构成更改。 
+具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+勾股OA遵循Apache2开源协议发布,并提供免费使用。
+版权所有Copyright © 2021-2025 by gouguCMS (https://www.gougucms.com)
+All rights reserved。

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 201 - 0
README.md


+ 18 - 0
app/adm/common.php

@@ -0,0 +1,18 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+/**
+======================
+ *模块数据获取公共文件
+======================
+ */
+use think\facade\Db;

+ 173 - 0
app/adm/controller/Api.php

@@ -0,0 +1,173 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+declare (strict_types = 1);
+namespace app\adm\controller;
+
+use app\api\BaseController;
+use app\adm\model\Property;
+use app\adm\model\Car;
+use think\facade\Db;
+use think\facade\View;
+
+class Api extends BaseController
+{	
+	public function get_propertycate()
+	{
+        $cate = get_base_data('PropertyCate');
+        return to_assign(0, '', $cate);
+    }
+	
+    public function get_propertycate_tree()
+    {
+        $cate = get_base_data('PropertyCate');
+        $list = get_tree($cate, 0, 2);
+        $data['trees'] = $list;
+        return json($data);
+    }
+	//获取资产数据
+	public function get_property()
+    {
+		$param = get_params();
+		$where = array();
+		if (!empty($param['keywords'])) {
+			$where[] = ['p.title', 'like', '%' . $param['keywords'] . '%'];
+		}
+		$where[] = ['p.status', '=', 1];
+        $rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$model = new Property();
+		$list = $model->datalist($where, $param);
+		return table_assign(0, '', $list);
+    }
+	
+	//获取车辆信息
+	public function get_car()
+    {
+		$param = get_params();
+		$where = array();
+		if (!empty($param['keywords'])) {
+			$where[] = ['title|name', 'like', '%' . $param['keywords'] . '%'];
+		}
+		$where[] = ['delete_time', '=', 0];
+        $rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$model = new Car();
+		$list = $model->datalist($where, $param);
+		return table_assign(0, '', $list);
+    }
+	
+	//获取车辆维修信息
+	public function get_car_repair()
+    {
+		$param = get_params();
+		$where = array();
+		$where[] = ['cr.car_id','=',$param['car_id']];
+		$where[] = ['cr.types','=',1];
+		$where[] = ['cr.delete_time','=',0];
+		$model = new Car();
+		$list = $model->repairlist($where, $param);
+		return table_assign(0, '', $list);
+    }
+	//获取车辆保养信息
+	public function get_car_protect()
+    {
+		$param = get_params();
+		$where = array();
+		$where[] = ['cr.car_id','=',$param['car_id']];
+		$where[] = ['cr.types','=',2];
+		$where[] = ['cr.delete_time','=',0];
+		$model = new Car();
+		$list = $model->repairlist($where, $param);
+		return table_assign(0, '', $list);
+    }
+	
+	//获取车辆费用信息
+	public function get_car_fee()
+    {
+		$param = get_params();
+		$where = array();
+		$where[] = ['cf.car_id','=',$param['car_id']];
+		$where[] = ['cf.delete_time','=',0];
+		$model = new Car();
+		$list = $model->feelist($where, $param);
+		return table_assign(0, '', $list);
+    }
+	
+	//获取车辆费用信息
+	public function get_car_mileage()
+    {
+		$param = get_params();
+		$where = array();
+		$where[] = ['car_id','=',$param['car_id']];
+		$where[] = ['delete_time','=',0];
+		$model = new Car();
+		$list = $model->mileagelist($where, $param);
+		return table_assign(0, '', $list);
+    }
+	
+	//获取会议室
+    public function get_meeting_room()
+    {
+		$list = Db::name('MeetingRoom')->where('status',1)->paginate(['list_rows'=> 20]);
+        return table_assign(0, '', $list);
+    }
+	
+	//获取审核类型
+    public function get_flow_item()
+    {
+        $param = get_params();
+		$flows = Db::name('FlowItem')->where(['flow_cate'=>$param['cate'],'status'=>1])->select()->toArray();
+		return to_assign(0, '', $flows);
+	} 
+
+	//修改公章状态
+    public function set_seal_status()
+    {
+		$param = get_params();
+		$res = Db::name('Seal')->where(['id'=>$param['id']])->update(['status'=>$param['status']]);
+		if($res!==false){
+			return to_assign();
+		}
+		else{
+			return to_assign(1, '操作失败');
+		}
+	} 
+
+	//测试demo
+	public function work_flow()
+    {
+		return view('/flow/work_flow');
+	}
+	
+    public function table()
+    {
+        $param = get_params();
+		$prefix = config('database.connections.mysql.prefix');
+		//查询指定表信息
+        $table_info = Db::query('SHOW TABLE STATUS LIKE ' . "'" .$prefix.$param['name'] . "'");
+		if(empty($table_info)){
+			return view(EEEOR_REPORTING,['code'=>406,'warning'=>'找不到该数据表']);
+		}
+		$table_columns = Db::query("SHOW FULL COLUMNS FROM " .$prefix.$param['name']);
+		$columns=[];
+		foreach($table_columns as $key=>$val) {
+			if (strpos($val['Type'], 'int') !== false || strpos($val['Type'], 'decimal') !== false) {
+				$columns[]=$val;
+			}
+		}
+		//var_dump($table_info);exit;
+		//dd($table_columns);exit;
+		View::assign('id', 0);
+		View::assign('columns', $columns);
+		return view('/flow/table');
+    }
+}

+ 93 - 0
app/adm/controller/Basic.php

@@ -0,0 +1,93 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\validate\BasicAdmCheck;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Basic extends BaseController
+{	
+	public function datalist()
+    {
+        if (request()->isAjax()) {
+			$param = get_params();
+			$where=[];
+			if (!empty($param['types'])) {
+                $where[] = ['types', '=', $param['types']];
+            }
+            $list = Db::name('BasicAdm')->where($where)->order('create_time asc')->select();
+            return to_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+    //新建编辑
+    public function add()
+    {
+        if (request()->isAjax()) {
+            $param = get_params();
+            if (!empty($param['id']) && $param['id'] > 0) {
+                try {
+                    validate(BasicAdmCheck::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['update_time'] = time();
+                $res = Db::name('BasicAdm')->strict(false)->field('title,types,id,update_time')->update($param);
+                if ($res) {
+                    add_log('edit', $param['id'], $param);
+                }
+                return to_assign();
+            } else {
+                try {
+                    validate(BasicAdmCheck::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['create_time'] = time();
+                $insertId = Db::name('BasicAdm')->strict(false)->field('title,types,id,create_time')->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        }
+    }
+	
+    //设置
+    public function set()
+    {
+		$param = get_params();
+        $res = Db::name('BasicAdm')->strict(false)->field('id,status')->update($param);
+		if ($res) {
+			if($param['status'] == 0){
+				add_log('disable', $param['id'], $param);
+			}
+			else if($param['status'] == 1){
+				add_log('recovery', $param['id'], $param);
+			}
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }   
+}

+ 501 - 0
app/adm/controller/Car.php

@@ -0,0 +1,501 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+ 
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\model\Car as CarModel;
+use app\adm\validate\CarValidate;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Car extends BaseController
+{
+	/**
+     * 构造函数
+     */
+	protected $model;
+    public function __construct()
+    {
+		parent::__construct(); // 调用父类构造函数
+        $this->model = new CarModel();
+    }
+	
+    /**
+    * 数据列表
+    */
+    public function datalist()
+    {
+		$param = get_params();
+        if (request()->isAjax()) {
+			$where=[];
+			$where[]=['delete_time','=',0];
+            if (!empty($param['keywords'])) {
+                $where[] = ['id|title', 'like', '%' . $param['keywords'] . '%'];
+            }
+            $list = $this->model->datalist($where, $param);
+            return table_assign(0, '', $list);
+        }
+        else{
+            return view();
+        }
+    }
+	
+    /**
+    * 添加/编辑
+    */
+    public function add()
+    {
+		$param = get_params();	
+        if (request()->isAjax()) {
+			if (isset($param['insure_time'])) {
+                $param['insure_time'] = strtotime($param['insure_time']);
+            }
+			if (isset($param['review_time'])) {
+                $param['review_time'] = strtotime($param['review_time']);
+            }	
+			if (isset($param['buy_time'])) {
+                $param['buy_time'] = strtotime($param['buy_time']);
+            }			
+            if (!empty($param['id']) && $param['id'] > 0) {
+                try {
+                    validate(CarValidate::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+				$this->model->edit($param);
+            } else {
+                try {
+                    validate(CarValidate::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $this->model->add($param);
+            }	 
+        }else{
+			$id = isset($param['id']) ? $param['id'] : 0;
+			if ($id>0) {
+				$detail = $this->model->getById($id);
+				if(!empty($detail['file_ids'])){
+					$file_array = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+					$detail['file_array'] = $file_array;
+				}
+				if($detail['driver']>0){
+					$detail['driver_name'] = Db::name('Admin')->where('id','=',$detail['driver'])->value('name');
+				}
+                View::assign('detail', $detail);
+				return view('edit');
+			}
+			return view();
+		}
+    }
+	
+    /**
+    * 查看
+    */
+    public function view($id)
+    {
+		$detail = $this->model->getById($id);
+		if (!empty($detail)) {
+			if(!empty($detail['file_ids'])){
+				$file_array = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+				$detail['file_array'] = $file_array;
+			}
+			if($detail['driver']>0){
+				$detail['driver_name'] = Db::name('Admin')->where('id','=',$detail['driver'])->value('name');
+			}
+			$latestMileage = Db::name('CarMileage')->where(['car_id'=>$detail['id'],'delete_time'=>0])->max('mileage');
+			if(empty($latestMileage)){
+				$latestMileage = $detail['mileage'];
+			}
+			$detail['latestMileage'] = $latestMileage;
+			View::assign('detail', $detail);
+			return view();
+		}
+		else{
+			return view(EEEOR_REPORTING,['warning'=>'找不到页面']);
+		}
+    }
+	
+   /**
+    * 删除
+    */
+    public function del()
+    {
+		$param = get_params();
+		$id = isset($param['id']) ? $param['id'] : 0;
+		if (request()->isDelete()) {
+			$this->model->delById($id);
+		} else {
+            return to_assign(1, "错误的请求");
+        }
+    }  
+	
+	//维修记录列表
+    public function repair_list()
+    {
+        if (request()->isAjax()) {
+			$param = get_params();
+			$where = [];
+			if (!empty($param['keywords'])) {
+                $where[] = ['c.title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			if (!empty($param['diff_time'])) {
+				$diff_time =explode('~', $param['diff_time']);
+                $where[] = ['cr.repair_time', 'between', [strtotime(urldecode($diff_time[0])),strtotime(urldecode($diff_time[1]))]];
+            }
+			$where[] = ['cr.types','=',1];
+			$where[] = ['cr.delete_time','=',0];
+            $model = new Car();
+			$list = $this->model->repairlist($where, $param);
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+	
+    //维修记录添加&编辑
+    public function repair_add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+			if (isset($param['repair_time'])) {
+                $param['repair_time'] = strtotime($param['repair_time']);
+            }
+            if (!empty($param['id']) && $param['id'] > 0) {
+                $param['update_time'] = time();
+				$res = Db::name('CarRepair')->strict(false)->field(true)->update($param);
+				if($res){
+					add_log('edit', $param['id'], $param);
+					return to_assign();
+				}
+            } else {
+                $param['create_time'] = time();
+                $insertId = Db::name('CarRepair')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            $cid = isset($param['cid']) ? $param['cid'] : 0;
+            if ($id > 0) {
+                $detail = Db::name('CarRepair')->where(['id' => $id])->find();
+                $detail['handled_name'] = Db::name('Admin')->where('id',$detail['handled'])->value('name');
+                $detail['car'] = Db::name('Car')->where('id',$detail['car_id'])->value('title');
+				if($detail['file_ids'] !=''){
+					$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+					$detail['fileArray'] = $fileArray;
+				}
+                View::assign('detail', $detail);
+				return view('repair_edit');
+            }
+			if($cid>0){
+				View::assign('car', $this->model->getById($cid));
+			}
+            View::assign('cid', $cid);
+            View::assign('id', $id);
+            return view();
+        }
+    }
+	
+    //维修记录查看
+    public function repair_view()
+    {
+        $param = get_params();
+        $id = isset($param['id']) ? $param['id'] : 0;
+		$detail = Db::name('CarRepair')->where(['id' => $id])->find();
+		$detail['handled_name'] = Db::name('Admin')->where('id',$detail['handled'])->value('name');
+        $detail['car'] = Db::name('Car')->where('id',$detail['car_id'])->value('title');
+		if($detail['file_ids'] !=''){
+			$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+			$detail['fileArray'] = $fileArray;
+		}
+		View::assign('detail', $detail);
+        return view();
+    }
+	
+     //维修记录删除
+    public function repair_del()
+    {
+		$param = get_params();
+        $res = Db::name('CarRepair')->where('id',$param['id'])->update(['delete_time'=>time()]);
+		if ($res) {
+			add_log('delete', $param['id'], $param);
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }  
+	
+	
+	//保养记录列表
+    public function protect_list()
+    {
+        if (request()->isAjax()) {
+			$param = get_params();
+			$where = [];
+			if (!empty($param['keywords'])) {
+                $where[] = ['c.title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			if (!empty($param['diff_time'])) {
+				$diff_time =explode('~', $param['diff_time']);
+                $where[] = ['cr.repair_time', 'between', [strtotime(urldecode($diff_time[0])),strtotime(urldecode($diff_time[1]))]];
+            }
+			$where[] = ['cr.types','=',2];
+			$where[] = ['cr.delete_time','=',0];
+			$list = $this->model->repairlist($where, $param);
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+	
+    //保养记录添加&编辑
+    public function protect_add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+			if (isset($param['repair_time'])) {
+                $param['repair_time'] = strtotime($param['repair_time']);
+            }
+            if (!empty($param['id']) && $param['id'] > 0) {
+                $param['update_time'] = time();
+				$res = Db::name('CarRepair')->strict(false)->field(true)->update($param);
+				if($res){
+					add_log('edit', $param['id'], $param);
+					return to_assign();
+				}
+            } else {
+                $param['create_time'] = time();
+                $param['types'] = 2;
+                $insertId = Db::name('CarRepair')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            $cid = isset($param['cid']) ? $param['cid'] : 0;
+            if ($id > 0) {
+                $detail = Db::name('CarRepair')->where(['id' => $id])->find();
+                $detail['handled_name'] = Db::name('Admin')->where('id',$detail['handled'])->value('name');
+                $detail['car'] = Db::name('Car')->where('id',$detail['car_id'])->value('title');
+				if($detail['file_ids'] !=''){
+					$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+					$detail['fileArray'] = $fileArray;
+				}
+                View::assign('detail', $detail);
+				return view('protect_edit');
+            }
+			if($cid>0){
+				View::assign('car', $this->model->getById($cid));
+			}
+            View::assign('cid', $cid);
+            View::assign('id', $id);
+            return view();
+        }
+    }
+	
+    //保养记录查看
+    public function protect_view()
+    {
+        $param = get_params();
+        $id = isset($param['id']) ? $param['id'] : 0;
+		$detail = Db::name('CarRepair')->where(['id' => $id])->find();
+		$detail['handled_name'] = Db::name('Admin')->where('id',$detail['handled'])->value('name');
+        $detail['car'] = Db::name('Car')->where('id',$detail['car_id'])->value('title');
+		if($detail['file_ids'] !=''){
+			$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+			$detail['fileArray'] = $fileArray;
+		}
+		View::assign('detail', $detail);
+        return view();
+    }
+	
+     //保养记录删除
+    public function protect_del()
+    {
+		$param = get_params();
+        $res = Db::name('CarRepair')->where('id',$param['id'])->update(['delete_time'=>time()]);
+		if ($res) {
+			add_log('delete', $param['id'], $param);
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }  
+	
+	//费用记录列表
+    public function fee_list()
+    {
+        if (request()->isAjax()) {
+			$param = get_params();
+			$where = [];
+			if (!empty($param['keywords'])) {
+                $where[] = ['cf.title|c.title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			if (!empty($param['diff_time'])) {
+				$diff_time =explode('~', $param['diff_time']);
+                $where[] = ['cf.fee_time', 'between', [strtotime(urldecode($diff_time[0])),strtotime(urldecode($diff_time[1]))]];
+            }
+			if (!empty($param['types'])) {
+                $where[] = ['cf.types','=',$param['types']];
+            }
+			$where[] = ['cf.delete_time','=',0];
+			$list = $this->model->feelist($where, $param);
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+	
+    //费用记录添加&编辑
+    public function fee_add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+			if (isset($param['fee_time'])) {
+                $param['fee_time'] = strtotime($param['fee_time']);
+            }
+            if (!empty($param['id']) && $param['id'] > 0) {
+                $param['update_time'] = time();
+				$res = Db::name('CarFee')->strict(false)->field(true)->update($param);
+				if($res){
+					add_log('edit', $param['id'], $param);
+					return to_assign();
+				}
+            } else {
+                $param['create_time'] = time();
+                $insertId = Db::name('CarFee')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            $cid = isset($param['cid']) ? $param['cid'] : 0;
+            if ($id > 0) {
+                $detail = Db::name('CarFee')->where(['id' => $id])->find();
+                $detail['handled_name'] = Db::name('Admin')->where('id',$detail['handled'])->value('name');
+                $detail['car'] = Db::name('Car')->where('id',$detail['car_id'])->value('title');
+				if($detail['file_ids'] !=''){
+					$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+					$detail['fileArray'] = $fileArray;
+				}
+                View::assign('detail', $detail);
+				return view('fee_edit');
+            }
+			if($cid>0){
+				View::assign('car', $this->model->getById($cid));
+			}
+            View::assign('cid', $cid);
+            View::assign('id', $id);
+            return view();
+        }
+    }
+	
+    //费用记录查看
+    public function fee_view()
+    {
+        $param = get_params();
+        $id = isset($param['id']) ? $param['id'] : 0;
+		$detail = Db::name('CarFee')->where(['id' => $id])->find();
+		$detail['handled_name'] = Db::name('Admin')->where('id',$detail['handled'])->value('name');
+        $detail['car'] = Db::name('Car')->where('id',$detail['car_id'])->value('title');
+        $detail['types_str'] = Db::name('basicAdm')->where('id',$detail['types'])->value('title');
+		if($detail['file_ids'] !=''){
+			$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+			$detail['fileArray'] = $fileArray;
+		}
+		View::assign('detail', $detail);
+        return view();
+    }
+	
+    //费用记录删除
+    public function fee_del()
+    {
+		$param = get_params();
+        $res = Db::name('CarFee')->where('id',$param['id'])->update(['delete_time'=>time()]);
+		if ($res) {
+			add_log('delete', $param['id'], $param);
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }  
+	
+	//获取里程数记录
+	public function mileage_list()
+    {
+        $param = get_params();
+		$where = array();
+		$where[] = ['car_id', '=', $param['car_id']];
+		$where[] = ['delete_time', '=', 0];
+		$this->model->mileagelist($where, $param);
+        table_assign(0, '', $list);
+    }
+	
+	//增加里程数记录
+	public function mileage_add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+			if (isset($param['mileage_time'])) {
+                $param['mileage_time'] = strtotime($param['mileage_time']);
+            }
+			$latestMileage = Db::name('CarMileage')->where([['id','<>',$param['id']],['car_id','=',$param['car_id']],['delete_time','=',0]])->order('mileage_time', 'desc')->value('mileage');
+			$mileage = Db::name('Car')->where('id',$param['car_id'])->value('mileage');
+			if(empty($latestMileage)){
+				$latestMileage = $mileage;
+			}
+			if($param['mileage'] < $latestMileage){
+				 return to_assign(1,'新增的里程数,不能小于现有里程数');
+			}
+            if (!empty($param['id']) && $param['id'] > 0) {
+                $param['update_time'] = time();
+                $res = Db::name('CarMileage')->strict(false)->field(true)->update($param);
+                return to_assign();
+            } else {
+                $param['create_time'] = time();
+                $param['admin_id'] = $this->uid;
+                $insertId = Db::name('CarMileage')->strict(false)->field(true)->insertGetId($param);
+                return to_assign();
+            }
+        }
+    }
+	
+    //里程数记录删除
+    public function mileage_del()
+    {
+		$param = get_params();
+        $res = Db::name('CarMileage')->where('id',$param['id'])->update(['delete_time'=>time()]);
+		if ($res) {
+			return to_assign();
+		}
+		else{
+			return to_assign(1, '操作失败');
+		}
+    }  
+}

+ 353 - 0
app/adm/controller/Flow.php

@@ -0,0 +1,353 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\validate\FlowCateCheck;
+use app\adm\validate\FlowCheck;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Flow extends BaseController
+{	
+
+    public function datalist()
+    {
+        if (request()->isAjax()) {
+			$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+			$list = Db::name('Flow')
+				->field('f.*,fc.title as cate,fm.title as module')
+				->alias('f')
+                ->join('FlowCate fc', 'fc.id = f.cate_id', 'left')
+                ->join('FlowModule fm', 'fm.id = fc.module_id', 'left')
+				->order('id desc')->paginate(['list_rows'=> $rows])
+				->each(function($item, $key){
+					if(!empty($item['department_ids'])){
+						$item['departments']=get_department_name($item['department_ids']);
+					}
+					else{
+						$item['departments']='全部';
+					}
+					if(!empty($item['copy_uids'])){
+						$copy_unames=Db::name('Admin')->where([['status','=',1],['id','in',$item['copy_uids']]])->column('name');
+						$item['copy_unames']=implode(',',$copy_unames);
+					}
+					else{
+						$item['copy_unames']='-';
+					}
+					return $item;
+				});
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+
+    //添加新增/编辑
+    public function add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+			$param['flow_list'] = '';
+			$flow_list=[];
+			//固定审批流
+			if($param['check_type']==2){
+				$roleData = isset($param['check_role']) ? $param['check_role'] : '';
+				$positionIdData = isset($param['check_position_id']) ? $param['check_position_id'] : '';
+				$checkUidsData = isset($param['check_uids_a']) ? $param['check_uids_a'] : '';
+				$checkTypesData = isset($param['check_types']) ? $param['check_types'] : '';
+				foreach ($roleData as $key => $value) {
+					if (!$value) {
+						continue;
+					}
+					if($value==3 && $positionIdData[$key]==''){
+						return to_assign(1, '第'.($key+1).'行的指定岗位职称未选择');
+						break;
+					}
+					if($value>3 && $checkUidsData[$key]==''){
+						return to_assign(1, '第'.($key+1).'行的指定人未选择');
+						break;
+					}
+					$item = [];
+					$item['check_role'] = $value;
+					$item['check_position_id'] = $positionIdData[$key];
+					$item['check_uids'] = $checkUidsData[$key];
+					$item['check_types'] = $checkTypesData[$key];
+					$flow_list[]=$item;	
+				}
+				$param['flow_list'] = serialize($flow_list);
+			}
+			//可回退审批流
+			if($param['check_type']==3){
+				$flowNameData = isset($param['flow_name']) ? $param['flow_name'] : '';
+				$checkUidsData = isset($param['check_uids_b']) ? $param['check_uids_b'] : '';
+				foreach ($flowNameData as $key => $value) {
+					if (!$value) {
+						continue;
+					}
+					if($checkUidsData[$key]==''){
+						return to_assign(1, '第'.($key+1).'行的指定人未选择');
+						break;
+					}
+					$item = [];
+					$item['check_role'] = 5;
+					$item['flow_name'] = $value;
+					$item['check_uids'] = $checkUidsData[$key];
+					$flow_list[]=$item;	
+				}
+				if(empty($flow_list)){
+					return to_assign(1, '审批流程信息未完善');
+				}
+				$param['flow_list'] = serialize($flow_list);
+			}
+			
+            if ($param['id'] > 0) {
+                try {
+                    validate(FlowCheck::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['update_time'] = time();
+                Db::name('Flow')->strict(false)->field(true)->update($param);
+                add_log('edit', $param['id'], $param);
+            } else {
+                try {
+                    validate(FlowCheck::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['admin_id'] = $this->uid;
+                $param['create_time'] = time();
+                $mid = Db::name('Flow')->strict(false)->field(true)->insertGetId($param);
+                add_log('add', $mid, $param);
+            }
+            return to_assign();
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            $check_type = 1;
+            if($id>0){
+                $detail = Db::name('Flow')->where('id',$id)->find();
+                $flow_list = unserialize($detail['flow_list']);
+				if(!empty($flow_list)){
+					foreach ($flow_list as $key => &$val) {
+						$val['check_unames'] ='';
+						$val['check_position_title'] ='';
+						if($val['check_role']==3){
+							$val['check_position_title'] = Db::name('Position')->where('id', '=', $val['check_position_id'])->value('title');
+						}
+						if($val['check_role']>3){
+							$check_unames = Db::name('Admin')->where('id', 'in', $val['check_uids'])->column('name');
+							$val['check_unames'] = implode(',', $check_unames);
+						}
+					}
+				}
+				$detail['flow_list'] = $flow_list;
+				$detail['copy_unames'] ='';
+				if($detail['copy_uids']!=''){
+					$copy_unames = Db::name('Admin')->where('id', 'in', $detail['copy_uids'])->column('name');
+					$detail['copy_unames'] = implode(',', $copy_unames);
+				}
+				$check_type = $detail['check_type'];
+				//var_dump($flow_list);exit;
+                View::assign('detail', $detail);
+            }
+            View::assign('check_type', $check_type);
+            View::assign('id', $id);
+            return view();
+        }
+    }
+
+    //禁用/启用
+    public function check()
+    {
+        $param = get_params();
+		$param['update_time']= time();
+		$res = Db::name('Flow')->strict(false)->field('status,update_time')->update($param);
+		if($res!==false){
+			if($param['status'] == 0){
+				add_log('disable', $param['id'], $param);
+			}
+			else if($param['status'] == 1){
+				add_log('recovery', $param['id'], $param);
+			}
+			return to_assign();
+		}
+		else{
+			return to_assign(1,'操作失败');
+		}
+    }
+	//审批模块
+    public function modulelist()
+    {
+        if (request()->isAjax()) {
+			$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+			$list = Db::name('FlowModule')
+				->order('sort desc,id desc')
+				->paginate(['list_rows'=> $rows]);
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+    //添加模块
+    public function module_add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+            if (!empty($param['id']) && $param['id'] > 0) {
+                $param['update_time'] = time();
+                $res = Db::name('FlowModule')->strict(false)->field(true)->update($param);
+                if ($res) {
+                    add_log('edit', $param['id'], $param);
+                }
+                return to_assign();
+            } else {
+                $param['create_time'] = time();
+                $insertId = Db::name('FlowModule')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        }else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            if ($id > 0) {
+                $detail = Db::name('FlowModule')->find($id);
+                View::assign('detail', $detail);
+            }
+            View::assign('id', $id);
+            return view();
+        }
+    }
+	
+    //设置
+    public function module_check()
+    {
+		$param = get_params();
+        $res = Db::name('FlowModule')->strict(false)->field('id,status')->update($param);
+		if ($res) {
+			if($param['status'] == 0){
+				add_log('disable', $param['id'], $param);
+			}
+			else if($param['status'] == 1){
+				add_log('recovery', $param['id'], $param);
+			}
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }   
+	
+	//审批类型列表
+    public function catelist()
+    {
+        if (request()->isAjax()) {
+			$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+			$list = Db::name('FlowCate')
+				->field('fc.*,fm.title as module')
+				->alias('fc')
+				->join('FlowModule fm', 'fm.id = fc.module_id', 'left')
+				->order('fc.sort desc,fc.id desc')
+				->paginate(['list_rows'=> $rows])
+				->each(function($item, $key){
+					if(!empty($item['department_ids'])){
+						$item['departments']=get_department_name($item['department_ids']);
+					}
+					else{
+						$item['departments']='全部';
+					}
+					return $item;
+				});
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+    //添加审批类型
+    public function cate_add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+            if (!empty($param['id']) && $param['id'] > 0) {
+                try {
+                    validate(FlowCateCheck::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['update_time'] = time();
+                $res = Db::name('FlowCate')->strict(false)->field(true)->update($param);
+                if ($res) {
+                    add_log('edit', $param['id'], $param);
+                }
+                return to_assign();
+            } else {
+                try {
+                    validate(FlowCateCheck::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['create_time'] = time();
+                $insertId = Db::name('FlowCate')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        }else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            if ($id > 0) {
+                $detail = Db::name('FlowCate')->find($id);
+				if(!empty($detail['department_ids'])){
+					$detail['departments']=get_department_name($detail['department_ids']);
+				}
+				else{
+					$detail['departments']='全部';
+				}
+				if($detail['template_id']>0){
+					$detail['template_title'] = Db::name('Template')->where('id',$detail['template_id'])->value('title');
+				}
+                View::assign('detail', $detail);
+            }
+            View::assign('id', $id);
+            return view();
+        }
+    }
+	
+    //审批类型设置
+    public function cate_check()
+    {
+		$param = get_params();
+        $res = Db::name('FlowCate')->strict(false)->field('id,status')->update($param);
+		if ($res) {
+			if($param['status'] == 0){
+				add_log('disable', $param['id'], $param);
+			}
+			else if($param['status'] == 1){
+				add_log('recovery', $param['id'], $param);
+			}
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }   
+}

+ 373 - 0
app/adm/controller/Meeting.php

@@ -0,0 +1,373 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\model\MeetingRecords as MeetingRecordsModel;
+use app\adm\model\MeetingOrder;
+use schedule\Schedule as ScheduleIndex;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Meeting extends BaseController
+{	
+	protected $model;
+    public function __construct()
+    {
+		parent::__construct(); // 调用父类构造函数
+        $this->model = new MeetingRecordsModel();
+    }
+	
+	
+    /**
+    * 预定数据列表
+    */
+    public function datalist()
+    {
+		$param = get_params();
+        if (request()->isAjax()) {
+			$where=[];
+			$whereOr=[];
+			$where[]=['delete_time','=',0];
+            if (!empty($param['keywords'])) {
+                $where[] = ['id|title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			$model = new MeetingOrder();
+            $list = $model->datalist($param,$where,$whereOr);
+            return table_assign(0, '', $list);
+        }
+        else{
+            return view();
+        }
+    }
+	
+    /**
+    * 添加/编辑预定
+    */
+    public function add()
+    {
+		$param = get_params();	
+        if (request()->isAjax()) {
+			$param['start_date'] = strtotime($param['start_date']);
+			$param['end_date'] = strtotime($param['end_date']);
+			if ($param['end_date'] <= $param['start_date']) {
+                return to_assign(1, "结束时间需要大于开始时间");
+            }
+            $where1[] = ['delete_time', '=', 0];
+            $where1[] = ['room_id', '=', $param['room_id']];
+            $where1[] = ['start_date', 'between', [$param['start_date'], $param['end_date'] - 1]];
+
+            $where2[] = ['delete_time', '=', 0];
+            $where2[] = ['room_id', '=', $param['room_id']];
+            $where2[] = ['start_date', '<=', $param['start_date']];
+            $where2[] = ['start_date', '>=', $param['end_date']];
+
+            $where3[] = ['delete_time', '=', 0];
+            $where3[] = ['room_id', '=', $param['room_id']];
+            $where3[] = ['end_date', 'between', [$param['start_date'] + 1, $param['end_date']]];
+
+            $record = Db::name('MeetingOrder')
+                ->where(function ($query) use ($where1) {
+                    $query->where($where1);
+                })
+                ->whereOr(function ($query) use ($where2) {
+                    $query->where($where2);
+                })
+                ->whereOr(function ($query) use ($where3) {
+                    $query->where($where3);
+                })
+                ->count();
+            if ($record > 0) {
+                return to_assign(1, "您所选的时间区间已有预定记录,请重新选时间");
+            }
+			$requirementData = isset($param['requirement']) ? $param['requirement'] : '';
+            $param['requirements'] = implode(',', $requirementData);
+            if (!empty($param['id']) && $param['id'] > 0) {
+				$model = new MeetingOrder();
+				$model->edit($param);
+            } else {
+				$param['admin_id'] = $this->uid;
+				$param['did'] = $this->did;
+				$model = new MeetingOrder();
+                $model->add($param);
+            }	 
+        }else{
+			$id = isset($param['id']) ? $param['id'] : 0;
+			$requirements = get_base_type_data('BasicAdm',2);
+			if ($id>0) {
+				$model = new MeetingOrder();
+				$detail = $model->getById($id);
+				$requirements_array = explode(',', $detail['requirements']);
+				foreach ($requirements as &$val) {
+					if (in_array($val['id'], $requirements_array)) {
+						$val['checked'] = 1;
+					} else {
+						$val['checked'] = 0;
+					}
+				}
+				View::assign('requirements', $requirements);
+				View::assign('detail', $detail);
+			}
+			View::assign('requirements', $requirements);
+			if(is_mobile()){
+				return view('qiye@/approve/add_meeting');
+			}			
+			return view();
+		}
+    }
+	
+    /**
+    * 查看预定
+    */
+    public function view($id)
+    {
+		$model = new MeetingOrder();
+		$detail = $model->getById($id);
+		View::assign('create_user', get_admin($detail['admin_id']));
+		if (!empty($detail)) {
+			View::assign('detail', $detail);
+			if(is_mobile()){
+				return view('qiye@/approve/view_meeting');
+			}
+			return view();
+		}
+		else{
+			return view(EEEOR_REPORTING,['code'=>404,'warning'=>'找不到页面']);
+		}
+    }
+	
+   /**
+    * 删除预定
+    */
+    public function del()
+    {
+		if (request()->isDelete()) {
+			$param = get_params();
+			$id = isset($param['id']) ? $param['id'] : 0;
+			$model = new MeetingOrder();
+			$model->delById($id);
+		} else {
+            return to_assign(1, "错误的请求");
+        }
+    }   
+	
+	
+	
+	//会议室
+    public function room()
+    {
+        if (request()->isAjax()) {
+			$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+			$list = Db::name('MeetingRoom')
+				->field('mr.*,u.name as keep_name')
+				->alias('mr')
+				->join('Admin u', 'u.id = mr.keep_uid', 'left')
+				->paginate(['list_rows'=> $rows]);
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+    //会议室添加
+    public function room_add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+            if (!empty($param['id']) && $param['id'] > 0) {
+                $param['update_time'] = time();
+                $res = Db::name('MeetingRoom')->strict(false)->field(true)->update($param);
+                if ($res) {
+                    add_log('edit', $param['id'], $param);
+                }
+                return to_assign();
+            } else {
+                $param['create_time'] = time();
+                $insertId = Db::name('MeetingRoom')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+		} else {
+			//keep_name
+			$id = isset($param['id']) ? $param['id'] : 0;
+			if ($id>0) {
+				$detail = Db::name('MeetingRoom')->find($id);
+				if($detail['keep_uid']>0){
+					$detail['keep_name'] = Db::name('Admin')->where('id','=',$detail['keep_uid'])->value('name');
+				}
+                View::assign('detail', $detail);
+				return view('room_edit');
+			}
+			return view();
+        }
+    }
+	
+    //会议室查看
+    public function room_view()
+    {
+		$param = get_params();
+		$detail = Db::name('MeetingRoom')->find($param['id']);
+		if($detail['keep_uid']>0){
+			$detail['keep_name'] = Db::name('Admin')->where('id','=',$detail['keep_uid'])->value('name');
+		}
+		View::assign('detail', $detail);
+		return view();
+    }
+	
+	//会议室查看
+    public function room_use()
+    {
+		if (request()->isAjax()) {
+            $param = get_params();
+            $where = [];
+			
+			$where[] = ['start_date','<=',strtotime($param['end'])];
+            $where[] = ['end_date','>=',strtotime($param['start'])];
+            $where[] = ['delete_time', '=', 0];
+            $where[] = ['check_status', '=', 2];
+            $where[] = ['room_id', '=', $param['id']];
+
+            $schedule = Db::name('MeetingOrder')
+            ->where($where)
+            ->field('id,title,start_date,end_date')
+            ->select()->toArray();
+            $events = [];
+            $bg_array=['#ECECEC','#FFD3D3','#F6F6C7','#D7EBFF','#CCEBCC','#E9E9CB'];
+            $border_array=['#CCCCCC','#FF9999','#E8E89B','#99CCFF','#99CC99','#CCCC99'];
+            foreach ($schedule as $k => $v) {
+                $v['backgroundColor'] = $bg_array[3];
+                $v['borderColor'] = $border_array[3];
+                $v['title'] = $v['title'];
+                $v['start'] = date('Y-m-d H:i', $v['start_date']);
+                $v['end'] = date('Y-m-d H:i', $v['end_date']);
+                unset($v['start_date']);
+                unset($v['end_date']);
+                $events[] = $v;
+            }
+            $input_arrays = $events;
+            $range_start = parseDateTime($param['start']);
+            $range_end = parseDateTime($param['end']);
+            $timeZone = null;
+            if (isset($_GET['timeZone'])) {
+                $timeZone = new DateTimeZone($_GET['timeZone']);
+            }
+
+            // Accumulate an output array of event data arrays.
+            $output_arrays = array();
+            foreach ($input_arrays as $array) {
+                // Convert the input array into a useful Event object
+                $event = new ScheduleIndex($array, $timeZone);
+                // If the event is in-bounds, add it to the output
+                if ($event->isWithinDayRange($range_start, $range_end)) {
+                    $output_arrays[] = $event->toArray();
+                }
+            }
+            return json($output_arrays);
+        } else {
+			$param = get_params();
+			$detail = Db::name('MeetingRoom')->find($param['id']);
+			View::assign('detail', $detail);
+			return view();
+		}
+    } 
+	
+    //会议室设置
+    public function room_check()
+    {
+		$param = get_params();
+        $res = Db::name('MeetingRoom')->strict(false)->field('id,status')->update($param);
+		if ($res) {
+			if($param['status'] == 0){
+				add_log('disable', $param['id'], $param);
+			}
+			else if($param['status'] == 1){
+				add_log('recovery', $param['id'], $param);
+			}
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }  
+	
+	//会议纪要
+    public function records()
+    {
+        if (request()->isAjax()) {
+            $param = get_params();
+			$where=[];
+			$whereOr = [];
+			$uid = $this->uid;
+            if (!empty($param['keywords'])) {
+                $where[] = ['title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			if (!empty($param['anchor_id'])) {
+                $where[] = ['anchor_id', '=', $param['anchor_id']];
+            }
+			if (!empty($param['diff_time'])) {
+				$diff_time =explode('~', $param['diff_time']);
+                $where[] = ['meeting_date', 'between', [strtotime(urldecode($diff_time[0])),strtotime(urldecode($diff_time[1].' 23:59:59'))]];
+            }
+            $where[] = ['delete_time', '=', 0];
+			$list = $this->model->datalist($param,$where,$whereOr);
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+
+    //添加会议纪要
+    public function records_add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+            $param['meeting_date'] = isset($param['meeting_date']) ? strtotime(urldecode($param['meeting_date'])) : 0;
+            if (!empty($param['id']) && $param['id'] > 0) {
+               $this->model->edit($param);
+            } else {
+                $param['admin_id'] = $this->uid;
+                $this->model->add($param);
+            }
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            if ($id > 0) {
+                View::assign('detail', $this->model->getById($id));
+				return view('records_edit');
+            }
+            return view();
+        }
+    }
+
+    //查看会议纪要
+    public function records_view($id)
+    {
+		View::assign('detail', $this->model->getById($id));
+        return view();
+    }
+
+    //删除会议纪要
+    public function records_del()
+    {
+		if (request()->isDelete()) {
+			$id = get_params("id");
+			$this->model->delById($id);
+		} else {
+            return to_assign(1, "错误的请求");
+        }
+    }
+}

+ 135 - 0
app/adm/controller/News.php

@@ -0,0 +1,135 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+ 
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\model\News as NewsModel;
+use app\adm\validate\NewsValidate;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class News extends BaseController
+{
+	/**
+     * 构造函数
+     */
+	protected $model;
+    public function __construct()
+    {
+		parent::__construct(); // 调用父类构造函数
+        $this->model = new NewsModel();
+    }
+	
+    /**
+    * 数据列表
+    */
+    public function datalist()
+    {
+		$param = get_params();
+        if (request()->isAjax()) {
+			$where=[];
+			$where[]=['delete_time','=',0];
+            if (!empty($param['keywords'])) {
+                $where[] = ['id|title', 'like', '%' . $param['keywords'] . '%'];
+            }
+            $list = $this->model->datalist($where, $param);
+            return table_assign(0, '', $list);
+        }
+        else{
+            return view();
+        }
+    }
+	
+    /**
+    * 添加/编辑
+    */
+    public function add()
+    {
+		$param = get_params();	
+        if (request()->isAjax()) {		
+            if (!empty($param['id']) && $param['id'] > 0) {
+                try {
+                    validate(NewsValidate::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+				$this->model->edit($param);
+            } else {
+                try {
+                    validate(NewsValidate::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+				$param['admin_id']=$this->uid;
+                $this->model->add($param);
+            }	 
+        }else{
+			$id = isset($param['id']) ? $param['id'] : 0;
+			if ($id>0) {
+				$detail = $this->model->getById($id);
+				if($detail['file_ids'] !=''){
+					$file_array = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+					$detail['file_array'] = $file_array;
+				}
+				View::assign('detail', $detail);
+			}
+			View::assign('id', $id);
+			return view();
+		}
+    }
+	
+    /**
+    * 查看
+    */
+    public function view($id)
+    {
+		$detail = $this->model->getById($id);
+		if (!empty($detail)) {
+			$detail['cate'] = Db::name('NoteCate')->where(['id' => $detail['cate_id']])->value('title');
+			$detail['admin_name'] = Db::name('Admin')->where(['id' => $detail['admin_id']])->value('name');
+			if($detail['file_ids'] !=''){
+				$file_array = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+				$detail['file_array'] = $file_array;
+			}
+			View::assign('detail', $detail);
+			if(is_mobile()){
+				return view('qiye@/index/view_news');
+			}
+			return view();
+		}
+		else{
+			return view(EEEOR_REPORTING,['code'=>404,'warning'=>'找不到页面']);
+		}
+    }
+	
+   /**
+    * 删除
+    */
+    public function del()
+    {
+		$param = get_params();
+		$id = isset($param['id']) ? $param['id'] : 0;
+		if (request()->isDelete()) {
+			$this->model->delById($id);
+		} else {
+            return to_assign(1, "错误的请求");
+        }
+    }   
+
+}

+ 140 - 0
app/adm/controller/Note.php

@@ -0,0 +1,140 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+ 
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\model\Note as NoteModel;
+use app\adm\validate\NoteValidate;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Note extends BaseController
+{
+	/**
+     * 构造函数
+     */
+	protected $model;
+    public function __construct()
+    {
+		parent::__construct(); // 调用父类构造函数
+        $this->model = new NoteModel();
+    }
+	
+    /**
+    * 数据列表
+    */
+    public function datalist()
+    {
+		$param = get_params();
+        if (request()->isAjax()) {
+			$where=[];
+			$where[]=['a.delete_time','=',0];
+            if (!empty($param['keywords'])) {
+                $where[] = ['a.id|a.title', 'like', '%' . $param['keywords'] . '%'];
+            }
+            $list = $this->model->datalist($where, $param);
+            return table_assign(0, '', $list);
+        }
+        else{
+            return view();
+        }
+    }
+	
+    /**
+    * 添加/编辑
+    */
+    public function add()
+    {
+		$param = get_params();	
+        if (request()->isAjax()) {		
+			$param['start_time'] = isset($param['start_time']) ? strtotime(urldecode($param['start_time'])) : 0;
+            $param['end_time'] = isset($param['end_time']) ? strtotime(urldecode($param['end_time'])) : 0;
+            if (!empty($param['id']) && $param['id'] > 0) {
+                try {
+                    validate(NoteValidate::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+				$this->model->edit($param);
+            } else {
+                try {
+                    validate(NoteValidate::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+				$param['admin_id']=$this->uid;
+                $this->model->add($param);
+            }	 
+        }else{
+			$id = isset($param['id']) ? $param['id'] : 0;
+			if ($id>0) {
+				$detail = $this->model->getById($id);
+				if($detail['file_ids'] !=''){
+					$file_array = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+					$detail['file_array'] = $file_array;
+				}
+				View::assign('detail', $detail);
+			}
+			View::assign('id', $id);
+			if(is_mobile()){
+				return view('qiye@/index/note_add');
+			}
+			return view();
+		}
+    }
+	
+    /**
+    * 查看
+    */
+    public function view($id)
+    {
+		$detail = $this->model->getById($id);
+		if (!empty($detail)) {
+			$detail['cate'] = Db::name('NoteCate')->where(['id' => $detail['cate_id']])->value('title');
+			$detail['admin_name'] = Db::name('Admin')->where(['id' => $detail['admin_id']])->value('name');
+			if($detail['file_ids'] !=''){
+				$file_array = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+				$detail['file_array'] = $file_array;
+			}
+			View::assign('detail', $detail);
+			if(is_mobile()){
+				return view('qiye@/index/note_view');
+			}
+			return view();
+		}
+		else{
+			return view(EEEOR_REPORTING,['code'=>404,'warning'=>'找不到页面']);
+		}
+    }
+	
+   /**
+    * 删除
+    */
+    public function del()
+    {
+		$param = get_params();
+		$id = isset($param['id']) ? $param['id'] : 0;
+		if (request()->isDelete()) {
+			$this->model->delById($id);
+		} else {
+            return to_assign(1, "错误的请求");
+        }
+    }   
+
+}

+ 141 - 0
app/adm/controller/Notecate.php

@@ -0,0 +1,141 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+ 
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\model\NoteCate as NoteCateModel;
+use app\adm\validate\NotecateValidate;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Notecate extends BaseController
+{
+	/**
+     * 构造函数
+     */
+	protected $model;
+    public function __construct()
+    {
+		parent::__construct(); // 调用父类构造函数
+        $this->model = new NoteCateModel();
+    }
+	
+    /**
+    * 数据列表
+    */
+    public function datalist()
+    {
+        if (request()->isAjax()) {
+            $list = $this->model->where('delete_time',0)->order('sort asc')->select();
+            return to_assign(0, '', $list);
+        }
+        else{
+            return view();
+        }
+    }
+	
+    /**
+    * 添加/编辑
+    */
+    public function add()
+    {
+		$param = get_params();	
+        if (request()->isAjax()) {		
+            if (!empty($param['id']) && $param['id'] > 0) {
+                try {
+                    validate(NotecateValidate::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+				$this->model->edit($param);
+            } else {
+                try {
+                    validate(NotecateValidate::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $this->model->add($param);
+            }	 
+        }else{
+			$id = isset($param['id']) ? $param['id'] : 0;
+			if ($id>0) {
+				$detail = $this->model->getCateById($id);
+				View::assign('detail', $detail);
+			}
+			return view();
+		}
+    }
+	
+    /**
+    * 查看
+    */
+    public function view($id)
+    {
+		$detail = $this->model->getById($id);
+		if (!empty($detail)) {
+			View::assign('detail', $detail);
+			return view();
+		}
+		else{
+			return view(EEEOR_REPORTING,['code'=>404,'warning'=>'找不到页面']);
+		}
+    }
+	
+   /**
+    * 删除
+    */
+    public function del()
+    {
+		if (request()->isDelete()) {
+			$param = get_params();
+			$id = isset($param['id']) ? $param['id'] : 0;
+			$type = isset($param['type']) ? $param['type'] : 0;
+			$this->model->delById($id,$type);
+		} else {
+            return to_assign(1, "错误的请求");
+        }
+    }
+
+    /**
+    * 设置
+    */
+    public function set()
+    {
+		if (request()->isAjax()) {
+			$param = get_params();
+			$res = $this->model->strict(false)->field('id,status')->update($param);
+			if ($res) {
+				if($param['status'] == 0){
+					add_log('disable', $param['id'], $param);
+				}
+				else if($param['status'] == 1){
+					add_log('recovery', $param['id'], $param);
+				}
+				return to_assign();
+			}
+			else{
+				return to_assign(0, '操作失败');
+			}
+		} else {
+            return to_assign(1, "错误的请求");
+        }
+    }
+   
+
+}

+ 206 - 0
app/adm/controller/Official.php

@@ -0,0 +1,206 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+ 
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\model\OfficialDocs;
+use app\adm\validate\CarValidate;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Official extends BaseController
+{
+	/**
+     * 构造函数
+     */
+	protected $model;
+    public function __construct()
+    {
+		parent::__construct(); // 调用父类构造函数
+        $this->model = new OfficialDocs();
+    }
+	
+    /**
+    * 数据列表
+    */
+    public function datalist()
+    {
+		$param = get_params();
+        if (request()->isAjax()) {
+			$where=[];
+			$whereOr = [];
+			$map1 = [];
+			$map2 = [];
+			$map3 = [];
+			$map4 = [];
+			$uid = $this->uid;
+			$tab = isset($param['tab']) ? $param['tab'] : 0;
+			
+			//条件1
+			$map1[] = ['admin_id','=',$uid];
+
+			//条件2
+			$map2[] = ['check_status','=',2];
+			$map2[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',send_uids)")];
+				
+			//条件3	
+			$map3[] = ['check_status','=',2];
+			$map3[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',copy_uids)")];
+			
+			//条件4
+			$map4[] = ['check_status','=',2];
+			$map4[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',share_uids)")];
+			
+			
+			$where[]=['delete_time','=',0];
+            if (!empty($param['keywords'])) {
+                $where[] = ['id|title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			if (!empty($param['secrets'])) {
+                $where[] = ['secrets', '=', $param['secrets']];
+            }
+			if (!empty($param['urgency'])) {
+                $where[] = ['urgency', '=', $param['urgency']];
+            }
+			if($tab == 0){
+				$whereOr = [$map1,$map2];
+			}
+			if($tab == 1){
+				$where[] = ['admin_id','=',$uid];
+			}
+			if($tab == 2){
+				$where[] = ['check_status','=',2];
+				$where[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',send_uids)")];
+			}
+			if($tab == 3){
+				$where[] = ['check_status','=',2];
+				$where[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',copy_uids)")];
+			}
+			if($tab == 4){
+				$where[] = ['check_status','=',2];
+				$where[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',share_uids)")];
+			}
+            $list = $this->model->datalist($param,$where,$whereOr);
+            return table_assign(0, '', $list);
+        }
+        else{
+			View::assign('secrets', $this->model::$Secrets);
+			View::assign('urgency', $this->model::$Urgency);
+            return view();
+        }
+    }
+	
+    /**
+    * 添加/编辑
+    */
+    public function add()
+    {
+		$param = get_params();	
+        if (request()->isAjax()) {
+			if (isset($param['draft_time'])) {
+                $param['draft_time'] = strtotime($param['draft_time']);
+            }	
+            if (!empty($param['id']) && $param['id'] > 0) {
+				$this->model->edit($param);
+            } else {
+				$param['admin_id'] = $this->uid;
+                $this->model->add($param);
+            }	 
+        }else{
+			$id = isset($param['id']) ? $param['id'] : 0;
+			if(is_mobile()){
+				return view('qiye@/index/405',['msg' => '由于公文包含了富文本编辑,手机端不方便操作,请到PC端新增或编辑']);
+			}
+			if ($id>0) {
+				$detail = $this->model->getById($id);
+                View::assign('detail', $detail);
+				return view('edit');
+			}
+			return view();
+		}
+    }
+	
+    /**
+    * 查看
+    */
+    public function view($id)
+    {
+		$detail = $this->model->getById($id);
+		if (!empty($detail)) {
+			View::assign('detail', $detail);
+			View::assign('auth_office', isAuth($this->uid,'office_admin','conf_1'));			
+			if(is_mobile()){
+				return view('qiye@/index/official_view');
+			}
+			return view();
+		}
+		else{
+			return view(EEEOR_REPORTING,['warning'=>'找不到页面']);
+		}
+    }
+	
+   /**
+    * 删除
+    */
+    public function del()
+    {
+		$param = get_params();
+		$id = isset($param['id']) ? $param['id'] : 0;
+		if (request()->isDelete()) {
+			$this->model->delById($id);
+		} else {
+            return to_assign(1, "错误的请求");
+        }
+    }  
+	
+	//待审公文列表
+    public function pending()
+    {
+        if (request()->isAjax()) {
+			$param = get_params();
+			$uid = $this->uid;
+			$where=[];
+			if (!empty($param['keywords'])) {
+                $where[] = ['title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			$where[] = ['check_status', '=', 1];
+			$where[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',check_uids)")];
+			$list = $this->model->datalist($param,$where);
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+	
+	//已审公文列表
+    public function reviewed()
+    {
+        if (request()->isAjax()) {
+			$param = get_params();
+			$uid = $this->uid;
+			$where=[];
+			if (!empty($param['keywords'])) {
+                $where[] = ['title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			$where[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',check_history_uids)")];
+			$list = $this->model->datalist($param,$where);
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+}

+ 282 - 0
app/adm/controller/Property.php

@@ -0,0 +1,282 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\model\Property as PropertyModel;
+use app\adm\validate\PropertyCheck;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Property extends BaseController
+{
+	/**
+     * 构造函数
+     */
+	protected $model;
+    public function __construct()
+    {
+		parent::__construct(); // 调用父类构造函数
+        $this->model = new PropertyModel();
+    }
+	
+	public function datalist()
+    {
+        if (request()->isAjax()) {
+			$param = get_params();
+			$where = [];
+			if (!empty($param['keywords'])) {
+                $where[] = ['p.title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			if (isset($param['status']) && $param['status']!='') {
+				$where[] = ['p.status', '=', $param['status']];
+            }
+			else{
+               $where[] = ['p.status','>=',0];
+			}
+			if (!empty($param['cate_id'])) {
+				$cate_id_array = get_cate_son('PropertyCate',$param['cate_id']);
+                $where[] = ['p.cate_id', 'in', $cate_id_array];
+            }
+			if (!empty($param['brand_id'])) {
+                $where[] = ['p.brand_id', '=', $param['brand_id']];
+            }
+			$list = $this->model->datalist($where, $param);
+            return table_assign(0, '', $list);
+        } else {
+			View::assign('status', $this->model::$property_status);
+            return view();
+        }
+    }
+    //新建编辑
+    public function add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+			if (isset($param['buy_time'])) {
+                $param['buy_time'] = strtotime($param['buy_time']);
+            }
+			if (isset($param['quality_time'])) {
+                $param['quality_time'] = strtotime($param['quality_time']);
+            }
+            if (!empty($param['id']) && $param['id'] > 0) {
+                try {
+                    validate(PropertyCheck::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['update_time'] = time();
+				$param['update_id'] = $this->uid;
+                $this->model->edit($param);
+            } else {
+                try {
+                    validate(PropertyCheck::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['create_time'] = time();
+                $param['admin_id'] = $this->uid;
+                $this->model->add($param);
+            }
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+			View::assign('status', $this->model::$property_status);
+			View::assign('source', $this->model::$property_source);
+            if($id>0){
+                $detail = $this->model->getById($id);
+				if(!empty($detail['user_ids'])){
+					$users =  Db::name('Admin')->where('id','in',$detail['user_ids'])->column('name');
+					$detail['users_name'] = implode(',',$users);
+				}
+				if($detail['file_ids'] !=''){
+					$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+					$detail['fileArray'] = $fileArray;
+				}
+                View::assign('detail', $detail);
+				return view('edit');
+            }
+            return view();
+        }
+    }
+	
+    //查看
+    public function view()
+    {
+        $param = get_params();
+		$id = isset($param['id']) ? $param['id'] : 0;
+		$detail = $this->model->getById($id);
+		if($detail['cate_id']>0){
+			$detail['cate'] = Db::name('PropertyCate')->where('id',$detail['cate_id'])->value('title');
+		}
+		if($detail['unit_id']>0){
+			$detail['unit'] = Db::name('PropertyUnit')->where('id',$detail['unit_id'])->value('title');
+		}
+		if($detail['brand_id']>0){
+			$detail['brand'] = Db::name('PropertyBrand')->where('id',$detail['brand_id'])->value('title');
+		}
+		if(!empty($detail['user_ids'])){
+			$users =  Db::name('Admin')->where('id','in',$detail['user_ids'])->column('name');
+			$detail['users_name'] = implode(',',$users);
+		}
+		if(!empty($detail['user_dids'])){
+			$titles =  Db::name('Department')->where('id','in',$detail['user_dids'])->column('title');
+			$detail['dids_title'] = implode(',',$titles);
+		}
+		if($detail['file_ids'] !=''){
+			$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+			$detail['fileArray'] = $fileArray;
+		}
+		$repair = Db::name('PropertyRepair')
+				->field('pr.*,u.name as director_name')
+				->alias('pr')
+				->join('Admin u', 'u.id = pr.director_id', 'left')
+				->where(['pr.delete_time'=>0,'pr.property_id'=>$detail['id']])
+				->select()->toArray();
+		$detail['repair'] = $repair;
+		View::assign('detail', $detail);
+		return view();
+    }
+	
+    //设置
+    public function check()
+    {
+		$param = get_params();
+        $res = Db::name('Property')->strict(false)->field('id,status')->update($param);
+		if ($res) {
+			add_log('set', $param['id'], $param);
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }   
+	
+	
+	//维修记录列表
+    public function repair_list()
+    {
+        if (request()->isAjax()) {
+			$param = get_params();
+			$where = [];
+			if (!empty($param['keywords'])) {
+                $where[] = ['p.title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			if (!empty($param['diff_time'])) {
+				$diff_time =explode('~', $param['diff_time']);
+                $where[] = ['pr.repair_time', 'between', [strtotime(urldecode($diff_time[0])),strtotime(urldecode($diff_time[1]))]];
+            }
+			$where[] = ['pr.delete_time','=',0];
+			$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+            $list = Db::name('PropertyRepair')
+				->field('pr.*,pc.title as cate,pb.title as brand,p.title,p.model,u.name as director_name')
+				->alias('pr')
+				->join('Property p', 'p.id = pr.property_id', 'left')
+				->join('PropertyCate pc', 'pc.id = p.cate_id', 'left')
+				->join('PropertyBrand pb', 'pb.id = p.brand_id', 'left')
+				->join('Admin u', 'u.id = pr.director_id', 'left')
+				->where($where)
+				->order('id desc')
+				->paginate(['list_rows'=> $rows])
+				->each(function ($item, $key){
+					$item['repair_time'] = date('Y-m-d',$item['repair_time']);
+					$item['create_time'] = date('Y-m-d H:i',$item['create_time']);
+					return $item;
+				});
+            return table_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+	
+    //维修记录添加&编辑
+    public function repair_add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+			if (isset($param['repair_time'])) {
+                $param['repair_time'] = strtotime($param['repair_time']);
+            }
+            if (!empty($param['id']) && $param['id'] > 0) {
+                $param['update_time'] = time();
+				$res = Db::name('PropertyRepair')->strict(false)->field(true)->update($param);
+				if($res){
+					add_log('edit', $param['id'], $param);
+					return to_assign();
+				}
+            } else {
+                $param['create_time'] = time();
+                $insertId = Db::name('PropertyRepair')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            $pid = isset($param['pid']) ? $param['pid'] : 0;
+            if ($id > 0) {
+                $detail = Db::name('PropertyRepair')->where(['id' => $id])->find();
+                $detail['director_name'] = Db::name('Admin')->where('id',$detail['director_id'])->value('name');
+                $detail['property'] = Db::name('Property')->where('id',$detail['property_id'])->value('title');
+				if($detail['file_ids'] !=''){
+					$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+					$detail['fileArray'] = $fileArray;
+				}
+                View::assign('detail', $detail);
+				return view('repair_edit');
+            }
+			if($pid>0){
+				View::assign('property', $this->model->getById($pid));
+			}
+            View::assign('pid', $pid);
+            View::assign('id', $id);
+            return view();
+        }
+    }
+	
+    //维修记录查看
+    public function repair_view()
+    {
+        $param = get_params();
+        $id = isset($param['id']) ? $param['id'] : 0;
+		$detail = Db::name('PropertyRepair')->where(['id' => $id])->find();
+		$detail['director_name'] = Db::name('Admin')->where('id',$detail['director_id'])->value('name');
+		$detail['property'] = Db::name('Property')->where('id',$detail['property_id'])->value('title');
+		if($detail['file_ids'] !=''){
+			$fileArray = Db::name('File')->where('id','in',$detail['file_ids'])->select();
+			$detail['fileArray'] = $fileArray;
+		}
+		View::assign('detail', $detail);
+        return view();
+    }
+	
+     //维修记录删除
+    public function repair_del()
+    {
+		$param = get_params();
+        $res = Db::name('PropertyRepair')->where('id',$param['id'])->update(['delete_time'=>time()]);
+		if ($res) {
+			add_log('delete', $param['id'], $param);
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }  
+}

+ 87 - 0
app/adm/controller/Propertybrand.php

@@ -0,0 +1,87 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Propertybrand extends BaseController
+{	
+	//资产品牌
+    public function datalist()
+    {
+        if (request()->isAjax()) {
+            $cate = Db::name('PropertyBrand')->order('create_time asc')->select();
+            return to_assign(0, '', $cate);
+        } else {
+            return view();
+        }
+    }
+
+    //添加&编辑
+    public function add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+            if (!empty($param['id']) && $param['id'] > 0) {
+                $param['update_time'] = time();
+				$res = Db::name('PropertyBrand')->strict(false)->field(true)->update($param);
+				if($res){
+					add_log('edit', $param['id'], $param);
+					return to_assign();
+				}
+            } else {
+                $param['create_time'] = time();
+                $insertId = Db::name('PropertyBrand')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            if ($id > 0) {
+                $detail = Db::name('PropertyBrand')->where(['id' => $id])->find();
+                View::assign('detail', $detail);
+            }
+            View::assign('id', $id);
+            return view();
+        }
+    }
+
+    //禁用启用
+    public function check()
+    {
+		$param = get_params();
+        $res = Db::name('PropertyBrand')->strict(false)->field('id,status')->update($param);
+		if ($res) {
+			if($param['status'] == 0){
+				add_log('disable', $param['id'], $param);
+			}
+			else if($param['status'] == 1){
+				add_log('recovery', $param['id'], $param);
+			}
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    } 
+   
+   
+}

+ 112 - 0
app/adm/controller/Propertycate.php

@@ -0,0 +1,112 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\validate\CateCheck;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Propertycate extends BaseController
+{	
+	//类别
+    public function datalist()
+    {
+        if (request()->isAjax()) {
+            $cate = Db::name('PropertyCate')->order('create_time asc')->select();
+			$list = generateTree($cate);
+            return to_assign(0, '', $list);
+        } else {
+            return view();
+        }
+    }
+
+    //分类添加&编辑
+    public function add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+            if (!empty($param['id']) && $param['id'] > 0) {
+                try {
+                    validate(CateCheck::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $note_array = get_cate_son('PropertyCate',$param['id']);
+                if (in_array($param['pid'], $note_array)) {
+                    return to_assign(1, '父级分类不能是该分类本身或其子分类');
+                } else {
+                    $param['update_time'] = time();
+                    $res = Db::name('PropertyCate')->strict(false)->field(true)->update($param);
+                    if($res){
+                        add_log('edit', $param['id'], $param);
+                        return to_assign();
+                    }
+                }
+            } else {
+                try {
+                    validate(CateCheck::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['create_time'] = time();
+                $insertId = Db::name('PropertyCate')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            $pid = isset($param['pid']) ? $param['pid'] : 0;
+			$cate = Db::name('PropertyCate')->order('id desc')->select()->toArray();
+			$cates = set_recursion($cate);
+            if ($id > 0) {
+                $detail = Db::name('PropertyCate')->where(['id' => $id])->find();
+                View::assign('detail', $detail);
+            }
+            View::assign('id', $id);
+            View::assign('pid', $pid);
+            View::assign('cates', $cates);
+            return view();
+        }
+    }
+
+    //删除分类
+    public function del()
+    {
+        $id = get_params("id");
+        $cate_count = Db::name('PropertyCate')->where(["pid" => $id])->count();
+        if ($cate_count > 0) {
+            return to_assign(1, "该分类下还有子分类,无法删除");
+        }
+        $content_count = Db::name('Property')->where(["cate_id" => $id])->count();
+        if ($content_count > 0) {
+            return to_assign(1, "该分类下还有资产,无法删除");
+        }
+        if (Db::name('PropertyCate')->delete($id) !== false) {
+            add_log('delete', $id);
+            return to_assign(0, "删除分类成功");
+        } else {
+            return to_assign(1, "删除失败");
+        }
+    }
+   
+   
+}

+ 87 - 0
app/adm/controller/Propertyunit.php

@@ -0,0 +1,87 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Propertyunit extends BaseController
+{	
+	//资产单位
+    public function datalist()
+    {
+        if (request()->isAjax()) {
+            $cate = Db::name('PropertyUnit')->order('create_time asc')->select();
+            return to_assign(0, '', $cate);
+        } else {
+            return view();
+        }
+    }
+
+    //添加&编辑
+    public function add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+            if (!empty($param['id']) && $param['id'] > 0) {
+                $param['update_time'] = time();
+				$res = Db::name('PropertyUnit')->strict(false)->field(true)->update($param);
+				if($res){
+					add_log('edit', $param['id'], $param);
+					return to_assign();
+				}
+            } else {
+                $param['create_time'] = time();
+                $insertId = Db::name('PropertyUnit')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        } else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            if ($id > 0) {
+                $detail = Db::name('PropertyUnit')->where(['id' => $id])->find();
+                View::assign('detail', $detail);
+            }
+            View::assign('id', $id);
+            return view();
+        }
+    }
+
+    //禁用启用
+    public function check()
+    {
+		$param = get_params();
+        $res = Db::name('PropertyUnit')->strict(false)->field('id,status')->update($param);
+		if ($res) {
+			if($param['status'] == 0){
+				add_log('disable', $param['id'], $param);
+			}
+			else if($param['status'] == 1){
+				add_log('recovery', $param['id'], $param);
+			}
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    } 
+   
+   
+}

+ 206 - 0
app/adm/controller/Seal.php

@@ -0,0 +1,206 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+ 
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\model\Seal as SealModel;
+use app\adm\validate\CarValidate;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Seal extends BaseController
+{
+	/**
+     * 构造函数
+     */
+	protected $model;
+    public function __construct()
+    {
+		parent::__construct(); // 调用父类构造函数
+        $this->model = new SealModel();
+    }
+	
+    /**
+    * 数据列表
+    */
+    public function datalist()
+    {
+		$param = get_params();
+        if (request()->isAjax()) {
+			$tab = isset($param['tab']) ? $param['tab'] : 0;
+			$uid=$this->uid;
+            $where = array();
+            $whereOr = array();
+			$where[]=['delete_time','=',0];
+			if($tab == 0){
+				//全部
+				$whereOr[] = ['admin_id', '=', $this->uid];
+				$whereOr[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',check_uids)")];
+				$whereOr[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',check_history_uids)")];
+				$whereOr[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',check_copy_uids)")];
+			}
+			if($tab == 1){
+				//创建的
+				$where[] = ['admin_id', '=', $this->uid];
+			}
+			if($tab == 2){
+				//待我审核的
+				$where[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',check_uids)")];
+			}
+			if($tab == 3){
+				//我已审核的
+				$where[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',check_history_uids)")];
+			}
+			if($tab == 4){
+				//抄送给我的
+				$where[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',check_copy_uids)")];
+			}
+            if (!empty($param['seal_cate_id'])) {
+                $where[] = ['seal_cate_id', '=', $param['seal_cate_id']];
+            }
+			if (isset($param['check_status']) && $param['check_status'] != "") {
+                $where[] = ['check_status', '=', $param['check_status']];
+            }
+			if (!empty($param['keywords'])) {
+                $where[] = ['id|title', 'like', '%' . $param['keywords'] . '%'];
+            }
+            $list = $this->model->datalist($where,$whereOr, $param);
+            return table_assign(0, '', $list);
+        }
+        else{
+            return view();
+        }
+    }
+	
+    /**
+    * 添加/编辑
+    */
+    public function add()
+    {
+		$param = get_params();	
+        if (request()->isAjax()) {
+			if (!empty($param['use_time'])) {
+                $param['use_time'] = strtotime($param['use_time']);
+            }
+			if (!empty($param['start_time'])) {
+                $param['start_time'] = strtotime($param['start_time']);
+            }
+			else{
+				$param['start_time'] = 0;
+			}
+			if (!empty($param['end_time'])) {
+                $param['end_time'] = strtotime($param['end_time']);
+				if($param['end_time']<$param['start_time']){
+					return to_assign(1, "结束借用日期需要大于等于印章借用日期");
+				}
+            }
+			else{
+				$param['end_time'] = 0;
+			}
+            if (!empty($param['id']) && $param['id'] > 0) {
+				$this->model->edit($param);
+            } else {
+				$param['admin_id'] = $this->uid;
+                $this->model->add($param);
+            }	 
+        }else{
+			$id = isset($param['id']) ? $param['id'] : 0;
+			$did = $this->did;
+			$map1 = [];
+			$map2 = [];
+			$map1[] = ['status', '=', 1];
+			$map1[] = ['dids', '=', ''];
+
+			$map2[] = ['status', '=', 1];
+			$map2[] = ['', 'exp', Db::raw("FIND_IN_SET('{$did}',dids)")];
+
+			$sealcate = Db::name('SealCate')->whereOr([$map1,$map2])->order('id desc')->select()->toArray();
+			View::assign('sealcate', $sealcate);
+			View::assign('user', get_admin($this->uid));
+			if ($id>0) {
+				$detail = $this->model->getById($id);
+				if($detail['check_status']==0 || $detail['check_status']==4){
+					View::assign('detail', $detail);
+					if(is_mobile()){
+						return view('qiye@/approve/add_seal');
+					}
+					return view('edit');
+				}
+			}
+			if(is_mobile()){
+				return view('qiye@/approve/add_seal');
+			}
+			return view();
+		}
+    }
+	
+    /**
+    * 查看
+    */
+    public function view($id)
+    {
+		$detail = $this->model->getById($id);
+		if (!empty($detail)) {
+			View::assign('detail', $detail);
+			View::assign('create_user', get_admin($detail['admin_id']));
+			if(is_mobile()){
+				return view('qiye@/approve/view_seal');
+			}
+			return view();
+		}
+		else{
+			return view(EEEOR_REPORTING,['warning'=>'找不到页面']);
+		}
+    }
+	
+   /**
+    * 删除
+    */
+    public function del()
+    {
+		$param = get_params();
+		$id = isset($param['id']) ? $param['id'] : 0;
+		if (request()->isDelete()) {
+			$this->model->delById($id);
+		} else {
+            return to_assign(1, "错误的请求");
+        }
+    }  
+	
+	//用章记录
+    public function record()
+    {
+        if (request()->isAjax()) {
+			$param = get_params();
+			$where = [];
+			$whereOr = [];
+			$where[]=['delete_time','=',0];
+			$where[]=['check_status','=',2];
+            if (!empty($param['seal_cate_id'])) {
+                $where[] = ['seal_cate_id', '=', $param['seal_cate_id']];
+            }
+			if (!empty($param['keywords'])) {
+                $where[] = ['id|title', 'like', '%' . $param['keywords'] . '%'];
+            }
+			$list = $this->model->datalist($where,$whereOr, $param);
+            return table_assign(0, '', $list);
+        } else {
+			View::assign('status', ['未使用','已使用','已归还']);
+            return view();
+        }
+    }
+}

+ 111 - 0
app/adm/controller/Sealcate.php

@@ -0,0 +1,111 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+declare (strict_types = 1);
+
+namespace app\adm\controller;
+
+use app\base\BaseController;
+use app\adm\validate\SealCateCheck;
+use think\exception\ValidateException;
+use think\facade\Db;
+use think\facade\View;
+
+class Sealcate extends BaseController
+{	
+	//印章类别
+    public function datalist()
+    {
+        if (request()->isAjax()) {
+            $cate = Db::name('SealCate')
+				->field('a.*,u.name,d.title as department')
+				->alias('a')
+				->join('Admin u', 'u.id = a.keep_uid')
+				->join('Department d', 'd.id = u.did')
+				->order('create_time asc')->select()->toArray();
+				foreach ($cate as $key => &$value) {
+					if(!empty($value['dids'])){
+						$value['departments']=get_department_name($value['dids']);
+					}
+					else{
+						$value['departments']='全部';
+					}
+				}
+            return to_assign(0, '', $cate);
+        } else {
+            return view();
+        }
+    }
+    //添加
+    public function add()
+    {
+        $param = get_params();
+        if (request()->isAjax()) {
+            if (!empty($param['id']) && $param['id'] > 0) {
+                try {
+                    validate(SealCateCheck::class)->scene('edit')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['update_time'] = time();
+                $res = Db::name('SealCate')->strict(false)->field(true)->update($param);
+                if ($res) {
+                    add_log('edit', $param['id'], $param);
+                }
+                return to_assign();
+            } else {
+                try {
+                    validate(SealCateCheck::class)->scene('add')->check($param);
+                } catch (ValidateException $e) {
+                    // 验证失败 输出错误信息
+                    return to_assign(1, $e->getError());
+                }
+                $param['create_time'] = time();
+                $insertId = Db::name('SealCate')->strict(false)->field(true)->insertGetId($param);
+                if ($insertId) {
+                    add_log('add', $insertId, $param);
+                }
+                return to_assign();
+            }
+        }else {
+            $id = isset($param['id']) ? $param['id'] : 0;
+            if ($id > 0) {
+                $detail = Db::name('SealCate')->where(['id' => $id])->find();
+                $detail['keep_name'] = Db::name('Admin')->where(['id' =>  $detail['keep_uid']])->value('name');
+                View::assign('detail', $detail);
+            }
+            View::assign('id', $id);
+            return view();
+        }
+    }
+	
+    //设置
+    public function check()
+    {
+		$param = get_params();
+        $res = Db::name('SealCate')->strict(false)->field('id,status')->update($param);
+		if ($res) {
+			if($param['status'] == 0){
+				add_log('disable', $param['id'], $param);
+			}
+			else if($param['status'] == 1){
+				add_log('recovery', $param['id'], $param);
+			}
+			return to_assign();
+		}
+		else{
+			return to_assign(0, '操作失败');
+		}
+    }   
+}

+ 8 - 0
app/adm/event.php

@@ -0,0 +1,8 @@
+<?php
+return [
+	'listen'    => [
+        //注册监听类
+        'SendMessage' => ['app\listener\SendMessage'],
+    ],
+    //'subscribe' => ['app\subscribe\Message'],
+];

+ 8 - 0
app/adm/middleware.php

@@ -0,0 +1,8 @@
+<?php
+// 这是系统自动生成的middleware定义文件
+return [
+    //开启session中间件
+    //'think\middleware\SessionInit',
+    //验证勾股OA是否完成安装
+    \app\home\middleware\Install::class,
+];

+ 197 - 0
app/adm/model/Car.php

@@ -0,0 +1,197 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+namespace app\adm\model;
+use think\model;
+use think\facade\Db;
+class Car extends Model
+{
+    /**
+    * 获取分页列表
+    * @param $where
+    * @param $param
+    */
+    public function datalist($where, $param)
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {
+            $list = self::where($where)
+			->order($order)
+			->paginate(['list_rows'=> $rows])
+			->each(function ($item, $key){
+				$item->buy_time = date('Y-m-d', $item->buy_time);
+				$item->insure_time = date('Y-m-d', $item->insure_time);
+				$item->insure_time_note = count_days(date("Y-m-d"),$item->insure_time);
+				$item->review_time = date('Y-m-d', $item->review_time);
+				$item->review_time_note = count_days(date("Y-m-d"),$item->review_time);
+				if($item->driver>0){
+					$item->driver_name = Db::name('Admin')->where('id','=',$item->driver)->value('name');
+				}
+				else{
+					$item->driver_name='-';
+				}
+				$item->create_time = to_date($item->create_time);
+			});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+    /**
+    * 添加数据
+    * @param $param
+    */
+    public function add($param)
+    {
+		$insertId = 0;
+        try {
+			$param['create_time'] = time();
+			$param['mileage_now'] = $param['mileage'];
+			$insertId = self::strict(false)->field(true)->insertGetId($param);
+			add_log('add', $insertId, $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['aid'=>$insertId]);
+    }
+
+    /**
+    * 编辑信息
+    * @param $param
+    */
+    public function edit($param)
+    {
+        try {
+            $param['update_time'] = time();
+            self::where('id', $param['id'])->strict(false)->field(true)->update($param);
+			add_log('edit', $param['id'], $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign();
+    }
+	
+    /**
+    * 根据id获取信息
+    * @param $id
+    */
+    public function getById($id)
+    {
+        $info = self::find($id);
+		return $info;
+    }
+
+    /**
+    * 删除信息
+    * @param $id
+    * @param $type
+    * @return array
+    */
+    public function delById($id,$type=0)
+    {
+		if($type==0){
+			//逻辑删除
+			try {
+				$param['delete_time'] = time();
+				self::where('id', $id)->update(['delete_time'=>time()]);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		else{
+			//物理删除
+			try {
+				self::destroy($id);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		return to_assign();
+    }
+	
+	//维修(保养)记录
+    public function repairlist($where, $param)
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {
+            $list = Db::name('CarRepair')
+				->field('cr.*,c.title as car,c.name,u.name as handled_name')
+				->alias('cr')
+				->join('Car c', 'c.id = cr.car_id', 'left')
+				->join('Admin u', 'u.id = cr.handled', 'left')
+				->where($where)
+				->order($order)
+				->paginate(['list_rows'=> $rows])
+				->each(function ($item, $key){
+					$item['repair_time'] = date('Y-m-d',$item['repair_time']);
+					$item['create_time'] = date('Y-m-d H:i',$item['create_time']);
+					return $item;
+				});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+	
+	//费用记录
+    public function feelist($where, $param)
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {
+            $list = Db::name('CarFee')
+				->field('cf.*,c.title as car,c.name,u.name as handled_name,ba.title as types_str')
+				->alias('cf')
+				->join('Car c', 'c.id = cf.car_id', 'left')
+				->join('basicAdm ba', 'ba.id = cf.types', 'left')
+				->join('Admin u', 'u.id = cf.handled', 'left')
+				->where($where)
+				->order($order)
+				->paginate(['list_rows'=> $rows])
+				->each(function ($item, $key){
+					$item['fee_time'] = date('Y-m-d',$item['fee_time']);
+					$item['create_time'] = date('Y-m-d H:i',$item['create_time']);
+					return $item;
+				});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+	
+	//里程记录
+    public function mileagelist($where, $param)
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {
+			$list = Db::name('CarMileage')
+				->order('mileage_time desc')
+				->where($where)
+				->order($order)
+				->paginate($rows, false)->each(function($item, $key){
+					$item['mileage_time'] = date('Y-m', $item['mileage_time']);
+					$item['create_time'] = date('Y-m-d H:i:s', $item['create_time']);
+					$item['admin_name'] =  Db::name('Admin')->where('id',$item['admin_id'])->value('name');
+					return $item;
+				});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+}
+

+ 143 - 0
app/adm/model/MeetingOrder.php

@@ -0,0 +1,143 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\model;
+use think\model;
+use think\facade\Db;
+class MeetingOrder extends Model
+{
+    /**
+    * 获取分页列表
+    * @param $where
+    * @param $param
+    */
+    public function datalist($param=[],$where=[],$whereOr=[])
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {			
+            $list = self::where($where)
+				->where(function ($query) use($whereOr) {
+					if (!empty($whereOr)){
+						$query->whereOr($whereOr);
+					}
+				})
+				->order($order)
+				->paginate(['list_rows'=> $rows])
+				->each(function ($item, $key){
+					$item['room'] = Db::name('MeetingRoom')->where(['id' => $item['room_id']])->value('title');
+					$item['meeting_date'] = date('Y-m-d H:i', $item['start_date']).' 至 '.date('Y-m-d H:i', $item['end_date']);
+					$item['did_name'] = Db::name('Department')->where(['id' => $item['did']])->value('title');
+					$item['admin_name'] = Db::name('Admin')->where('id',$item['admin_id'])->value('name');
+					$item['create_time'] = to_date($item['create_time']);
+					$item->check_status_str = check_status_name($item->check_status);
+					$item['check_user'] = '-';
+					if($item['check_status']==1 && !empty($item['check_uids'])){
+						$check_user = Db::name('Admin')->where('id','in',$item['check_uids'])->column('name');
+						$item['check_user'] = implode(',',$check_user);
+					}
+				});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+
+    /**
+    * 添加数据
+    * @param $param
+    */
+    public function add($param)
+    {
+		$insertId = 0;
+        try {
+			$param['create_time'] = time();
+			$insertId = self::strict(false)->field(true)->insertGetId($param);
+			add_log('add', $insertId, $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['return_id'=>$insertId]);
+    }
+
+    /**
+    * 编辑信息
+    * @param $param
+    */
+    public function edit($param)
+    {
+        try {
+            $param['update_time'] = time();
+            self::where('id', $param['id'])->strict(false)->field(true)->update($param);
+			add_log('edit', $param['id'], $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['return_id'=>$param['id']]);
+    }	
+
+    /**
+    * 根据id获取信息
+    * @param $id
+    */
+    public function getById($id)
+    {
+        $info = self::find($id);
+		$info['start_time'] = to_date($info['start_date'],'Y-m-d H:i');
+		$info['end_time'] = to_date($info['end_date'],'Y-m-d H:i');
+		$info['room'] = Db::name('MeetingRoom')->where(['id' => $info['room_id']])->value('title');
+		$info['department'] = Db::name('Department')->where(['id' => $info['did']])->value('title');
+		$info['admin_name'] = Db::name('Admin')->where('id','=',$info['admin_id'])->value('name');
+		$requirements = get_base_type_data('BasicAdm',2);
+		$requirements_array = explode(',', $info['requirements']);
+		foreach ($requirements as &$val) {
+			if (in_array($val['id'], $requirements_array)) {
+				$val['checked'] = 1;
+			} else {
+				$val['checked'] = 0;
+			}
+		}
+		$info['requirements_array'] = $requirements;
+		return $info;
+    }
+
+    /**
+    * 删除信息
+    * @param $id
+    * @param $type
+    * @return array
+    */
+    public function delById($id,$type=0)
+    {
+		if($type==0){
+			//逻辑删除
+			try {
+				$param['delete_time'] = time();
+				self::where('id', $id)->update(['delete_time'=>time()]);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		else{
+			//物理删除
+			try {
+				self::destroy($id);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		return to_assign();
+    }
+}

+ 131 - 0
app/adm/model/MeetingRecords.php

@@ -0,0 +1,131 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\model;
+use think\model;
+use think\facade\Db;
+class MeetingRecords extends Model
+{
+    /**
+    * 获取分页列表
+    * @param $where
+    * @param $param
+    */
+    public function datalist($param=[],$where=[],$whereOr=[])
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {			
+            $list = self::where($where)
+				->where(function ($query) use($whereOr) {
+					if (!empty($whereOr)){
+						$query->whereOr($whereOr);
+					}
+				})
+				->order($order)
+				->paginate(['list_rows'=> $rows])
+				->each(function ($item, $key){					
+					$item['anchor'] = Db::name('Admin')->where(['id' => $item['anchor_id']])->value('name');
+					$item['meeting_date'] = empty($item['meeting_date']) ? '-' : date('Y-m-d', $item['meeting_date']);
+					$item['did_name'] = Db::name('Department')->where(['id' => $item['did']])->value('title');
+					$item['recorder_name'] = Db::name('Admin')->where(['id' => $item['recorder_id']])->value('name');
+				});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+
+    /**
+    * 添加数据
+    * @param $param
+    */
+    public function add($param)
+    {
+		$insertId = 0;
+        try {
+			$param['create_time'] = time();
+			$insertId = self::strict(false)->field(true)->insertGetId($param);
+			add_log('add', $insertId, $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['aid'=>$insertId]);
+    }
+
+    /**
+    * 编辑信息
+    * @param $param
+    */
+    public function edit($param)
+    {
+        try {
+            $param['update_time'] = time();
+            self::where('id', $param['id'])->strict(false)->field(true)->update($param);
+			add_log('edit', $param['id'], $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign();
+    }	
+
+    /**
+    * 根据id获取信息
+    * @param $id
+    */
+    public function getById($id)
+    {
+        $info = self::find($id);
+		$info['recorder_name'] = Db::name('Admin')->where(['id' => $info['recorder_id']])->value('name');
+		$info['anchor_name'] = Db::name('Admin')->where(['id' => $info['anchor_id']])->value('name');
+		$info['room'] = Db::name('MeetingRoom')->where(['id' => $info['room_id']])->value('title');
+		$info['did_name'] = Db::name('Department')->where(['id' => $info['did']])->value('title');
+		$join_names = Db::name('Admin')->where([['id','in',$info['join_uids']]])->column('name');
+		$info['join_names'] =implode(',' ,$join_names);
+		$sign_names = Db::name('Admin')->where([['id','in',$info['sign_uids']]])->column('name');
+		$info['sign_names'] =implode(',' ,$sign_names);
+		$share_names = Db::name('Admin')->where([['id','in',$info['share_uids']]])->column('name');
+		$info['share_names'] =implode(',' ,$share_names);
+		return $info;
+    }
+
+    /**
+    * 删除信息
+    * @param $id
+    * @param $type
+    * @return array
+    */
+    public function delById($id,$type=0)
+    {
+		if($type==0){
+			//逻辑删除
+			try {
+				$param['delete_time'] = time();
+				self::where('id', $id)->update(['delete_time'=>time()]);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		else{
+			//物理删除
+			try {
+				self::destroy($id);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		return to_assign();
+    }
+}

+ 114 - 0
app/adm/model/News.php

@@ -0,0 +1,114 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+namespace app\adm\model;
+use think\model;
+use think\facade\Db;
+class News extends Model
+{
+    /**
+    * 获取分页列表
+    * @param $where
+    * @param $param
+    */
+    public function datalist($where, $param)
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {
+            $list = self::where($where)
+			->order($order)
+			->paginate(['list_rows'=> $rows])
+			->each(function ($item, $key){
+				$item->admin_name = Db::name('Admin')->where('id',$item->admin_id)->value('name');
+				$item->create_time = to_date($item->create_time);
+			});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+
+    /**
+    * 添加数据
+    * @param $param
+    */
+    public function add($param)
+    {
+		$insertId = 0;
+        try {
+			$param['create_time'] = time();
+			$insertId = self::strict(false)->field(true)->insertGetId($param);
+			add_log('add', $insertId, $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['return_id'=>$insertId]);
+    }
+
+    /**
+    * 编辑信息
+    * @param $param
+    */
+    public function edit($param)
+    {
+        try {
+            $param['update_time'] = time();
+            self::where('id', $param['id'])->strict(false)->field(true)->update($param);
+			add_log('edit', $param['id'], $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['return_id'=>$param['id']]);
+    }
+	
+    /**
+    * 根据id获取信息
+    * @param $id
+    */
+    public function getById($id)
+    {
+        $info = self::find($id);
+		return $info;
+    }
+
+    /**
+    * 删除信息
+    * @param $id
+    * @param $type
+    * @return array
+    */
+    public function delById($id,$type=0)
+    {
+		if($type==0){
+			//逻辑删除
+			try {
+				$param['delete_time'] = time();
+				self::where('id', $id)->update(['delete_time'=>time()]);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		else{
+			//物理删除
+			try {
+				self::destroy($id);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		return to_assign();
+    }
+}
+

+ 129 - 0
app/adm/model/Note.php

@@ -0,0 +1,129 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+namespace app\adm\model;
+use think\model;
+use think\facade\Db;
+class Note extends Model
+{
+    /**
+    * 获取分页列表
+    * @param $where
+    * @param $param
+    */
+    public function datalist($where, $param)
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'a.sort desc,a.create_time desc' : $param['order'];
+        try {
+            $list = self::where($where)
+			->field('a.*,c.title as cate')
+            ->alias('a')
+            ->join('NoteCate c', 'a.cate_id = c.id', 'LEFT')
+			->order($order)
+			->paginate(['list_rows'=> $rows])
+			->each(function ($item, $key){
+				$item->admin_name = Db::name('Admin')->where('id',$item->admin_id)->value('name');
+				$item->create_time = to_date($item->create_time);
+			});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+
+    /**
+    * 添加数据
+    * @param $param
+    */
+    public function add($param)
+    {
+		$insertId = 0;
+        try {
+			$param['create_time'] = time();
+			$insertId = self::strict(false)->field(true)->insertGetId($param);
+			add_log('add', $insertId, $param);
+			$users= Db::name('Admin')->field('id as from_uid')->where(['status' => 1])->column('id');
+			$msg=[
+				'from_uid'=>$param['admin_id'],//发送人
+				'to_uids'=>$users,//接收人
+				'template_id'=>'note',//消息模板ID
+				'content'=>[ //消息内容
+					'create_time'=>date('Y-m-d H:i:s'),
+					'title' => $param['title'],
+					'action_id'=>$insertId
+				]
+			];
+			event('SendMessage',$msg);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['aid'=>$insertId]);
+    }
+
+    /**
+    * 编辑信息
+    * @param $param
+    */
+    public function edit($param)
+    {
+        try {
+            $param['update_time'] = time();
+            self::where('id', $param['id'])->strict(false)->field(true)->update($param);
+			add_log('edit', $param['id'], $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign();
+    }
+	
+    /**
+    * 根据id获取信息
+    * @param $id
+    */
+    public function getById($id)
+    {
+        $info = self::find($id);
+		return $info;
+    }
+
+    /**
+    * 删除信息
+    * @param $id
+    * @param $type
+    * @return array
+    */
+    public function delById($id,$type=0)
+    {
+		if($type==0){
+			//逻辑删除
+			try {
+				$param['delete_time'] = time();
+				self::where('id', $id)->update(['delete_time'=>time()]);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		else{
+			//物理删除
+			try {
+				self::destroy($id);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		return to_assign();
+    }
+}
+

+ 108 - 0
app/adm/model/NoteCate.php

@@ -0,0 +1,108 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+namespace app\adm\model;
+use think\model;
+use think\facade\Db;
+class NoteCate extends Model
+{
+    /**
+    * 获取分页列表
+    * @param $where
+    * @param $param
+    */
+    public function datalist($where, $param)
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {
+            $list = self::where($where)->order($order)->paginate(['list_rows'=> $rows]);
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+
+    /**
+    * 添加数据
+    * @param $param
+    */
+    public function add($param)
+    {
+		$insertId = 0;
+        try {
+			$param['create_time'] = time();
+			$insertId = self::strict(false)->field(true)->insertGetId($param);
+			add_log('add', $insertId, $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['aid'=>$insertId]);
+    }
+
+    /**
+    * 编辑信息
+    * @param $param
+    */
+    public function edit($param)
+    {
+        try {
+            $param['update_time'] = time();
+            self::where('id', $param['id'])->strict(false)->field(true)->update($param);
+			add_log('edit', $param['id'], $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign();
+    }
+	
+    /**
+    * 根据id获取信息
+    * @param $id
+    */
+    public function getById($id)
+    {
+        $info = self::find($id);
+		return $info;
+    }
+
+    /**
+    * 删除信息
+    * @param $id
+    * @param $type
+    * @return array
+    */
+    public function delById($id,$type=0)
+    {
+		if($type==0){
+			//逻辑删除
+			try {
+				$param['delete_time'] = time();
+				self::where('id', $id)->update(['delete_time'=>time()]);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		else{
+			//物理删除
+			try {
+				self::destroy($id);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		return to_assign();
+    }
+}
+

+ 145 - 0
app/adm/model/OfficialDocs.php

@@ -0,0 +1,145 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+namespace app\adm\model;
+use think\model;
+use think\facade\Db;
+class OfficialDocs extends Model
+{
+	//密级程度
+	public static $Secrets = ['','公开','秘密','机密'];
+	
+	//紧急程度
+	public static $Urgency = ['','普通','紧急','加急'];
+    /**
+    * 获取分页列表
+    * @param $where
+    * @param $param
+    */
+    public function datalist($param=[],$where=[],$whereOr=[])
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {
+            $list = self::where($where)
+			->where(function ($query) use($whereOr) {
+				if (!empty($whereOr)){
+					$query->whereOr($whereOr);
+				}
+			})
+			->order($order)
+			->paginate(['list_rows'=> $rows])
+			->each(function ($item, $key){
+				$item->secrets_str = self::$Secrets[$item->secrets];
+				$item->urgency_str = self::$Urgency[$item->urgency];
+				$item->check_status_str = check_status_name($item->check_status);
+				$item->draft_time = date('Y-m-d', $item->draft_time);
+				$item->draft_name = Db::name('Admin')->where('id','=',$item->draft_uid)->value('name');
+				$item->draft_dname = Db::name('Department')->where('id','=',$item->did)->value('title');
+				$item->create_time = to_date($item->create_time);
+			});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+    /**
+    * 添加数据
+    * @param $param
+    */
+    public function add($param)
+    {
+		$insertId = 0;
+        try {
+			$param['create_time'] = time();
+			$insertId = self::strict(false)->field(true)->insertGetId($param);
+			add_log('add', $insertId, $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['aid'=>$insertId]);
+    }
+
+    /**
+    * 编辑信息
+    * @param $param
+    */
+    public function edit($param)
+    {
+        try {
+            $param['update_time'] = time();
+            self::where('id', $param['id'])->strict(false)->field(true)->update($param);
+			add_log('edit', $param['id'], $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign();
+    }
+	
+    /**
+    * 根据id获取信息
+    * @param $id
+    */
+    public function getById($id)
+    {
+        $info = self::find($id);
+		$info['draft_name'] = Db::name('Admin')->where('id','=',$info['draft_uid'])->value('name');
+		$info['draft_dame'] = Db::name('Department')->where('id','=',$info['did'])->value('title');
+		
+		$send_names = Db::name('Admin')->where([['id','in',$info['send_uids']]])->column('name');
+		$info['send_names'] =implode(',' ,$send_names);
+		
+		$copy_names = Db::name('Admin')->where([['id','in',$info['copy_uids']]])->column('name');
+		$info['copy_names'] =implode(',' ,$copy_names);
+		
+		$share_names = Db::name('Admin')->where([['id','in',$info['share_uids']]])->column('name');
+		$info['share_names'] =implode(',' ,$share_names);
+		
+		if(!empty($info['file_ids'])){
+			$file_array = Db::name('File')->where('id','in',$info['file_ids'])->select();
+			$info['file_array'] = $file_array;
+		}
+		
+		return $info;
+    }
+
+    /**
+    * 删除信息
+    * @param $id
+    * @param $type
+    * @return array
+    */
+    public function delById($id,$type=0)
+    {
+		if($type==0){
+			//逻辑删除
+			try {
+				$param['delete_time'] = time();
+				self::where('id', $id)->update(['delete_time'=>time()]);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		else{
+			//物理删除
+			try {
+				self::destroy($id);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		return to_assign();
+    }
+}
+

+ 135 - 0
app/adm/model/Property.php

@@ -0,0 +1,135 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\model;
+use think\model;
+use think\facade\Db;
+class Property extends Model
+{
+	//资产来源
+	public static $property_source = ['','采购','赠与','自产','其他'];
+	
+	//资产状态
+	public static $property_status = ['闲置','在用','维修','报废','丢失'];
+    /**
+    * 获取分页列表
+    * @param $where
+    * @param $param
+    */
+    public function datalist($where, $param)
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'p.id desc' : $param['order'];
+        try {			
+            $list = self::where($where)
+				->field('p.*,pc.title as cate,pb.title as brand,pu.title as unit,u.name as create_name')
+				->alias('p')
+				->join('PropertyCate pc', 'pc.id = p.cate_id', 'left')
+				->join('PropertyBrand pb', 'pb.id = p.brand_id', 'left')
+				->join('PropertyUnit pu', 'pu.id = p.unit_id', 'left')
+				->join('Admin u', 'u.id = p.admin_id', 'left')
+				->order($order)
+				->paginate(['list_rows'=> $rows])
+				->each(function ($item, $key){
+					$item->update_time_str = '-';
+					$item->update_name = '-';
+					if(!empty($item->update_time)){
+						$item->update_time_str = $item->update_time;
+						$item->update_name = Db::name('Admin')->where('id',$item->update_id)->value('name');
+					}
+					$item->status_str = self::$property_status[$item->status];
+					$item->source_str = self::$property_source[$item->source];
+					$item->create_time = to_date($item->create_time);
+					$item->update_time_str = to_date($item->update_time);
+				});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+
+    /**
+    * 添加数据
+    * @param $param
+    */
+    public function add($param)
+    {
+		$insertId = 0;
+        try {
+			$param['create_time'] = time();
+			$insertId = self::strict(false)->field(true)->insertGetId($param);
+			add_log('add', $insertId, $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['aid'=>$insertId]);
+    }
+
+    /**
+    * 编辑信息
+    * @param $param
+    */
+    public function edit($param)
+    {
+        try {
+            $param['update_time'] = time();
+            self::where('id', $param['id'])->strict(false)->field(true)->update($param);
+			add_log('edit', $param['id'], $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign();
+    }	
+
+    /**
+    * 根据id获取信息
+    * @param $id
+    */
+    public function getById($id)
+    {
+        $info = self::find($id);
+		$info['status_str'] = self::$property_status[$info['status']];
+		$info['source_str'] = self::$property_source[$info['source']];
+		return $info;
+    }
+
+    /**
+    * 删除信息
+    * @param $id
+    * @param $type
+    * @return array
+    */
+    public function delById($id,$type=0)
+    {
+		if($type==0){
+			//逻辑删除
+			try {
+				$param['delete_time'] = time();
+				self::where('id', $id)->update(['delete_time'=>time()]);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		else{
+			//物理删除
+			try {
+				self::destroy($id);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		return to_assign();
+    }
+}

+ 154 - 0
app/adm/model/Seal.php

@@ -0,0 +1,154 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+namespace app\adm\model;
+use think\model;
+use think\facade\Db;
+class Seal extends Model
+{
+    /**
+    * 获取分页列表
+    * @param $where
+    * @param $param
+    */
+    public function datalist($where, $whereOr, $param)
+    {
+		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
+		$order = empty($param['order']) ? 'id desc' : $param['order'];
+        try {
+            $list = self::where($where)
+			->where(function ($query) use($whereOr) {
+				if (!empty($whereOr)){
+					$query->whereOr($whereOr);
+				}
+			})
+			->order($order)
+			->paginate(['list_rows'=> $rows])
+			->each(function ($item, $key){
+				$item->check_status_str = check_status_name($item->check_status);
+				$item->use_time = date('Y-m-d', $item->use_time);
+				$item->admin_name = Db::name('Admin')->where('id','=',$item->admin_id)->value('name');
+				$item->use_dname = Db::name('Department')->where('id','=',$item->did)->value('title');
+				$item->seal_cate = Db::name('SealCate')->where('id','=',$item->seal_cate_id)->value('title');
+				$item->create_time = to_date($item->create_time);
+			});
+			return $list;
+        } catch(\Exception $e) {
+            return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
+        }
+    }
+    /**
+    * 添加数据
+    * @param $param
+    */
+    public function add($param)
+    {
+		$insertId = 0;
+        try {
+			$param['create_time'] = time();
+			$insertId = self::strict(false)->field(true)->insertGetId($param);
+			add_log('add', $insertId, $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['return_id'=>$insertId]);
+    }
+
+    /**
+    * 编辑信息
+    * @param $param
+    */
+    public function edit($param)
+    {
+        try {
+            $param['update_time'] = time();
+            self::where('id', $param['id'])->strict(false)->field(true)->update($param);
+			add_log('edit', $param['id'], $param);
+        } catch(\Exception $e) {
+			return to_assign(1, '操作失败,原因:'.$e->getMessage());
+        }
+		return to_assign(0,'操作成功',['return_id'=> $param['id']]);
+    }
+	
+    /**
+    * 根据id获取信息
+    * @param $id
+    */
+    public function getById($id)
+    {
+        $info = self::find($id);
+		$info['admin_name'] = Db::name('Admin')->where('id','=',$info['admin_id'])->value('name');
+		$info['use_dname'] = Db::name('Department')->where('id','=',$info['did'])->value('title');
+		$info['seal_cate'] = Db::name('SealCate')->where('id','=',$info['seal_cate_id'])->value('title');
+		if($info['start_time']>0){
+			$info['start_time'] = date('Y-m-d',$info['start_time']);
+			$info['end_time'] = date('Y-m-d',$info['end_time']);
+		}
+		else{
+			$info['start_time'] = '';
+			$info['end_time'] = '';	
+		}
+		if($info['use_time']>0){
+			$info['use_time'] = date('Y-m-d',$info['use_time']);
+		}
+		else{
+			$info['use_time'] = '';
+		}
+		$status_str = '未使用';
+		if($info['status'] == 1){
+			$status_str = '已使用';
+			if($info['is_borrow']==1){
+				$status_str = '已外借';
+			}
+		}
+		if($info['status'] == 2){
+			$status_str = '已归还';
+		}
+		$info['status_str'] = $status_str;
+		if(!empty($info['file_ids'])){
+			$file_array = Db::name('File')->where('id','in',$info['file_ids'])->select();
+			$info['file_array'] = $file_array;
+		}
+		return $info;
+    }
+
+    /**
+    * 删除信息
+    * @param $id
+    * @param $type
+    * @return array
+    */
+    public function delById($id,$type=0)
+    {
+		if($type==0){
+			//逻辑删除
+			try {
+				$param['delete_time'] = time();
+				self::where('id', $id)->update(['delete_time'=>time()]);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		else{
+			//物理删除
+			try {
+				self::destroy($id);
+				add_log('delete', $id);
+			} catch(\Exception $e) {
+				return to_assign(1, '操作失败,原因:'.$e->getMessage());
+			}
+		}
+		return to_assign();
+    }
+}
+

+ 34 - 0
app/adm/validate/BasicAdmCheck.php

@@ -0,0 +1,34 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+
+use think\Validate;
+
+class BasicAdmCheck extends Validate
+{
+    protected $rule = [
+        'title' => 'require',
+        'id' => 'require',
+    ];
+
+    protected $message = [
+        'title.require' => '名称不能为空',
+        'id.require' => '缺少更新条件',
+    ];
+
+    protected $scene = [
+        'add' => ['title'],
+        'edit' => ['id', 'title'],
+    ];
+}

+ 43 - 0
app/adm/validate/CarValidate.php

@@ -0,0 +1,43 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+use think\Validate;
+use think\facade\Db;
+
+class CarValidate extends Validate
+{
+	// 自定义验证规则
+	protected function checkOne($value,$rule,$data=[])
+	{
+		$id = isset($data['id'])?$data['id']:0;
+		$count = Db::name('Car')->where([['title','=',$data['title']],['id','<>',$id],['delete_time','=',0]])->count();
+		return $count == 0 ? true : false;
+	}
+	
+    protected $rule = [
+		'title' => 'require|checkOne',
+		'id' => 'require',
+	];
+
+    protected $message = [
+		'title.require' => '名称不能为空',
+		'title.checkOne' => '同样的名称已经存在',
+		'id.require' => '缺少更新条件',
+	];
+	
+    protected $scene = [
+        'add' => ['title'],
+        'edit' => ['title', 'id'],
+    ];
+}

+ 35 - 0
app/adm/validate/CateCheck.php

@@ -0,0 +1,35 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+
+use think\Validate;
+
+class CateCheck extends Validate
+{
+    protected $rule = [
+        'title' => 'require|unique:property_cate',
+        'id' => 'require',
+    ];
+
+    protected $message = [
+        'title.require' => '名称不能为空',
+        'title.unique' => '同样的名称已经存在',
+        'id.require' => '缺少更新条件',
+    ];
+
+    protected $scene = [
+        'add' => ['title'],
+        'edit' => ['id', 'title'],
+    ];
+}

+ 57 - 0
app/adm/validate/FlowCateCheck.php

@@ -0,0 +1,57 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+
+use think\Validate;
+use think\facade\Db;
+
+class FlowCateCheck extends Validate
+{
+	// 自定义验证规则
+	protected function checkOne($value,$rule,$data=[])
+	{
+		$id = isset($data['id'])?$data['id']:0;
+		$table_array = ['invoice','ticket','approve'];
+		if(in_array($data['check_table'],$table_array)){
+			return true;
+		}
+		else{
+			$count = Db::name('FlowCate')->where([['check_table','=',$data['check_table']],['id','<>',$id]])->count();
+			return $count == 0 ? true : false;
+		}
+	}
+	
+    protected $rule = [
+        'title' => 'require',
+        'name' => 'require|alphaDash|unique:flow_cate',
+        'check_table' => 'require|alphaDash|checkOne',
+        'id' => 'require',
+    ];
+
+    protected $message = [
+        'title.require' => '审批类型名称不能为空',
+        'name.require' => '审批类型标识不能为空',
+        'name.unique' => '同样的审批类型标识已经存在',
+		'name.alphaDash' => '审批类型标识只能是小写字母',
+        'check_table.require' => '数据表不能为空',
+        'check_table.alphaDash' => '数据表只能是小写字母、数字下划线_',
+        'check_table.checkOne' => '同样的数据表已经存在',
+        'id.require' => '缺少更新条件',
+    ];
+
+    protected $scene = [
+        'add' => ['title','check_table'],
+        'edit' => ['id', 'title','check_table'],
+    ];
+}

+ 34 - 0
app/adm/validate/FlowCheck.php

@@ -0,0 +1,34 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+
+use think\Validate;
+
+class FlowCheck extends Validate
+{
+    protected $rule = [
+        'title' => 'require',
+        'id' => 'require',
+    ];
+
+    protected $message = [
+        'title.require' => '流程名称不能为空',
+        'id.require' => '缺少更新条件',
+    ];
+
+    protected $scene = [
+        'add' => ['title',],
+        'edit' => ['id','title'],
+    ];
+}

+ 35 - 0
app/adm/validate/MeetingCateCheck.php

@@ -0,0 +1,35 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+
+use think\Validate;
+
+class MeetingCateCheck extends Validate
+{
+    protected $rule = [
+        'title' => 'require|unique:meeting_cate',
+        'id' => 'require',
+    ];
+
+    protected $message = [
+        'title.require' => '名称不能为空',
+        'title.unique' => '同样的名称已经存在',
+        'id.require' => '缺少更新条件',
+    ];
+
+    protected $scene = [
+        'add' => ['title'],
+        'edit' => ['id', 'title'],
+    ];
+}

+ 43 - 0
app/adm/validate/NewsValidate.php

@@ -0,0 +1,43 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+use think\Validate;
+use think\facade\Db;
+
+class NewsValidate extends Validate
+{
+	// 自定义验证规则
+	protected function checkOne($value,$rule,$data=[])
+	{
+		$id = isset($data['id'])?$data['id']:0;
+		$count = Db::name('News')->where([['title','=',$data['title']],['id','<>',$id],['delete_time','=',0]])->count();
+		return $count == 0 ? true : false;
+	}
+	
+    protected $rule = [
+		'title' => 'require|checkOne',
+		'id' => 'require',
+	];
+
+    protected $message = [
+		'title.require' => '名称不能为空',
+		'title.checkOne' => '同样的名称已经存在',
+		'id.require' => '缺少更新条件',
+	];
+	
+    protected $scene = [
+        'add' => ['title'],
+        'edit' => ['title', 'id'],
+    ];
+}

+ 43 - 0
app/adm/validate/NoteValidate.php

@@ -0,0 +1,43 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+use think\Validate;
+use think\facade\Db;
+
+class NoteValidate extends Validate
+{
+	// 自定义验证规则
+	protected function checkOne($value,$rule,$data=[])
+	{
+		$id = isset($data['id'])?$data['id']:0;
+		$count = Db::name('Note')->where([['title','=',$data['title']],['id','<>',$id],['delete_time','=',0]])->count();
+		return $count == 0 ? true : false;
+	}
+	
+    protected $rule = [
+		'title' => 'require|checkOne',
+		'id' => 'require',
+	];
+
+    protected $message = [
+		'title.require' => '名称不能为空',
+		'title.checkOne' => '同样的名称已经存在',
+		'id.require' => '缺少更新条件',
+	];
+	
+    protected $scene = [
+        'add' => ['title'],
+        'edit' => ['title', 'id'],
+    ];
+}

+ 43 - 0
app/adm/validate/NotecateValidate.php

@@ -0,0 +1,43 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+use think\Validate;
+use think\facade\Db;
+
+class NotecateValidate extends Validate
+{
+	// 自定义验证规则
+	protected function checkOne($value,$rule,$data=[])
+	{
+		$id = isset($data['id'])?$data['id']:0;
+		$count = Db::name('NoteCate')->where([['title','=',$data['title']],['id','<>',$id],['delete_time','=',0]])->count();
+		return $count == 0 ? true : false;
+	}
+	
+    protected $rule = [
+		'title' => 'require|checkOne',
+		'id' => 'require',
+	];
+
+    protected $message = [
+		'title.require' => '名称不能为空',
+		'title.checkOne' => '同样的名称已经存在',
+		'id.require' => '缺少更新条件',
+	];
+	
+    protected $scene = [
+        'add' => ['title'],
+        'edit' => ['title', 'id'],
+    ];
+}

+ 35 - 0
app/adm/validate/PropertyCheck.php

@@ -0,0 +1,35 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+
+use think\Validate;
+
+class PropertyCheck extends Validate
+{
+    protected $rule = [
+        'title' => 'require|unique:property',
+        'id' => 'require',
+    ];
+
+    protected $message = [
+        'title.require' => '名称不能为空',
+        'title.unique' => '同样的名称已经存在',
+        'id.require' => '缺少更新条件',
+    ];
+
+    protected $scene = [
+        'add' => ['title'],
+        'edit' => ['id', 'title'],
+    ];
+}

+ 35 - 0
app/adm/validate/SealCateCheck.php

@@ -0,0 +1,35 @@
+<?php
+/**
++-----------------------------------------------------------------------------------------------
+* GouGuOPEN [ 左手研发,右手开源,未来可期!]
++-----------------------------------------------------------------------------------------------
+* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
++-----------------------------------------------------------------------------------------------
+* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
++-----------------------------------------------------------------------------------------------
+* @Author 勾股工作室 <hdm58@qq.com>
++-----------------------------------------------------------------------------------------------
+*/
+
+namespace app\adm\validate;
+
+use think\Validate;
+
+class SealCateCheck extends Validate
+{
+    protected $rule = [
+        'title' => 'require|unique:seal_cate',
+        'id' => 'require',
+    ];
+
+    protected $message = [
+        'title.require' => '名称不能为空',
+        'title.unique' => '同样的名称已经存在',
+        'id.require' => '缺少更新条件',
+    ];
+
+    protected $scene = [
+        'add' => ['title'],
+        'edit' => ['id', 'title'],
+    ];
+}

+ 138 - 0
app/adm/view/basic/datalist.html

@@ -0,0 +1,138 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-3">
+    <div class="layui-card">
+		<div class="body-table layui-tab layui-tab-brief" lay-filter="tab">
+			<ul class="layui-tab-title" style="border-bottom:none;">
+				<li class="layui-this" data-index="1">车辆费用类型</li>
+				<li data-index="2">其他</li>
+			</ul>
+			<div class="layui-tab-content" style="padding:0">
+				<table class="layui-hide" id="test" lay-filter="test"></table>
+			</div>
+		</div> 
+	</div> 
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm add-new" type="button">+ 新增内容</button>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+	<script>
+	const moduleInit = ['tool'];
+	function gouguInit() {
+		var table = layui.table, tool = layui.tool, element = layui.element,form = layui.form;
+		var data_type=1;
+		element.on('tab(tab)', function(data){
+			data_type = data.index+1;
+			layui.pageTable.reload({where:{types:data_type},page:{curr:1}});
+			return false;
+		});
+		
+		layui.pageTable = table.render({
+			elem: '#test'
+			,toolbar: '#toolbarDemo'
+			,title:'基础数据列表'
+			,url: "/adm/basic/datalist"
+			,where:{types:data_type}
+			,page: false
+			,cellMinWidth: 80
+			,cols: [[
+					{field:'id',width:80, title: 'ID号', align:'center'}
+					,{field:'title',title: '名称'}
+					,{field:'status', title: '状态',width:80,align:'center',templet: function(d){
+						var html1='<span class="green">正常</span>';
+						var html2='<span class="yellow">禁用</span>';
+						if(d.status==1){
+							return html1;
+						}
+						else{
+							return html2;
+						}
+					}}
+					,{width:100,title: '操作', align:'center',templet: function(d){
+						var html='';
+						var btn='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>';
+						var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
+						var btn2='<a class="layui-btn layui-btn-xs" lay-event="open">启用</a>';
+						if(d.status==1){
+							html = '<div class="layui-btn-group">'+btn+btn1+'</div>';
+						}
+						else{
+							html = '<div class="layui-btn-group">'+btn+btn2+'</div>';
+						}
+						return html;
+					}}
+				]]
+			});
+			
+			table.on('tool(test)',function (obj) {
+				if(obj.event === 'edit'){					
+					addExpense(obj.data.id,obj.data.title);
+				}
+				if(obj.event === 'disable'){
+					layer.confirm('确定要禁用该数据吗?', {icon: 3, title:'提示'}, function(index){
+						let callback = function (e) {
+							layer.msg(e.msg);
+							if (e.code == 0) {
+								layui.pageTable.reload();
+							}
+						}
+						tool.post("/adm/basic/set", { id: obj.data.id,status: 0,title: obj.data.title}, callback);
+						layer.close(index);
+					});
+				}
+				if(obj.event === 'open'){
+					layer.confirm('确定要启用该数据吗?', {icon: 3, title:'提示'}, function(index){
+						let callback = function (e) {
+							layer.msg(e.msg);
+							if (e.code == 0) {
+								layui.pageTable.reload();
+							}
+						}
+						tool.post("/adm/basic/set", { id: obj.data.id,status: 1,title: obj.data.title}, callback);
+						layer.close(index);
+					});
+				}
+			});
+			
+			$('body').on('click','.add-new',function(){
+				addExpense(0,'');	
+			});
+			
+			function addExpense(id,val){
+				var title = '新增内容';
+				if(id>0){
+					title = '编辑内容';
+				}
+				layer.prompt({
+					title: title,
+					value: val,
+					yes: function(index, layero) {
+						// 获取文本框输入的值
+						var value = layero.find(".layui-layer-input").val();
+						if (value) {
+							let callback = function (e) {
+								layer.msg(e.msg);
+								if (e.code == 0) {
+									layui.pageTable.reload();				
+								}
+							}
+							tool.post("/adm/basic/add", {id: id,types:data_type,title: value}, callback);
+							layer.close(index);
+						} else {
+							layer.msg('请填写内容');
+						}
+					}
+				})
+			}
+		}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 120 - 0
app/adm/view/car/add.html

@@ -0,0 +1,120 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">添加车辆信息</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">车辆名称<font>*</font></td>
+			<td><input type="text" name="title" autocomplete="off" placeholder="请输入车辆名称" lay-verify="required" lay-reqText="请输入车辆名称" class="layui-input"></td>
+			<td class="layui-td-gray">车牌号码<font>*</font></td>
+			<td><input type="text" name="name" autocomplete="off" placeholder="请输入车牌号码" lay-verify="required" lay-reqText="请输入车牌号码" class="layui-input"></td>
+			<td class="layui-td-gray-2" rowspan="5">
+				车辆缩略图
+				<button type="button" class="layui-btn layui-btn-sm" id="uploadImg">+ 上传图片</button>
+			</td>
+			<td rowspan="5" style="width:252px;">
+				  <div id="demo1" style="width: 240px; height:136px; overflow: hidden;">
+					<img src="" style="max-width: 100%; height:136px;" />
+					<input type="hidden" name="thumb" value="">
+				  </div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">购买日期<font>*</font></td>
+			<td><input type="text" name="buy_time" value='' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择购买日期" class="layui-input tool-time" data-max="0"></td>
+			<td class="layui-td-gray-2">购买价格<font>*</font></td>
+			<td><input type="text" name="price" value='' placeholder="请输入购买价格" lay-verify="required|number" lay-reqText="请输入购买价格" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">车身颜色<font>*</font></td>
+			<td><input type="text" name="color" value='' placeholder="请输入车身颜色" lay-verify="required" lay-reqText="请输入车身颜色" class="layui-input"></td>
+			<td class="layui-td-gray">座位数<font>*</font></td>
+			<td><input type="text" name="seats" autocomplete="off" placeholder="请输入座位数" lay-verify="required|number" lay-reqText="请输入座位数" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">发动机号<font>*</font></td>
+			<td><input type="text" name="engine" autocomplete="off" placeholder="请输入发动机号" lay-verify="required" lay-reqText="请输入发动机号" class="layui-input"></td>
+			<td class="layui-td-gray-2">车架号<font>*</font></td>
+			<td><input type="text" name="vin" value='' placeholder="请输入车架号" lay-verify="required" lay-reqText="请输入车架号" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">车险到期日期<font>*</font></td>
+			<td><input type="text" name="insure_time" value='' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择车险到期日期" class="layui-input tool-time"></td>
+			<td class="layui-td-gray-2">车审到期日期<font>*</font></td>
+			<td><input type="text" name="review_time" value='' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择车审到期日期" class="layui-input tool-time"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">车辆油耗<font>*</font></td>
+			<td><input type="text" name="oil" autocomplete="off" placeholder="请输入油耗" lay-verify="required" lay-reqText="请输入油耗" class="layui-input"></td>
+			<td class="layui-td-gray-2">开始里程数<font>*</font></td>
+			<td><input type="text" name="mileage" value='' placeholder="请输入开始里程数" lay-verify="required|number" lay-reqText="请输入开始里程数" class="layui-input"></td>
+			<td class="layui-td-gray-2">驾驶员</td>
+			<td><input type="text" name="driver_name" value='' readonly placeholder="请选择"class="layui-input picker-admin"><input type="hidden" name="driver" value='0'></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="">
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">备注信息</td>
+			<td colspan="5">
+				<textarea name="remark" placeholder="请输入备注信息" class="layui-textarea"></textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','uploadPlus','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,uploadPlus= layui.uploadPlus;	
+		//单图上传
+		var photoUpload = new uploadPlus({
+			'use':'single',
+			'target':'uploadImg',
+			'callback':function(res){
+				layer.msg(res.msg);
+				if (res.code == 0) {
+					//上传成功
+					$('#demo1 input').attr('value', res.data.id);
+					$('#demo1 img').attr('src', res.data.filepath);
+				}
+			}
+		});
+
+		//相关附件上传
+		var attachment = new uploadPlus();
+		//监听提交
+		form.on('submit(webform)', function(data){
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);				
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/car/add", data.field, callback,clickbtn);
+			return false;
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 110 - 0
app/adm/view/car/datalist.html

@@ -0,0 +1,110 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="车辆名称/车牌号码" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="table_car" lay-filter="table_car"></table>
+</div>
+
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/adm/car/add">+ 添加车辆</button>
+  </div>
+</script>
+
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','tablePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool;
+		
+		layui.pageTable = table.render({
+			elem: "#table_car"
+			, toolbar: "#toolbarDemo"
+			,url: "/adm/car/datalist"
+			,page: true
+			,limit: 20
+			,cellMinWidth: 60
+			,height: 'full-114'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'title',title: '车辆名称',width:120}
+				,{field:'name',title: '车牌号码',width:100, align:'center'}
+				,{field:'buy_time',title: '购买日期',width:100, align:'center'}
+				,{field:'price',title: '购买价格',width:100, align:'center'}
+				,{field:'color',title: '车身颜色',width:80, align:'center'}
+				,{field:'seats',title: '座位数',width:60, align:'center'}
+				,{field:'driver_name',title: '驾驶员',width:80, align:'center'}
+				,{field:'oil',title: '油耗',width:60, align:'center'}
+				,{field:'mileage',title: '开始里程数',width:100, align:'center'}
+				,{field:'mileage_now',title: '当前里程数',width:100, align:'center'}
+				,{field:'insure_time',title: '保险到期日期',width:110, align:'center'}
+				,{field:'insure_time_note',title: '保险到期提醒',width:110, align:'center',templet: function(d){
+					var html = '<span class="red">还剩 '+d.insure_time_note+' 天</div>';
+					if(d.insure_time_note==0){
+						html = '<span class="red">已到期</div>';
+					}
+					return html;
+				}}
+				,{field:'review_time',title: '车审到期日期',width:110, align:'center'}
+				,{field:'review_time_note',title: '车审到期提醒',width:110, align:'center',templet: function(d){
+					var html = '<span class="red">还剩 '+d.review_time_note+' 天</div>';
+					if(d.review_time_note==0){
+						html = '<span class="red">已到期</div>';
+					}
+					return html;
+				}}
+				,{field:'create_time', title: '创建时间',width:150,align:'center'}
+				,{width:120,fixed:'right',title: '操作', align:'center',templet: function(d){
+					var html='';
+					var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>';
+					var btn2='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>';
+					var btn3='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>';
+					html = '<div class="layui-btn-group">'+btn1+btn2+btn3+'</div>';
+					return html;
+				}}
+			]]
+		});
+			
+		table.on('tool(table_car)',function (obj) {
+			var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
+			var data = obj.data;
+			if (obj.event === 'view') {
+				tool.side("/adm/car/view?id="+data.id);
+				return;
+			}
+			if (obj.event === 'edit') {
+				tool.side("/adm/car/add?id="+data.id);
+				return;
+			}
+			if (obj.event === 'del') {
+				layer.confirm('确定要删除该内容吗?', { icon: 3, title: '提示' }, function (index) {
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							obj.del();
+						}
+					}
+					tool.delete("/adm/car/del", { id: data.id }, callback);
+					layer.close(index);
+				});
+				return;
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 126 - 0
app/adm/view/car/edit.html

@@ -0,0 +1,126 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">编辑车辆信息</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">车辆名称<font>*</font></td>
+			<td><input type="text" name="title" value="{$detail.title}" autocomplete="off" placeholder="请输入车辆名称" lay-verify="required" lay-reqText="请输入车辆名称" class="layui-input"></td>
+			<td class="layui-td-gray">车牌号码<font>*</font></td>
+			<td><input type="text" name="name" value="{$detail.name}" autocomplete="off" placeholder="请输入车牌号码" lay-verify="required" lay-reqText="请输入车牌号码" class="layui-input"></td>
+			<td class="layui-td-gray-2" rowspan="5">
+				车辆缩略图
+				<button type="button" class="layui-btn layui-btn-sm" id="uploadImg">+ 上传图片</button>
+			</td>
+			<td rowspan="5" style="width:252px;">
+			    <div id="demo1" style="width: 240px; height:136px; overflow: hidden;">
+					<img src="{:get_file($detail.thumb)}" style="max-width: 100%; height:136px;" />
+					<input type="hidden" name="thumb" value="{$detail.thumb}">
+			    </div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">购买日期<font>*</font></td>
+			<td><input type="text" name="buy_time" value="{$detail.buy_time|date='Y-m-d'}" readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择购买日期" class="layui-input tool-time"  data-max="0"></td>
+			<td class="layui-td-gray-2">购买价格(元)<font>*</font></td>
+			<td><input type="text" name="price" value="{$detail.price}" placeholder="请输入购买价格" lay-verify="required|number" lay-reqText="请输入购买价格" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">车身颜色<font>*</font></td>
+			<td><input type="text" name="color" value="{$detail.color}" placeholder="请输入车身颜色" lay-verify="required" lay-reqText="请输入车身颜色" class="layui-input"></td>
+			<td class="layui-td-gray">座位数<font>*</font></td>
+			<td><input type="text" name="seats" value="{$detail.seats}" autocomplete="off" placeholder="请输入座位数" lay-verify="required|number" lay-reqText="请输入座位数" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">发动机号<font>*</font></td>
+			<td><input type="text" name="engine" value="{$detail.engine}" autocomplete="off" placeholder="请输入发动机号" lay-verify="required" lay-reqText="请输入发动机号" class="layui-input"></td>
+			<td class="layui-td-gray-2">车架号<font>*</font></td>
+			<td><input type="text" name="vin" value="{$detail.vin}" placeholder="请输入车架号" lay-verify="required" lay-reqText="请输入车架号" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">车险到期日期<font>*</font></td>
+			<td><input type="text" name="insure_time" value="{$detail.insure_time|date='Y-m-d'}" readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择车险到期日期" class="layui-input tool-time"></td>
+			<td class="layui-td-gray-2">车审到期日期<font>*</font></td>
+			<td><input type="text" name="review_time" value="{$detail.review_time|date='Y-m-d'}" readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择车审到期日期" class="layui-input tool-time"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">车辆油耗<font>*</font></td>
+			<td><input type="text" name="oil" value="{$detail.oil}" autocomplete="off" placeholder="请输入油耗" lay-verify="required" lay-reqText="请输入油耗" class="layui-input"></td>
+			<td class="layui-td-gray-2">开始里程数</td>
+			<td>{$detail.mileage}</td>
+			<td class="layui-td-gray-2">驾驶员</td>
+			<td><input type="text" name="driver_name" value="{$detail.driver_name|default=''}" readonly placeholder="请选择"class="layui-input picker-admin"><input type="hidden" name="driver" value="{$detail.driver}"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids}">
+					{notempty name="$detail.file_ids"}
+					{volist name="$detail.file_array" id="vo"}
+						<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo)}</div>
+					{/volist}
+					{/notempty}
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">备注信息</td>
+			<td colspan="5">
+				<textarea name="remark" placeholder="请输入备注信息" class="layui-textarea">{$detail.remark|default=''}</textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		<input type="hidden" name="id" value="{$detail.id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','uploadPlus','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,uploadPlus= layui.uploadPlus;	
+		//单图上传
+		var photoUpload = new uploadPlus({
+			'use':'single',
+			'target':'uploadImg',
+			'callback':function(res){
+				layer.msg(res.msg);
+				if (res.code == 0) {
+					//上传成功
+					$('#demo1 input').attr('value', res.data.id);
+					$('#demo1 img').attr('src', res.data.filepath);
+				}
+			}
+		});
+
+		//相关附件上传
+		var attachment = new uploadPlus();
+		//监听提交
+		form.on('submit(webform)', function(data){
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);				
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/car/add", data.field, callback,clickbtn);
+			return false;
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 111 - 0
app/adm/view/car/fee_add.html

@@ -0,0 +1,111 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">新增车辆收费记录</h3>
+	<table class="layui-table layui-table-form">
+		{eq name="$cid" value="0"}
+		<tr>
+			<td class="layui-td-gray">车辆名称<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="car_name" readonly lay-verify="required" lay-reqText="请选择车辆" placeholder="请选择" class="layui-input picker-oa" data-types="car">
+				<input type="hidden" name="car_id" value="">
+			</td>
+			<td class="layui-td-gray">费用类型<font>*</font></td>
+			<td>
+				<select name="types" lay-verify="required" lay-reqText="选择费用类型">
+				<option value="">选择费用类型</option>
+				{volist name=":get_base_data('basicAdm')" id="vo"}
+					<option value="{$vo.id}">{$vo.title}</option>
+				{/volist}
+			</select>
+			</td>
+		</tr>
+		{else/}
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td colspan="3">{$car.title}</td>
+			<td class="layui-td-gray">费用类型<font>*</font></td>
+			<td>
+				<select name="types" lay-verify="required" lay-reqText="选择费用类型">
+				<option value="">选择费用类型</option>
+				{volist name=":get_base_data('basicAdm')" id="vo"}
+					<option value="{$vo.id}">{$vo.title}</option>
+				{/volist}
+			</select>
+			</td>
+		</tr>
+		{/eq}
+		<tr>
+			<td class="layui-td-gray">费用主题<font>*</font></td>
+			<td colspan="5">
+				<input type="text" name="title" lay-verify="required" lay-reqText="请完善费用主题" placeholder="请完善费用主题" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">收费日期<font>*</font></td>
+			<td><input type="text" name="fee_time" readonly placeholder="请选择收费日期" class="layui-input tool-time" data-max="0"></td>
+			<td class="layui-td-gray">费用金额<font>*</font></td>
+			<td><input type="text" name="amount" placeholder="请输入费用金额" lay-verify="required|number" lay-reqText="请输入费用金额" class="layui-input"></td>
+			<td class="layui-td-gray">经手人<font>*</font></td>
+			<td>
+				<input type="text" name="handled_name" readonly lay-verify="required" lay-reqText="请选择经手人" placeholder="请选择" class="layui-input picker-admin">
+				<input type="hidden" name="handled">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="">
+				</div>
+			</td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">收费内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入收费内容" class="layui-textarea" lay-verify="required" lay-reqText="请完善收费内容"></textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		{gt name="$cid" value="0"}
+		<input type="hidden" name="car_id" value="{$cid}">
+		{/gt}
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','uploadPlus','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus;
+	//相关附件上传
+	var attachment = new uploadPlus();
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000,'feeTable');				
+			}
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/car/fee_add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 95 - 0
app/adm/view/car/fee_edit.html

@@ -0,0 +1,95 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">编辑车辆费用记录</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td colspan="3">{$detail.car}</td>
+			<td class="layui-td-gray">费用类型<font>*</font></td>
+			<td>
+				<select name="types" lay-verify="required" lay-reqText="选择费用类型">
+				<option value="">选择费用类型</option>
+				{volist name=":get_base_data('basicAdm')" id="vo"}
+					<option value="{$vo.id}" {eq name="$vo.id" value="$detail.types"} selected{/eq}>{$vo.title}</option>
+				{/volist}
+			</select>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">费用主题<font>*</font></td>
+			<td colspan="5">
+				<input type="text" name="title" value="{$detail.title}" lay-verify="required" lay-reqText="请完善费用主题" placeholder="请完善费用主题" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">费用日期<font>*</font></td>
+			<td><input type="text" name="fee_time" readonly value="{$detail.fee_time|date='Y-m-d'}" readonly placeholder="请选择费用日期" class="layui-input tool-time" lay-verify="required" lay-reqText="请完善费用日期"></td>
+			<td class="layui-td-gray">费用金额<font>*</font></td>
+			<td><input type="text" name="amount" value="{$detail.amount}" placeholder="请输入费用金额" lay-verify="required|number" lay-reqText="请输入费用金额" class="layui-input"></td>
+			<td class="layui-td-gray">经手人<font>*</font></td>
+			<td>
+				<input type="text" name="handled_name" value="{$detail.handled_name}" readonly lay-verify="required" lay-reqText="请选择经手人" class="layui-input picker-admin">
+				<input type="hidden" name="handled" value="{$detail.handled}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids}">
+					{notempty name="$detail.fileArray"}
+					{volist name="$detail.fileArray" id="vo"}
+					<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo)}</div>
+					{/volist}
+					{/notempty}
+				</div>
+			</td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">费用内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入费用内容" class="layui-textarea" lay-verify="required" lay-reqText="请完善收费内容">{$detail.content|default=''}</textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		<input type="hidden" name="id" value="{$detail.id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','uploadPlus','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus;
+	//相关附件上传
+	var attachment = new uploadPlus();
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000,'feeTable');				
+			}
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/car/fee_add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 94 - 0
app/adm/view/car/fee_list.html

@@ -0,0 +1,94 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px;">
+			<input type="text" class="layui-input" id="diff_time" placeholder="费用日期" readonly name="diff_time">
+		</div>
+		<div class="layui-input-inline" style="width:136px;">
+			<select name="types">
+				<option value="">选择费用类型</option>
+				{volist name=":get_base_data('basicAdm')" id="vo"}
+					<option value="{$vo.id}">{$vo.title}</option>
+				{/volist}
+			</select>
+		</div>
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="输入关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="test" lay-filter="test"></table>
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/adm/car/fee_add">+ 添加收费记录</button>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+	<script>
+	const moduleInit = ['tool','tablePlus','laydatePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool,form = layui.form,laydatePlus = layui.laydatePlus;	
+		var diff_time = new laydatePlus({'target':'diff_time'});		
+		
+		layui.feeTable = table.render({
+			elem: '#test'
+			,toolbar: '#toolbarDemo'
+			,title:'收费记录列表'
+			,url: "/adm/car/fee_list"
+			,is_excel: true
+			,page: true
+			,cellMinWidth: 60
+			,height: 'full-114'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'title',minWidth:300,title: '费用主题'}
+				,{field:'fee_time',title: '费用日期',align: 'center',width: 100}
+				,{field:'types_str',title: '费用类型',align: 'center',width: 100}
+				,{field:'amount',width:100, title: '费用金额(元)', align:'center',style:"color:#16b777"}
+				,{field:'car',width:120,title: '车辆名称'}
+				,{field:'name',width:100, title: '车牌号码', align:'center'}
+				,{field:'handled_name',title: '跟进人',align: 'center',width: 80}
+				,{field:'create_time',title: '记录时间',align: 'center',width: 130}
+				,{width:120,fixed:'right', title: '操作', align:'center',templet: function(d){
+					var html='<div class="layui-btn-group"><a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a><a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详情</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></div>';
+					return html;
+				}}
+			]]
+		});
+		
+		table.on('tool(test)',function (obj) {
+			var that = this;
+			if(obj.event === 'edit'){					
+				tool.side("/adm/car/fee_add?id="+obj.data.id);
+			}
+			if(obj.event === 'view'){					
+				tool.side("/adm/car/fee_view?id="+obj.data.id);
+			}
+			if(obj.event === 'del'){
+				layer.confirm('确定要删除该收费记录吗?', {icon: 3, title:'提示'}, function(index){
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							layui.feeTable.reload();
+						}
+					}
+					tool.post("/adm/car/fee_del", {id: obj.data.id}, callback);
+					layer.close(index);
+				});
+				return;
+			}
+		});
+	}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 56 - 0
app/adm/view/car/fee_view.html

@@ -0,0 +1,56 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">车辆收费记录</h3>
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td colspan="3">{$detail.car}</td>
+			<td class="layui-td-gray">收费地点</td>
+			<td>{$detail.types_str}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">费用主题</td>
+			<td colspan="5">{$detail.title}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">收费日期</td>
+			<td>{$detail.fee_time|date='Y-m-d'}</td>
+			<td class="layui-td-gray">收费费用</td>
+			<td>{$detail.amount}</td>
+			<td class="layui-td-gray">跟进人</td>
+			<td>{$detail.handled_name}</td>
+		</tr>
+		{notempty name="$detail.fileArray"}
+		<tr>
+			<td class="layui-td-gray">相关附件</div></td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">					
+					{volist name="$detail.fileArray" id="vo"}
+					<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo,'view')}</div>
+					{/volist}					
+				</div>
+			</td>
+		</tr>
+		{/notempty}
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">费用内容</td>
+			<td colspan="5">{$detail.content|default=''}</td>
+		</tr>
+	</table>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool;
+	
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 95 - 0
app/adm/view/car/protect_add.html

@@ -0,0 +1,95 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">新增车辆保养记录</h3>
+	<table class="layui-table layui-table-form">
+		{eq name="$cid" value="0"}
+		<tr>
+			<td class="layui-td-gray">车辆名称<font>*</font></td>
+			<td>
+				<input type="text" name="car_name" readonly lay-verify="required" lay-reqText="请选择车辆" placeholder="请选择" class="layui-input picker-oa" data-types="car">
+				<input type="hidden" name="car_id" value="">
+			</td>
+			<td class="layui-td-gray">保养地点<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="address" lay-verify="required" lay-reqText="请完善保养地点" placeholder="请完善保养地点" class="layui-input">
+			</td>
+		</tr>
+		{else/}
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td>{$car.title}</td>
+			<td class="layui-td-gray">保养地点<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="address" lay-verify="required" lay-reqText="请完善保养地点" placeholder="请完善保养地点" class="layui-input">
+			</td>
+		</tr>
+		{/eq}
+		<tr>
+			<td class="layui-td-gray">保养日期<font>*</font></td>
+			<td><input type="text" name="repair_time" readonly placeholder="请选择保养日期" class="layui-input tool-time" data-max="0" lay-verify="required" lay-reqText="请完善保养日期"></td>
+			<td class="layui-td-gray">保养费用<font>*</font></td>
+			<td><input type="text" name="amount" placeholder="请输入保养费用" lay-verify="required|number" lay-reqText="请输入保养费用" class="layui-input"></td>
+			<td class="layui-td-gray">经手人<font>*</font></td>
+			<td>
+				<input type="text" name="handled_name" readonly lay-verify="required" lay-reqText="请选择经手人" placeholder="请选择" class="layui-input picker-admin">
+				<input type="hidden" name="handled">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="">
+				</div>
+			</td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">保养内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入保养内容" class="layui-textarea" lay-verify="required" lay-reqText="请完善保养内容"></textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		{gt name="$cid" value="0"}
+		<input type="hidden" name="car_id" value="{$cid}">
+		{/gt}
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','uploadPlus','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus;
+	//相关附件上传
+	var attachment = new uploadPlus();
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000,'protectTable');				
+			}
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/car/protect_add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 84 - 0
app/adm/view/car/protect_edit.html

@@ -0,0 +1,84 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">编辑车辆保养记录</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td>{$detail.car}</td>
+			<td class="layui-td-gray">保养地点<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="address" value="{$detail.address}" lay-verify="required" lay-reqText="请完善保养地点" placeholder="请完善保养地点" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">保养日期<font>*</font></td>
+			<td><input type="text" name="repair_time" readonly value="{$detail.repair_time|date='Y-m-d'}" placeholder="请选择保养日期" class="layui-input tool-time" data-max="0" lay-verify="required" lay-reqText="请完善保养日期"></td>
+			<td class="layui-td-gray">保养费用<font>*</font></td>
+			<td><input type="text" name="amount" value="{$detail.amount}" placeholder="请输入保养费用" lay-verify="required|number" lay-reqText="请输入保养费用" class="layui-input"></td>
+			<td class="layui-td-gray">经手人<font>*</font></td>
+			<td>
+				<input type="text" name="handled_name" value="{$detail.handled_name}" readonly lay-verify="required" lay-reqText="请选择经手人" class="layui-input picker-admin">
+				<input type="hidden" name="handled" value="{$detail.handled}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids}">
+					{notempty name="$detail.fileArray"}
+					{volist name="$detail.fileArray" id="vo"}
+					<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo)}</div>
+					{/volist}
+					{/notempty}
+				</div>
+			</td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">保养内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入保养内容" class="layui-textarea" lay-verify="required" lay-reqText="请完善保养内容">{$detail.content|default=''}</textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		<input type="hidden" name="id" value="{$detail.id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','uploadPlus','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus;
+	//相关附件上传
+	var attachment = new uploadPlus();
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000,'protectTable');				
+			}
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/car/protect_add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 84 - 0
app/adm/view/car/protect_list.html

@@ -0,0 +1,84 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px;">
+			<input type="text" class="layui-input" id="diff_time" placeholder="保养日期" readonly name="diff_time">
+		</div>
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="输入关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="protectTable" lay-filter="protectTable"></table>
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/adm/car/protect_add">+ 添加保养记录</button>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+<!-- 脚本 -->
+{block name="script"}
+	<script>
+	const moduleInit = ['tool','tablePlus','laydatePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool,form = layui.form,laydatePlus = layui.laydatePlus;	
+		var diff_time = new laydatePlus({'target':'diff_time'});		
+		
+		layui.protectTable = table.render({
+			elem: '#protectTable'
+			,toolbar: '#toolbarDemo'
+			,title:'保养记录列表'
+			,url: "/adm/car/protect_list"
+			,is_excel: true
+			,page: true
+			,cellMinWidth: 60
+			,height: 'full-114'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'repair_time',title: '保养日期',align: 'center',width: 100}
+				,{field:'amount',width:100, title: '保养费用(元)', align:'center',style:"color:#16b777"}
+				,{field:'car',width:120,title: '车辆名称'}
+				,{field:'name',width:100, title: '车牌号码', align:'center'}
+				,{field:'content',minWidth:300,title: '保养内容'}
+				,{field:'handled_name',title: '跟进人',align: 'center',width: 80}
+				,{field:'create_time',title: '记录时间',align: 'center',width: 130}
+				,{width:120,fixed:'right', title: '操作', align:'center',templet: function(d){
+					var html='<div class="layui-btn-group"><a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a><a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详情</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></div>';
+					return html;
+				}}
+			]]
+		});
+		
+		table.on('tool(protectTable)',function (obj) {
+			var that = this;
+			if(obj.event === 'edit'){					
+				tool.side("/adm/car/protect_add?id="+obj.data.id);
+			}
+			if(obj.event === 'view'){					
+				tool.side("/adm/car/protect_view?id="+obj.data.id);
+			}
+			if(obj.event === 'del'){
+				layer.confirm('确定要删除该保养记录吗?', {icon: 3, title:'提示'}, function(index){
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							layui.protectTable.reload();
+						}
+					}
+					tool.post("/adm/car/protect_del", {id: obj.data.id}, callback);
+					layer.close(index);
+				});
+				return;
+			}
+		});
+	}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 52 - 0
app/adm/view/car/protect_view.html

@@ -0,0 +1,52 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">车辆保养记录</h3>
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td>{$detail.car}</td>
+			<td class="layui-td-gray">保养地点</td>
+			<td colspan="3">{$detail.address}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">保养日期</td>
+			<td>{$detail.repair_time|date='Y-m-d'}</td>
+			<td class="layui-td-gray">保养费用</td>
+			<td>{$detail.amount}</td>
+			<td class="layui-td-gray">跟进人</td>
+			<td>{$detail.handled_name}</td>
+		</tr>
+		{notempty name="$detail.fileArray"}
+		<tr>
+			<td class="layui-td-gray">相关附件</div></td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">					
+					{volist name="$detail.fileArray" id="vo"}
+					<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo,'view')}</div>
+					{/volist}					
+				</div>
+			</td>
+		</tr>
+		{/notempty}
+		<tr>
+			<td class="layui-td-gray-2" style="vertical-align:top;">保养原因&内容</td>
+			<td colspan="5">{$detail.content|default=''}</td>
+		</tr>
+	</table>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool;
+	
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 95 - 0
app/adm/view/car/repair_add.html

@@ -0,0 +1,95 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">新增车辆维修记录</h3>
+	<table class="layui-table layui-table-form">
+		{eq name="$cid" value="0"}
+		<tr>
+			<td class="layui-td-gray">车辆名称<font>*</font></td>
+			<td>
+				<input type="text" name="car_name" readonly lay-verify="required" lay-reqText="请选择车辆" placeholder="请选择" class="layui-input picker-oa" data-types="car">
+				<input type="hidden" name="car_id" value="">
+			</td>
+			<td class="layui-td-gray">维修地点<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="address" lay-verify="required" lay-reqText="请完善维修地点" placeholder="请完善维修地点" class="layui-input">
+			</td>
+		</tr>
+		{else/}
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td>{$car.title}</td>
+			<td class="layui-td-gray">维修地点<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="address" lay-verify="required" lay-reqText="请完善维修地点" placeholder="请完善维修地点" class="layui-input">
+			</td>
+		</tr>
+		{/eq}
+		<tr>
+			<td class="layui-td-gray">维修日期<font>*</font></td>
+			<td><input type="text" name="repair_time" readonly placeholder="请选择维修日期" class="layui-input tool-time" data-max="0" lay-verify="required" lay-reqText="请完善维修日期"></td>
+			<td class="layui-td-gray">维修费用<font>*</font></td>
+			<td><input type="text" name="amount" placeholder="请输入维修费用" lay-verify="required|number" lay-reqText="请输入维修费用" class="layui-input"></td>
+			<td class="layui-td-gray">经手人<font>*</font></td>
+			<td>
+				<input type="text" name="handled_name" readonly lay-verify="required" lay-reqText="请选择经手人" placeholder="请选择" class="layui-input picker-admin">
+				<input type="hidden" name="handled">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="">
+				</div>
+			</td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">维修内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入维修内容" class="layui-textarea" lay-verify="required" lay-reqText="请完善维修内容"></textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		{gt name="$cid" value="0"}
+		<input type="hidden" name="car_id" value="{$cid}">
+		{/gt}
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','uploadPlus','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus;
+	//相关附件上传
+	var attachment = new uploadPlus();
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000,'repairTable');				
+			}
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/car/repair_add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 84 - 0
app/adm/view/car/repair_edit.html

@@ -0,0 +1,84 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">编辑车辆维修记录</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td>{$detail.car}</td>
+			<td class="layui-td-gray">维修地点<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="address" value="{$detail.address}" lay-verify="required" lay-reqText="请完善维修地点" placeholder="请完善维修地点" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">维修日期<font>*</font></td>
+			<td><input type="text" name="repair_time" readonly value="{$detail.repair_time|date='Y-m-d'}" placeholder="请选择维修日期" class="layui-input tool-time" data-max="0" lay-verify="required" lay-reqText="请完善维修日期"></td>
+			<td class="layui-td-gray">维修费用<font>*</font></td>
+			<td><input type="text" name="amount" value="{$detail.amount}" placeholder="请输入维修费用" lay-verify="required|number" lay-reqText="请输入维修费用" class="layui-input"></td>
+			<td class="layui-td-gray">经手人<font>*</font></td>
+			<td>
+				<input type="text" name="handled_name" value="{$detail.handled_name}" readonly lay-verify="required" lay-reqText="请选择经手人" class="layui-input picker-admin">
+				<input type="hidden" name="handled" value="{$detail.handled}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids}">
+					{notempty name="$detail.fileArray"}
+					{volist name="$detail.fileArray" id="vo"}
+					<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo)}</div>
+					{/volist}
+					{/notempty}
+				</div>
+			</td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">维修内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入维修内容" class="layui-textarea" lay-verify="required" lay-reqText="请完善维修内容">{$detail.content|default=''}</textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		<input type="hidden" name="id" value="{$detail.id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','uploadPlus','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus;
+	//相关附件上传
+	var attachment = new uploadPlus();
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000,'repairTable');				
+			}
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/car/repair_add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 84 - 0
app/adm/view/car/repair_list.html

@@ -0,0 +1,84 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px;">
+			<input type="text" class="layui-input" id="diff_time" placeholder="维修日期" readonly name="diff_time">
+		</div>
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="输入关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="test" lay-filter="test"></table>
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/adm/car/repair_add">+ 添加维修记录</button>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+<!-- 脚本 -->
+{block name="script"}
+	<script>
+	const moduleInit = ['tool','tablePlus','laydatePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool,form = layui.form,laydatePlus = layui.laydatePlus;	
+		var diff_time = new laydatePlus({'target':'diff_time'});		
+		
+		layui.repairTable = table.render({
+			elem: '#test'
+			,toolbar: '#toolbarDemo'
+			,title:'维修记录列表'
+			,url: "/adm/car/repair_list"
+			,is_excel: true
+			,page: true
+			,cellMinWidth: 60
+			,height: 'full-114'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'repair_time',title: '维修日期',align: 'center',width: 100}
+				,{field:'amount',width:100, title: '维修费用(元)', align:'center',style:"color:#16b777"}
+				,{field:'car',width:120,title: '车辆名称'}
+				,{field:'name',width:100, title: '车牌号码', align:'center'}
+				,{field:'content',minWidth:300,title: '维修内容'}
+				,{field:'handled_name',title: '跟进人',align: 'center',width: 80}
+				,{field:'create_time',title: '记录时间',align: 'center',width: 130}
+				,{width:120,fixed:'right', title: '操作', align:'center',templet: function(d){
+					var html='<div class="layui-btn-group"><a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a><a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详情</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></div>';
+					return html;
+				}}
+			]]
+		});
+		
+		table.on('tool(test)',function (obj) {
+			var that = this;
+			if(obj.event === 'edit'){					
+				tool.side("/adm/car/repair_add?id="+obj.data.id);
+			}
+			if(obj.event === 'view'){					
+				tool.side("/adm/car/repair_view?id="+obj.data.id);
+			}
+			if(obj.event === 'del'){
+				layer.confirm('确定要删除该维修记录吗?', {icon: 3, title:'提示'}, function(index){
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							layui.repairTable.reload();
+						}
+					}
+					tool.post("/adm/car/repair_del", {id: obj.data.id}, callback);
+					layer.close(index);
+				});
+				return;
+			}
+		});
+	}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 52 - 0
app/adm/view/car/repair_view.html

@@ -0,0 +1,52 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">车辆维修记录</h3>
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td>{$detail.car}</td>
+			<td class="layui-td-gray">维修地点</td>
+			<td colspan="3">{$detail.address}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">维修日期</td>
+			<td>{$detail.repair_time|date='Y-m-d'}</td>
+			<td class="layui-td-gray">维修费用</td>
+			<td>{$detail.amount}</td>
+			<td class="layui-td-gray">跟进人</td>
+			<td>{$detail.handled_name}</td>
+		</tr>
+		{notempty name="$detail.fileArray"}
+		<tr>
+			<td class="layui-td-gray">相关附件</div></td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">					
+					{volist name="$detail.fileArray" id="vo"}
+					<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo,'view')}</div>
+					{/volist}					
+				</div>
+			</td>
+		</tr>
+		{/notempty}
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">维修内容</td>
+			<td colspan="5">{$detail.content|default=''}</td>
+		</tr>
+	</table>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool;
+	
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 390 - 0
app/adm/view/car/view.html

@@ -0,0 +1,390 @@
+{extend name="../../base/view/common/base" /}
+{block name="style"}
+<style>
+.layui-tab-title .layui-this{background-color:#fff;}
+.layui-tab-card,.layui-card{box-shadow:0 0 0 0 rgb(0 0 0 / 10%); border-radius:0; border-top:none;}
+</style>
+{/block}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+	<h3 class="pb-2">车辆信息详情</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">车辆名称</td>
+			<td>{$detail.title}</td>
+			<td class="layui-td-gray">车牌号码</td>
+			<td>{$detail.name}</td>
+			<td class="layui-td-gray-2" rowspan="5">车辆缩略图</td>
+			<td rowspan="5" style="width:252px;">
+			    <div id="demo1" style="width: 240px; height:136px; overflow: hidden;">
+					<img src="{:get_file($detail.thumb)}" style="max-width: 100%; height:136px;" />
+			    </div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">购买日期</td>
+			<td>{$detail.buy_time|date='Y-m-d'}</td>
+			<td class="layui-td-gray-2">购买价格</td>
+			<td>{$detail.price}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">车身颜色</td>
+			<td>{$detail.color}</td>
+			<td class="layui-td-gray">座位数</td>
+			<td>{$detail.seats}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">发动机号</td>
+			<td>{$detail.engine}</td>
+			<td class="layui-td-gray-2">车架号</td>
+			<td>{$detail.vin}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">车险到期日期</td>
+			<td>{$detail.insure_time|date='Y-m-d'}</td>
+			<td class="layui-td-gray-2">车审到期日期</td>
+			<td>{$detail.review_time|date='Y-m-d'}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">车辆油耗</td>
+			<td>{$detail.oil}</td>
+			<td class="layui-td-gray-2">当前里程数</td>
+			<td>{$detail.latestMileage}(开始里程数:{$detail.mileage})</td>
+			<td class="layui-td-gray-2">驾驶员</td>
+			<td>{$detail.driver_name|default=''}</td>
+		</tr>
+		{notempty name="$detail.remark"}
+		<tr>
+			<td class="layui-td-gray">备注信息</td>
+			<td colspan="5">{$detail.remark|default=''}</td>
+		</tr>
+		{/notempty}
+		{notempty name="$detail.file_ids"}
+		<tr>
+			<td colspan="6"><strong>相关附件<strong></td>
+		</tr>
+		<tr>
+			<td colspan="6">
+				<div class="layui-row" id="uploadBox">					
+					{volist name="$detail.file_array" id="vo"}
+						<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo,'view')}</div>
+					{/volist}					
+				</div>
+			</td>
+		</tr>
+		{/notempty}
+	</table>
+		
+	<div class="layui-tab layui-tab-card" style="margin:0; background-color:#fff;" lay-filter="car" id="carTab">
+		<ul class="layui-tab-title">
+			<li class="layui-this" data-load="true"><strong>里程记录</strong></li>
+			<li><strong>费用记录</strong></li>
+			<li><strong>维修记录</strong></li>
+			<li><strong>保养记录</strong></li>
+		</ul>
+		<div class="layui-tab-content" style="padding:0;">
+			<div class="layui-tab-item layui-show">
+				<div class="p-3">
+					<div class="pb-3">
+						<span class="layui-btn layui-btn-sm add-mileage">+ 里程记录</span>
+					</div>
+					<table class="layui-hide" id="mileage" lay-filter="mileage"></table>
+				</div>
+			</div>
+			<div class="layui-tab-item">
+				<div class="p-3">
+					<div class="pb-3">
+						<span class="layui-btn layui-btn-sm side-a" data-href="/adm/car/fee_add?cid={$detail.id}">+ 费用记录</span>
+					</div>
+					<table class="layui-hide" id="fee" lay-filter="fee"></table>
+				</div>
+			</div>
+			<div class="layui-tab-item">	
+				<div class="p-3">
+					<div class="pb-3">
+						<span class="layui-btn layui-btn-sm side-a" data-href="/adm/car/repair_add?cid={$detail.id}">+ 维修记录</span>
+					</div>
+					<table class="layui-hide" id="repair" lay-filter="repair"></table>
+				</div>
+			</div>
+			<div class="layui-tab-item">	
+				<div class="p-3">
+					<div class="pb-3">
+						<span class="layui-btn layui-btn-sm side-a" data-href="/adm/car/protect_add?cid={$detail.id}">+ 保养记录</span>
+					</div>
+					<table class="layui-hide" id="protect" lay-filter="protect"></table>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+{/block}
+<!-- /主体 -->
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	var car_id = {$detail.id};
+	var moduleInit = ['tool'];
+	function gouguInit() {
+		var tool = layui.tool,table = layui.table,element = layui.element;
+		element.on('tab(car)', function(data){
+			let index = data.index;
+			if(index == 1){
+				layui.feeTable = table.render({
+					elem: '#fee',
+					title: '费用记录',
+					cellMinWidth: 80,
+					url: "/adm/api/get_car_fee", //数据接口
+					where: { 'car_id': car_id },
+					page: true, //开启分页
+					limit: 10,
+					cols: [[
+						{field:'id',width:80, title: 'ID号', align:'center'}
+						,{field:'fee_time',title: '费用日期',align: 'center',width: 100}
+						,{field:'types_str',title: '费用类型',align: 'center',width: 100}
+						,{field:'amount',width:100, title: '费用金额(元)', align:'center',style:"color:#16b777"}
+						,{field:'title',minWidth:300,title: '费用主题'}
+						,{field:'handled_name',title: '跟进人',align: 'center',width: 80}
+						,{field:'create_time',title: '记录时间',align: 'center',width: 130}
+						,{width:120,fixed:'right', title: '操作', align:'center',templet: function(d){
+							var html='<div class="layui-btn-group"><a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a><a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详情</a><a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></div>';
+							return html;
+						}}
+					]]
+				});
+				//监听行工具事件
+				table.on('tool(fee)', function(obj) {
+					var data = obj.data;			
+					if(obj.event === 'edit'){
+						tool.side('/adm/car/fee_add?id='+data.id);
+						return;
+					}
+					if(obj.event === 'view'){
+						tool.side('/adm/car/fee_view?id='+data.id);
+						return;
+					}
+					if (obj.event === 'del') {
+						layer.confirm('确定要删除吗?', {
+							icon: 3,
+							title: '提示'
+						}, function(index) {
+							let callback = function (e) {
+								layer.msg(e.msg);
+								if (e.code == 0) {
+									obj.del();
+								}
+							}
+							tool.delete("/adm/car/fee_del", {id: data.id}, callback);
+							layer.close(index);
+						});
+					}
+				});	
+			}
+			if(index == 2){
+				layui.repairTable = table.render({
+					elem: '#repair',
+					title: '维修记录',
+					cellMinWidth: 80,
+					url: "/adm/api/get_car_repair", //数据接口
+					where: { 'car_id': car_id },
+					page: true, //开启分页
+					limit: 10,
+					cols: [[ //表头
+						{ field: 'id', title: '序号', width: 60, align: 'center' }
+						, { field: 'amount', title: '维修金额', style: 'color: #91CC75;', align: 'center', width: 100 }
+						, { field: 'repair_time', title: '维修日期', align: 'center', width: 100 }
+						, { field: 'content', title: '维修内容',minWidth:240}
+						, { field: 'handled_name', title: '经手人', align: 'center', width: 80 }
+						, { field: 'create_time', title: '记录时间', align: 'center', width: 136}
+						, {title: '操作',fixed:'right', align: 'center', width: 124, templet: function (d) {
+								return '<div class="layui-btn-group"><span class="layui-btn layui-btn-xs" lay-event="edit">修改</span><span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</span><span class="layui-btn layui-bg-red layui-btn-xs" lay-event="del">删除</span></div>';
+							}
+						}
+					]]
+				});
+				//监听行工具事件
+				table.on('tool(repair)', function(obj) {
+					var data = obj.data;			
+					if(obj.event === 'edit'){
+						tool.side('/adm/car/repair_add?id='+data.id);
+						return;
+					}
+					if(obj.event === 'view'){
+						tool.side('/adm/car/repair_view?id='+data.id);
+						return;
+					}
+					if (obj.event === 'del') {
+						layer.confirm('确定要删除吗?', {
+							icon: 3,
+							title: '提示'
+						}, function(index) {
+							let callback = function (e) {
+								layer.msg(e.msg);
+								if (e.code == 0) {
+									obj.del();
+								}
+							}
+							tool.delete("/adm/car/repair_del", {id: data.id}, callback);
+							layer.close(index);
+						});
+					}
+				});		
+			}
+			if(index == 3){		
+				layui.protectTable = table.render({
+					elem: '#protect',
+					title: '保养记录',
+					cellMinWidth: 80,
+					url: "/adm/api/get_car_protect", //数据接口
+					where: { 'car_id': car_id },
+					page: true, //开启分页
+					limit: 10,
+					cols: [[ //表头
+						{ field: 'id', title: '序号', width: 60, align: 'center' }
+						, { field: 'amount', title: '保养金额', style: 'color: #91CC75;', align: 'center', width: 100 }
+						, { field: 'repair_time', title: '保养日期', align: 'center', width: 100 }
+						, { field: 'content', title: '保养内容',minWidth:240}
+						, { field: 'handled_name', title: '经手人', align: 'center', width: 80 }
+						, { field: 'create_time', title: '记录时间', align: 'center', width: 136}
+						, {title: '操作',fixed:'right', align: 'center', width: 124, templet: function (d) {
+								return '<div class="layui-btn-group"><span class="layui-btn layui-btn-xs" lay-event="edit">修改</span><span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</span><span class="layui-btn layui-bg-red layui-btn-xs" lay-event="del">删除</span></div>';
+							}
+						}
+					]]
+				});
+				//监听行工具事件
+				table.on('tool(protect)', function(obj) {
+					var data = obj.data;			
+					if(obj.event === 'edit'){
+						tool.side('/adm/car/protect_add?id='+data.id);
+						return;
+					}
+					if(obj.event === 'view'){
+						tool.side('/adm/car/protect_view?id='+data.id);
+						return;
+					}
+					if (obj.event === 'del') {
+						layer.confirm('确定要删除吗?', {
+							icon: 3,
+							title: '提示'
+						}, function(index) {
+							let callback = function (e) {
+								layer.msg(e.msg);
+								if (e.code == 0) {
+									obj.del();
+								}
+							}
+							tool.delete("/adm/car/protect_del", {id: data.id}, callback);
+							layer.close(index);
+						});
+					}
+				});	
+			}
+		});
+		
+		
+		layui.mileageTable = table.render({
+			elem: '#mileage',
+			title: '里程记录',
+			cellMinWidth: 80,
+			url: "/adm/api/get_car_mileage", //数据接口
+			where: { 'car_id': car_id },
+			page: true, //开启分页
+			limit: 10,
+			cols: [[ //表头
+				{ field: 'id', title: '序号', width: 60, align: 'center' }
+				, { field: 'mileage', title: '里程数', align: 'center', width: 120}
+				, { field: 'mileage_time', title: '里程月份', align: 'center', width: 120 }
+				, { field: 'admin_name', title: '创建人', align: 'center', width: 120 }
+				, { field: 'create_time', title: '记录时间', align: 'center', minWidth: 150,}
+				, {title: '操作',fixed:'right', align: 'center', width: 124, templet: function (d) {
+						return '<div class="layui-btn-group"><span class="layui-btn layui-btn-xs" lay-event="edit">修改</span><span class="layui-btn layui-bg-red layui-btn-xs" lay-event="del">删除</span></div>';
+					}
+				}
+			]]
+		});
+		
+		$('body').on('click','.add-mileage',function(){
+			addMileage(0,'','');	
+		});
+		
+		function addMileage(id,mileage_time,mileage){
+			var biaoti = '新增里程记录';
+			if(id>0){
+				biaoti = '编辑里程记录';
+			}				
+			layer.open({
+				type: 1
+				,title: biaoti
+				,area: '368px;'
+				,id: 'LAY_module' //设定一个id,防止重复弹出
+				,btn: ['确定', '取消']
+				,btnAlign: 'c'
+				,content: '<div style="padding-top:15px;">\
+							<div class="layui-form-item">\
+							  <label class="layui-form-label">里程月份</label>\
+							  <div class="layui-input-inline">\
+								<input type="hidden" name="id" value="'+id+'">\
+								<input type="text" name="mileage_time" autocomplete="off" value="'+mileage_time+'" placeholder="请输入里程月份" readonly class="layui-input tool-time" data-type="month">\
+							  </div>\
+							</div>\
+							<div class="layui-form-item">\
+							  <label class="layui-form-label">里程数</label>\
+							  <div class="layui-input-inline">\
+								<input type="text" name="mileage" autocomplete="off" value="'+mileage+'" placeholder="请输入里程数" class="layui-input">\
+							  </div>\
+							</div>\
+						  </div>'
+				,yes: function(index){
+					let id = $('#LAY_module').find('[name="id"]').val();
+					let mileage_time = $('#LAY_module').find('[name="mileage_time"]').val();
+					let mileage = $('#LAY_module').find('[name="mileage"]').val();
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							layui.mileageTable.reload();	
+							layer.close(index);			
+						}
+					}
+					tool.post("/adm/car/mileage_add", {
+						id: id,
+						mileage_time: mileage_time,
+						mileage: mileage,
+						car_id:car_id
+					}, callback);						
+				}
+				,btn2: function(){
+					layer.closeAll();
+				}
+			});
+		}
+			
+			
+		//监听行工具事件
+		table.on('tool(mileage)', function(obj) {
+			var data = obj.data;			
+			if(obj.event === 'edit'){
+				addMileage(data.id,data.mileage_time,data.mileage)
+				return;
+			}
+			if (obj.event === 'del') {
+				layer.confirm('确定要删除吗?', {
+					icon: 3,
+					title: '提示'
+				}, function(index) {
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							obj.del();
+						}
+					}
+					tool.delete("/adm/car/mileage_del", {id: data.id}, callback);
+					layer.close(index);
+				});
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 373 - 0
app/adm/view/flow/add.html

@@ -0,0 +1,373 @@
+{extend name="../../base/view/common/base" /}
+{block name="style"}
+<style>
+.layui-form-pane .layui-form-label{color:#999; width:80px; padding:8px 3px;}
+.layui-form-item .layui-inline{margin-right:1px; margin-bottom:10px;}
+.layui-form-item{margin-bottom:5px;}
+.layui-form-item .layui-btn-danger{display:none; margin-top:-8px}
+.layui-form-item:hover .layui-btn-danger{display:inline-block;}
+.select-1,.select-2{display:none;}
+
+.check-type-1 .flow-tr-2,.check-type-1 .flow-tr-3{display:none;}
+.check-type-2 .flow-tr-1,.check-type-2 .flow-tr-3{display:none;}
+.check-type-3 .flow-tr-1,.check-type-3 .flow-tr-2{display:none;}
+
+.role-1 .select-3,.role-1 .select-4{display:none;}
+.role-2 .select-3,.role-2 .select-4{display:none;}
+.role-3 .select-4{display:none;}
+.role-4 .select-3{display:none;}
+.role-5 .select-3{display:none;}
+</style>
+{/block}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">审批流程</h3>
+	<table id="flowTable" class="layui-table check-type-{$check_type}">
+		<tr>
+			<td class="layui-td-gray">流程名称<font>*</font></td>
+			<td><input type="text" name="title" value="{$detail.title|default=''}" autocomplete="off" placeholder="请输入审批流程名称" lay-verify="required" lay-reqText="请输入审批流程名称" class="layui-input"></td>
+			<td class="layui-td-gray">审批类型<font>*</font></td>
+			<td>
+				{eq name="$id" value="0"}
+				<select name="cate_id" lay-filter="cate" lay-verify="required" lay-reqText="请选择审批类型">
+				  <option value="">--请选择审批类型--</option>
+				  {volist name=":get_base_data('FlowCate')" id="vo"}
+				  <option value="{$vo.id}">{$vo.title}</option>
+				  {/volist}
+				</select>
+				{else/}
+				<select name="cate_id" lay-filter="cate" lay-verify="required" lay-reqText="请选择审批类型">
+				  <option value="">--请选择审批类型--</option>
+				  {volist name=":get_base_data('FlowCate')" id="vo"}
+				  <option value="{$vo.id}" {eq name="$detail.cate_id" value="$vo.id"}selected=""{/eq}>{$vo.title}</option>
+				  {/volist}
+				</select>
+				{/eq}
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">应用部门</td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:80%;">
+					<select id="department_ids" name="department_ids" xm-selected="{$detail.department_ids|default=''}" xm-select="select1" xm-select-skin="default"></select>
+				</div>
+				<span class="red" style="font-size:12px;">(如果不选,默认是全公司)</span>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">流程说明</td>
+			<td colspan="3">
+				<textarea name="remark" placeholder="请输入流程说明" class="layui-textarea">{$detail.remark|default=''}</textarea>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">审批流类型<font>*</font></td>
+			<td colspan="3">
+				<input type="radio" name="check_type" lay-filter="checktype" value="1" title="自由审批流" {eq name="$check_type" value="1"}checked{/eq}>
+				<input type="radio" name="check_type" lay-filter="checktype" value="2" title="固定审批流" {eq name="$check_type" value="2"}checked{/eq}>
+				<input type="radio" name="check_type" lay-filter="checktype" value="3" title="可回退的审批流" {eq name="$check_type" value="3"}checked{/eq}>
+			</td>
+		</tr>
+		<tr id="flowTr1" class="flow-tr-1">
+			<td class="layui-td-gray">审批流程<font>*</font></td>
+			<td colspan="3">
+				<div style="padding:10px; font-size:12px; background-color:#fffcf0">
+					<p><strong>温馨提示</strong></p>
+					<p>无需配置审批人,审批时操作人员根据实际情况选择审批人即可,自由度最高。</p>
+				</div>
+			</td>
+		</tr>
+		<tr id="flowTr2" class="flow-tr-2">
+			<td class="layui-td-gray">审批流程<font>*</font></td>
+			<td colspan="3">
+				<div id="flowList2">
+					{eq name="$check_type" value="2"}
+						{volist name="detail.flow_list" id="vo"}
+						<div class="layui-form-item layui-form-pane role-{$vo.check_role}">
+							<div class="layui-inline">
+							  <label class="layui-form-label">第{$key+1}级</label>
+							  <div class="layui-input-inline" style="width:150px;">
+								<select name="check_role[]" lay-filter="role">
+									<option value="1" {eq name="$vo.check_role" value="1"}selected=""{/eq}>当前部门负责人</option>
+									<option value="2" {eq name="$vo.check_role" value="2"}selected=""{/eq}>上一级部门负责人</option>
+									<option value="3" {eq name="$vo.check_role" value="3"}selected=""{/eq}>指定岗位职称人</option>
+									<option value="4" {eq name="$vo.check_role" value="4"}selected=""{/eq}>指定成员</option>
+								</select>
+							  </div>
+							</div>
+							<div class="layui-inline select-3">
+								<label class="layui-form-label">岗位职称</label>
+								<div class="layui-input-inline" style="width:120px;">
+									<input type="text" name="check_position_title[]" value="{$vo.check_position_title}" autocomplete="off" readonly class="layui-input picker-oa" data-types="position">
+									<input type="hidden" name="check_position_id[]" value="{$vo.check_position_id}">
+								</div>
+							</div>
+							<div class="layui-inline select-4">
+								<label class="layui-form-label">指定人员</label>
+								<div class="layui-input-inline" style="width:320px;">
+									<input type="text" name="check_unames_a[]" value="{$vo.check_unames}" autocomplete="off" readonly class="layui-input picker-admin" data-type="2">
+									<input type="hidden" name="check_uids_a[]" value="{$vo.check_uids}">
+								</div>
+							</div>
+							<div class="layui-inline">
+							  <label class="layui-form-label" style="width:100px;">同时有多人时</label>
+							  <div class="layui-input-inline" style="width:80px;">
+								<select name="check_types[]">
+									<option value="1" {eq name="$vo.check_types" value="1"}selected=""{/eq}>会签</option>
+									<option value="2" {eq name="$vo.check_types" value="2"}selected=""{/eq}>或签</option>
+								</select>
+							  </div>
+							</div>
+							{gt name="$key" value="0"}
+							<span class="layui-btn layui-btn-danger layui-btn-sm">删除</span>
+							{/gt}
+						</div>
+						{/volist}
+					{else/}
+						<div class="layui-form-item layui-form-pane role-1">
+							<div class="layui-inline">
+							  <label class="layui-form-label">第1级</label>
+							  <div class="layui-input-inline" style="width:150px;">
+								<select name="check_role[]" lay-filter="role">
+									<option value="1">当前部门负责人</option>
+									<option value="2">上一级部门负责人</option>
+									<option value="3">指定岗位职称人</option>
+									<option value="4">指定成员</option>
+								</select>
+							  </div>
+							</div>
+							<div class="layui-inline select-3">
+								<label class="layui-form-label">岗位职称</label>
+								<div class="layui-input-inline" style="width:120px;">
+									<input type="text" name="check_position_title[]" value="" autocomplete="off" readonly class="layui-input picker-oa" data-types="position">
+									<input type="hidden" name="check_position_id[]" value="">
+								</div>
+							</div>
+							<div class="layui-inline select-4">
+								<label class="layui-form-label">指定人员</label>
+								<div class="layui-input-inline" style="width:320px;">
+									<input type="text" name="check_unames_a[]" value="" autocomplete="off" readonly class="layui-input picker-admin" data-type="2">
+									<input type="hidden" name="check_uids_a[]" value="">
+								</div>
+							</div>
+							<div class="layui-inline">
+							  <label class="layui-form-label" style="width:100px;">同时有多人时</label>
+							  <div class="layui-input-inline" style="width:80px;">
+								<select name="check_types[]">
+									<option value="1">会签</option>
+									<option value="2" selected="">或签</option>
+								</select>
+							  </div>
+							</div>
+						</div>
+					{/eq}
+				</div>
+				<span id="addFlow2" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加审批层级</span>
+				<div style="padding:10px; margin-top:10px; font-size:12px; background-color:#fffcf0">
+					<p><strong>温馨提示</strong></p>
+					<p>1、当选择<strong> “当前部门负责人” </strong>审批时,有多个当前部门负责人时支持会签、或签模式。</p>
+					<p>2、当选择<strong> “上一级部门负责人” </strong>审批时,有多个上一级部门负责人时支持会签、或签模式</p>
+					<p>3、当选择<strong> “指定岗位职称” </strong>审批时,该岗位职称同时有多个人时支持会签、或签模式</p>
+					<p>4、当选择<strong> “指定成员” </strong>时,有多个人时支持会签、或签模式。</p>
+					<p>5、如果指定用户没有分配查看审批模块的功能权限,系统会通知其审批,但是他无法查看此审批数据信息。</p>
+				</div>
+			</td>
+		</tr>
+		<tr id="flowTr3" class="flow-tr-3">
+			<td class="layui-td-gray">审批流程<font>*</font></td>
+			<td colspan="3">
+				<div id="flowList3">
+					{eq name="$check_type" value="3"}
+						{volist name="detail.flow_list" id="vo"}
+						<div class="layui-form-item layui-form-pane">
+							<div class="layui-inline">
+								<label class="layui-form-label">第{$key+1}级</label>
+								<div class="layui-input-inline" style="width:240px;">
+									<input type="text" name="flow_name[]" value="{$vo.flow_name}" autocomplete="off" placeholder="请输入流程名称" class="layui-input">
+								</div>
+							</div>
+							<div class="layui-inline">
+								<label class="layui-form-label">指定人员</label>
+								<div class="layui-input-inline" style="width:120px;">
+									<input type="text" name="check_unames_b[]" value="{$vo.check_unames}" autocomplete="off" readonly class="layui-input picker-admin"  data-type="1">
+									<input type="hidden" name="check_uids_b[]" value="{$vo.check_uids}">
+								</div>
+							</div>
+							{gt name="$key" value="0"}
+							<span class="layui-btn layui-btn-danger layui-btn-sm">删除</span>
+							{/gt}
+						</div>
+						{/volist}
+					{else/}
+						<div class="layui-form-item layui-form-pane">
+							<div class="layui-inline">
+								<label class="layui-form-label">第1级</label>
+								<div class="layui-input-inline" style="width:240px;">
+									<input type="text" name="flow_name[]" value="" autocomplete="off" placeholder="请输入流程名称" class="layui-input">
+								</div>
+							</div>
+							<div class="layui-inline">
+								<label class="layui-form-label">指定人员</label>
+								<div class="layui-input-inline" style="width:120px;">
+									<input type="text" name="check_unames_b[]" value="" readonly class="layui-input picker-admin" data-type="1">
+									<input type="hidden" name="check_uids_b[]" value="">
+								</div>
+							</div>
+						</div>
+					{/eq}
+				</div>
+				<span id="addFlow3" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加审批层级</span>
+				<div style="padding:10px; margin-top:10px; font-size:12px; background-color:#fffcf0">
+					<p><strong>温馨提示</strong></p>
+					<p>1、<strong>指定人员</strong>单选。后期审批的时候,审批人只能该指定人员。</p>
+					<p>2、该审批流程可<strong>回退</strong>,当拒绝审核时,会自动回退到上一位审批人节点。</p>
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">默认抄送人</td>
+			<td colspan="3">
+				<input type="text" name="copy_unames" value="{$detail.copy_unames|default=''}" placeholder="请选择" readonly class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="copy_uids" value="{$detail.copy_uids|default=''}">
+			</td>
+		</tr>
+	</table>
+	<div class="pt-2">
+		<input type="hidden" name="id" value="{$id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','formSelects','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,formSelects = layui.formSelects;
+		  
+		//选择应用部门
+		var selcted = $('#department_ids').attr('xm-selected');
+		formSelects.data('select1', 'server', {
+			url: '/api/index/get_department_select',
+			keyword: selcted,
+		});	
+		
+		
+		form.on('radio(checktype)', function(data){
+			$('#flowTable').attr('class','layui-table check-type-'+data.value);
+		});
+		
+		form.on('select(role)', function(data){
+			$(data.elem).parents('.layui-form-item').attr('class','layui-form-item layui-form-pane role-'+data.value);
+		});
+
+		//监听提交
+		form.on('submit(webform)', function(data){
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);					
+				}
+			}
+			tool.post("/adm/flow/add", data.field, callback);
+			return false;
+		});
+    
+		
+		$('#addFlow2').on('click',function(){
+			var len = $('#flowList2').find('.layui-form-item').length;
+			var index = len+1;
+			var timestamp=new Date().getTime();
+			var tem='<div class="layui-form-item layui-form-pane role-1">\
+						<div class="layui-inline">\
+						<label class="layui-form-label label-index">第'+index+'级</label>\
+						  <div class="layui-input-inline" style="width:150px;">\
+							<select name="check_role[]" lay-filter="role">\
+								<option value="1">当前部门负责人</option>\
+								<option value="2">上一级部门负责人</option>\
+								<option value="3">指定岗位职称人</option>\
+								<option value="4">指定成员</option>\
+							</select>\
+						  </div>\
+						</div>\
+						<div class="layui-inline select-3">\
+							<label class="layui-form-label">岗位职称</label>\
+							<div class="layui-input-inline" style="width:120px;">\
+								<input type="text" name="check_position_title[]" value="" autocomplete="off" readonly class="layui-input picker-oa" data-types="position">\
+								<input type="hidden" name="check_position_id[]" value="">\
+							</div>\
+						</div>\
+						<div class="layui-inline select-4">\
+							<label class="layui-form-label">指定人员</label>\
+							<div class="layui-input-inline" style="width:320px;">\
+								<input type="text" name="check_unames_a[]" value="" autocomplete="off" readonly class="layui-input picker-admin" data-type="2">\
+								<input type="hidden" name="check_uids_a[]" value="">\
+							</div>\
+						</div>\
+						<div class="layui-inline">\
+						  <label class="layui-form-label" style="width:100px;">同时有多人时</label>\
+						  <div class="layui-input-inline" style="width:80px;">\
+							<select name="check_types[]">\
+								<option value="1">会签</option>\
+								<option value="2" selected="">或签</option>\
+							</select>\
+						  </div>\
+						</div>\
+						<span class="layui-btn layui-btn-danger layui-btn-sm">删除</span>\
+					</div>';
+			$('#flowList2').append(tem);
+			form.render();
+		});
+		
+		$('#flowList2').on('click','.layui-btn-danger',function(){
+			$(this).parents('.layui-form-item').remove();
+			var items = $('.label-index').length;
+			if(items>0){
+				$('.label-index').each(function(index,item){
+					$(this).html('第'+(index+2)+'级');
+				})
+			}
+		});			
+		
+		//================================
+		$('#addFlow3').on('click',function(){
+			var len = $('#flowList3').find('.layui-form-item').length;
+			var index = len+1;
+			var timestamp=new Date().getTime();
+			var tem='<div class="layui-form-item layui-form-pane">\
+						<div class="layui-inline">\
+							<label class="layui-form-label label-index">第'+index+'级</label>\
+							<div class="layui-input-inline" style="width:240px;">\
+								<input type="text" name="flow_name[]" value="" autocomplete="off" placeholder="请输入流程名称" class="layui-input">\
+							</div>\
+						</div>\
+						<div class="layui-inline select-3">\
+							<label class="layui-form-label">指定人员</label>\
+							<div class="layui-input-inline" style="width:120px;">\
+								<input type="text" name="check_unames_b[]" value="" autocomplete="off" readonly class="layui-input picker-admin" data-type="1">\
+								<input type="hidden" name="check_uids_b[]" value="">\
+							</div>\
+						</div>\
+						<span class="layui-btn layui-btn-danger layui-btn-sm">删除</span>\
+					</div>';
+			$('#flowList3').append(tem);
+			form.render();
+		});
+		
+		$('#flowList3').on('click','.layui-btn-danger',function(){
+			$(this).parents('.layui-form-item').remove();
+			var items = $('.label-index').length;
+			if(items>0){
+				$('.label-index').each(function(index,item){
+					$(this).html('第'+(index+2)+'级');
+				})
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 265 - 0
app/adm/view/flow/cate_add.html

@@ -0,0 +1,265 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">审批类型</h3>
+	{eq name="$id" value="0"}
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">类型名称<font>*</font></td>
+			<td><input type="text" name="title" value="" lay-verify="required" autocomplete="off" placeholder="请输入审批类型名称" lay-reqText="请输入类型名称" class="layui-input"></td>
+			<td class="layui-td-gray-2">关联审批模块<font>*</font></td>
+			<td>
+				<select name="module_id" lay-verify="required" lay-reqText="请选择要关联的审批模块">
+					<option value="">请选择</option>
+					{volist name=":get_base_data('flow_module')" id="vo"}
+						<option value="{$vo.id}">{$vo.title}</option>
+					{/volist}
+				</select>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">类型标识<font>*</font></td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+				<input type="text" name="name" value="" lay-verify="required" autocomplete="off" placeholder="请输入类型标识,如:official" lay-reqText="请输入类型标识,只能是小写字母" class="layui-input">
+				</div>
+				<span class="red" style="font-size:12px;">(重要:请输入类型标识注意只能是小写字母,唯一)</span></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">数据表名<font>*</font></td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+				<input type="text" name="check_table" value="" lay-verify="required" autocomplete="off" placeholder="请输入关联的数据库表名称,如:official_docs" lay-reqText="请输入关联的数据库表名称" class="layui-input">
+				</div>
+				<span class="red" style="font-size:12px;">(重要:输入要关联的数据库表名称,注意不需要表前缀,输错无效)</span></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">新建审批链接<font>*</font></td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+					<input type="text" name="add_url" value="" lay-verify="required" autocomplete="off" placeholder="请输入新建审批链接,如:adm/official/add" lay-reqText="请输入新建审批链接" class="layui-input">
+				</div>
+				<span class="red" style="font-size:12px;">(重要:输入新建审批链接,可在【系统管理】的【功能节点】查找,输错无效)</span></td>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">查看审批链接<font>*</font></td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+					<input type="text" name="view_url" value="" lay-verify="required" autocomplete="off" placeholder="请输入查看审批链接,如:adm/official/view" lay-reqText="请输入查看审批链接" class="layui-input">
+				</div>
+				<span class="red" style="font-size:12px;">(重要:输入查看审批链接,可在【系统管理】的【功能节点】查找,输错无效)</span></td>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">应用部门</td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+					<select id="department_ids" name="department_ids" xm-selected="" xm-select="select1" xm-select-skin="default"></select>
+				</div>
+				<span class="red" style="font-size:12px;">(如果不选,默认是全公司)</span>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">消息模板</td>
+			<td>
+				<input type="text" name="template_title" value="" readonly autocomplete="off" class="layui-input picker-oa" data-types='template' placeholder="请选择">
+				<input type="hidden" name="template_id" value="0">
+			</td>
+			<td class="layui-td-gray">展示图标<font>*</font></td>
+			<td>
+				<div class="layui-input-inline" style="width:50%;">
+					<input class="layui-input" type="text" name="icon" value="" placeholder="请输入图标" lay-verify="required" lay-reqText="请输入图标" >
+				</div>			
+				<a href="/static/assets/icon/index.html" target="_blank" style="margin-left:10px; color:#007AFF">[查看图标]</a>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">在工作台快捷显示</td>
+			<td>
+				<input type="radio" name="is_list" value="1" title="显示" checked>
+				<input type="radio" name="is_list" value="0" title="不显示">
+			</td>
+			<td class="layui-td-gray-2">审批通过后支持通知抄送人</td>
+			<td>
+				<input type="radio" name="is_copy" value="1" title="支持" checked>
+				<input type="radio" name="is_copy" value="0" title="不支持">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">审批过程中支持撤回</td>
+			<td>
+				<input type="radio" name="is_back" value="1" title="支持" checked>
+				<input type="radio" name="is_back" value="0" title="不支持">
+			</td>
+			<td class="layui-td-gray-2">审批时支持上传附件</td>
+			<td>
+				<input type="radio" name="is_file" value="1" title="支持">
+				<input type="radio" name="is_file" value="0" title="不支持" checked>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">审批通过后支持反确认</td>
+			<td>
+				<input type="radio" name="is_reversed" value="1" title="支持">
+				<input type="radio" name="is_reversed" value="0" title="不支持" checked>
+			</td>
+			<td class="layui-td-gray-2">审批通过后支持导出PDF打印</td>
+			<td>
+				<input type="radio" name="is_export" value="1" title="支持">
+				<input type="radio" name="is_export" value="0" title="不支持" checked>
+			</td>
+		</tr>
+	</table>
+	{else/}
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">类型名称<font>*</font></td>
+			<td><input type="text" name="title" value="{$detail.title}" lay-verify="required" autocomplete="off" placeholder="请输入审批类型名称" lay-reqText="请输入类型名称" class="layui-input"></td>
+			<td class="layui-td-gray-2">关联审批模块<font>*</font></td>
+			<td>
+				<select name="module_id" lay-verify="required" lay-reqText="请选择要关联的审批模块">
+					<option value="">请选择</option>
+					{volist name=":get_base_data('flow_module')" id="vo"}
+						<option value="{$vo.id}" {eq name="$vo.id" value="$detail.module_id"}selected{/eq}>{$vo.title}</option>
+					{/volist}
+				</select>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">类型标识<font>*</font></td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+				<input type="text" name="name" value="{$detail.name}" lay-verify="required" autocomplete="off" placeholder="请输入类型标识,如:official" lay-reqText="请输入类型标识,只能是小写字母" class="layui-input">
+				</div>
+				<span class="red" style="font-size:12px;">(重要:请输入类型标识注意只能是小写字母,唯一)</span></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">数据表名<font>*</font></td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+				<input type="text" name="check_table" value="{$detail.check_table}" lay-verify="required" autocomplete="off" placeholder="请输入关联的数据库表名称,如:official_docs" lay-reqText="请输入关联的数据库表名称" class="layui-input">
+				</div>
+				<span class="red" style="font-size:12px;">(重要:输入要关联的数据库表名称,注意不需要表前缀,输错无效)</span></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">新建审批链接<font>*</font></td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+					<input type="text" name="add_url" value="{$detail.add_url}" lay-verify="required" autocomplete="off" placeholder="请输入新建审批链接,如:adm/official/add" lay-reqText="请输入新建审批链接" class="layui-input">
+				</div>
+				<span class="red" style="font-size:12px;">(重要:输入新建审批链接,可在【系统管理】的【功能节点】查找,输错无效)</span></td>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">查看审批链接<font>*</font></td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+					<input type="text" name="view_url" value="{$detail.view_url}" lay-verify="required" autocomplete="off" placeholder="请输入查看审批链接,如:adm/official/view" lay-reqText="请输入查看审批链接" class="layui-input">
+				</div>
+				<span class="red" style="font-size:12px;">(重要:输入查看审批链接,可在【系统管理】的【功能节点】查找,输错无效)</span></td>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">应用部门</td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:50%;">
+					<select id="department_ids" name="department_ids" xm-selected="{$detail.department_ids}" xm-select="select1" xm-select-skin="default"></select>
+				</div>
+				<span class="red" style="font-size:12px;">(如果不选,默认是全公司)</span>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">消息通知模板</td>
+			<td>
+				<input type="text" name="template_title" value="{$detail.template_title|default=''}" readonly autocomplete="off" class="layui-input picker-oa" data-types='template' placeholder="请选择">
+				<input type="hidden" name="template_id" value="{$detail.template_id}">
+			</td>
+			<td class="layui-td-gray">展示图标<font>*</font></td>
+			<td>
+				<div class="layui-input-inline" style="width:50%;">
+					<input class="layui-input" type="text" name="icon" value="{$detail.icon}" placeholder="请输入图标" lay-verify="required" lay-reqText="请输入图标" >
+				</div>			
+				<a href="/static/assets/icon/index.html" target="_blank" style="margin-left:10px; color:#007AFF">[查看图标]</a>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">在工作台快捷显示</td>
+			<td>
+				<input type="radio" name="is_list" value="1" title="显示" {eq name="$detail.is_list" value="1"}checked{/eq}>
+				<input type="radio" name="is_list" value="0" title="不显示" {eq name="$detail.is_list" value="0"}checked{/eq}>
+			</td>
+			<td class="layui-td-gray-2">审批通过后支持通知抄送人</td>
+			<td>
+				<input type="radio" name="is_copy" value="1" title="支持" {eq name="$detail.is_copy" value="1"}checked{/eq}>
+				<input type="radio" name="is_copy" value="0" title="不支持" {eq name="$detail.is_copy" value="0"}checked{/eq}>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">审批过程中支持撤回</td>
+			<td>
+				<input type="radio" name="is_back" value="1" title="支持" {eq name="$detail.is_back" value="1"}checked{/eq}>
+				<input type="radio" name="is_back" value="0" title="不支持" {eq name="$detail.is_back" value="0"}checked{/eq}>
+			</td>
+			<td class="layui-td-gray-2">审批时支持上传附件</td>
+			<td>
+				<input type="radio" name="is_file" value="1" title="支持" {eq name="$detail.is_file" value="1"}checked{/eq}>
+				<input type="radio" name="is_file" value="0" title="不支持" {eq name="$detail.is_file" value="0"}checked{/eq}>
+			</td>
+		</tr>
+		<tr>	
+			<td class="layui-td-gray-2">审批通过后支持反确认</td>
+			<td>
+				<input type="radio" name="is_reversed" value="1" title="支持" {eq name="$detail.is_reversed" value="1"}checked{/eq}>
+				<input type="radio" name="is_reversed" value="0" title="不支持" {eq name="$detail.is_reversed" value="0"}checked{/eq}>
+			</td>
+			<td class="layui-td-gray-2">审批通过后支持导出PDF打印</td>
+			<td>
+				<input type="radio" name="is_export" value="1" title="支持" {eq name="$detail.is_export" value="1"}checked{/eq}>
+				<input type="radio" name="is_export" value="0" title="不支持" {eq name="$detail.is_export" value="0"}checked{/eq}>
+			</td>
+		</tr>
+		<tr>
+			<td colspan="4">
+				<span class="red" style="font-size:12px;">温馨提示:审批类型的配置,如果有不明白的<a class="blue" href="https://blog.gougucms.com/home/book/detail/bid/3/id/242.html" target="_blank">可以点击这里查看</a></span></td>
+			</td>
+		</tr>
+	</table>
+	{/eq}
+	<div class="pt-4">
+		<input type="hidden" name="id" value="{$id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','formSelects','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,formSelects=layui.formSelects;
+		//选择应用部门
+		var selcted = $('#department_ids').attr('xm-selected');
+		formSelects.data('select1', 'server', {
+			url: '/api/index/get_department_select',
+			keyword: selcted,
+		});		
+		//监听提交
+		form.on('submit(webform)', function(data){
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);					
+				}
+			}
+			tool.post("/adm/flow/cate_add", data.field, callback);
+			return false;
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 111 - 0
app/adm/view/flow/catelist.html

@@ -0,0 +1,111 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+    <table class="layui-hide" id="test" lay-filter="test"></table>
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm side-a" type="button" data-href="/adm/flow/cate_add">+ 添加审批类型</button>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+	<script>
+	const moduleInit = ['tool'];
+	function gouguInit() {
+		var table = layui.table, tool = layui.tool, form = layui.form;
+		layui.pageTable = table.render({
+			elem: '#test'
+			,toolbar: '#toolbarDemo'
+			,defaultToolbar: false
+			,title:'审批类型'
+			,url: "/adm/flow/catelist"
+			,limit: 20
+			,page: true
+			,cellMinWidth: 60
+			,cols: [[
+					{field:'id',width:80, title: 'ID号', align:'center'}
+					,{field:'icon',title: '审批类型名称',width: 150,templet: function(d){
+						var html='<strong class="iconfont '+d.icon+'"></strong> ' +d.title;
+						return html;
+					}}
+					,{field:'module',title: '审批模块',width:80, align:'center'}
+					,{field:'check_table',title: '数据表',width:150}
+					,{field:'name',title: '类型标识',width:150}
+					,{field:'departments',title: '应用部门',minWidth:180}
+					,{field:'add_url',title: '审批新增链接',minWidth:180}
+					,{field:'view_url',title: '审批查看链接',minWidth:180}
+					,{field:'is_list',title: '列表显示',width:80,align:'center',templet: function(d){
+						var html1='<span class="green">显示</span>';
+						var html2='<span class="yellow">不显示</span>';
+						if(d.is_list==1){
+							return html1;
+						}
+						else{
+							return html2;
+						}
+					}}
+					,{field:'sort',title: '排序',width:60, align:'center'}
+					,{field:'status', title: '状态',width:80,align:'center',templet: function(d){
+						var html1='<span class="green">正常</span>';
+						var html2='<span class="yellow">禁用</span>';
+						if(d.status==1){
+							return html1;
+						}
+						else{
+							return html2;
+						}
+					}}
+					,{width:90,fixed:'right',title: '操作', align:'center',templet: function(d){
+						var html='';
+						var btn='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>';
+						var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
+						var btn2='<a class="layui-btn layui-btn-xs" lay-event="open">启用</a>';
+						if(d.status==1){
+							html = '<div class="layui-btn-group">'+btn+btn1+'</div>';
+						}
+						else{
+							html = '<div class="layui-btn-group">'+btn+btn2+'</div>';
+						}
+						return html;
+					}}
+				]]
+			});
+			
+			table.on('tool(test)',function (obj) {
+				if(obj.event === 'edit'){					
+					tool.side('/adm/flow/cate_add?id='+obj.data.id);
+				}
+				if(obj.event === 'disable'){
+					layer.confirm('确定要禁用该审批类型吗?', {icon: 3, title:'提示'}, function(index){
+						let callback = function (e) {
+							layer.msg(e.msg);
+							if (e.code == 0) {
+								layui.pageTable.reload();
+							}
+						}
+						tool.post("/adm/flow/cate_check", { id: obj.data.id,status: 0,title: obj.data.title}, callback);
+						layer.close(index);
+					});
+				}
+				if(obj.event === 'open'){
+					layer.confirm('确定要启用该审批类型吗?', {icon: 3, title:'提示'}, function(index){
+						let callback = function (e) {
+							layer.msg(e.msg);
+							if (e.code == 0) {
+								layui.pageTable.reload();
+							}
+						}
+						tool.post("/adm/flow/cate_check", { id: obj.data.id,status: 1,title: obj.data.title}, callback);
+						layer.close(index);
+					});
+				}
+			});
+		}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 113 - 0
app/adm/view/flow/datalist.html

@@ -0,0 +1,113 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-3">
+    <table class="layui-hide" id="test" lay-filter="test"></table>
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm addNew" type="button">+ 添加审批流程</button>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+	<script>
+	const moduleInit = ['tool'];
+	function gouguInit() {
+		var table = layui.table, tool = layui.tool, form = layui.form;
+		layui.pageTable = table.render({
+			elem: '#test'
+			,toolbar: '#toolbarDemo'
+			,defaultToolbar: false
+			,title:'审批流程列表'
+			,url: "/adm/flow/datalist"
+			,page: true //开启分页
+			,limit: 20
+			,cellMinWidth: 80
+			,cols: [[
+					{field:'id',width:80, title: 'ID号', align:'center'}
+					,{field:'title',title: '流程名称',width:150}
+					,{field:'check_type',title: '审批流类型', align:'center',width:110,templet:function(d){
+						var html = '<span class="green">自由审批流</span>';
+						if(d.check_type==2){
+							html = '<span class="blue">固定审批流</span>';
+						}
+						if(d.check_type==3){
+							html = '<span class="yellow">可回退审批流</span>';
+						}
+						if(d.check_type==4){
+							html = '<span class="red">条件审批流</span>';
+						}
+						return html;
+					}}
+					,{field:'cate',title: '关联审批类型',width:110, align:'center'}
+					,{field:'module',title: '关联审批模块',width:110, align:'center'}
+					,{field:'departments',title: '应用部门',minWidth:160}
+					,{field:'copy_unames',title: '默认抄送人',minWidth:160}
+					,{field:'status', title: '状态',width:80,align:'center',templet: function(d){
+						var html1='<span class="green">正常</span>';
+						var html2='<span class="yellow">禁用</span>';
+						if(d.status==1){
+							return html1;
+						}
+						else{
+							return html2;
+						}
+					}}
+					,{width:90,title: '操作', align:'center',templet: function(d){
+						var html='';
+						var btn='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>';
+						var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
+						var btn2='<a class="layui-btn layui-btn-xs" lay-event="open">启用</a>';
+						if(d.status==1){
+							html = '<div class="layui-btn-group">'+btn+btn1+'</div>';
+						}
+						else{
+							html = '<div class="layui-btn-group">'+btn+btn2+'</div>';
+						}
+						return html;
+					}}
+				]]
+			});
+			
+			table.on('tool(test)',function (obj) {
+				if(obj.event === 'edit'){		
+					tool.side('/adm/flow/add?id='+obj.data.id);
+				}
+				if(obj.event === 'disable'){
+					layer.confirm('确定要禁用该流程吗?', {icon: 3, title:'提示'}, function(index){
+						let callback = function (e) {
+							layer.msg(e.msg);
+							if (e.code == 0) {
+								layui.pageTable.reload();
+							}
+						}
+						tool.post("/adm/flow/check", { id: obj.data.id,status: 0 }, callback);
+						layer.close(index);						
+					});
+				}
+				if(obj.event === 'open'){
+					layer.confirm('确定要启用该流程吗?', {icon: 3, title:'提示'}, function(index){
+						let callback = function (e) {
+							layer.msg(e.msg);
+							if (e.code == 0) {
+								layui.pageTable.reload();
+							}
+						}
+						tool.post("/adm/flow/check", { id: obj.data.id,status: 1 }, callback);
+						layer.close(index);	
+					});
+				}
+			});
+			
+			$('body').on('click','.addNew',function(){
+				tool.side("/adm/flow/add");
+				return false;
+			});
+		}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 54 - 0
app/adm/view/flow/module_add.html

@@ -0,0 +1,54 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-4">
+	<h3 class="pb-1">审批模块</h3>
+	{eq name="$id" value="0"}
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray">模块名称<font>*</font></td>
+			<td><input type="text" name="title" lay-verify="required" autocomplete="off" placeholder="请输入模块名称" lay-reqText="请输入审批模块名称" class="layui-input"></td>
+			<td class="layui-td-gray">排序</td>
+			<td><input type="text" name="sort" autocomplete="off" class="layui-input"></td>
+		</tr>
+	</table>
+	{else/}
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray">模块名称<font>*</font></td>
+			<td><input type="text" name="title" value="{$detail.title}" lay-verify="required" autocomplete="off" placeholder="请输入审批模块名称" lay-reqText="请输入模块名称" class="layui-input"></td>
+			<td class="layui-td-gray">排序</td>
+			<td><input type="text" name="sort" value="{$detail.sort}" autocomplete="off" class="layui-input"></td>
+		</tr>
+	</table>
+	{/eq}
+	<div class="pt-2">
+		<input type="hidden" name="id" value="{$id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','formSelects'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,formSelects=layui.formSelects;
+		//监听提交
+		form.on('submit(webform)', function(data){
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);					
+				}
+			}
+			tool.post("/adm/flow/module_add", data.field, callback);
+			return false;
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 92 - 0
app/adm/view/flow/modulelist.html

@@ -0,0 +1,92 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+    <table class="layui-hide" id="test" lay-filter="test"></table>
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm side-a" type="button" data-href="/adm/flow/module_add">+ 添加模块</button>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+	<script>
+	const moduleInit = ['tool'];
+	function gouguInit() {
+		var table = layui.table, tool = layui.tool, form = layui.form;
+		layui.pageTable = table.render({
+			elem: '#test'
+			,toolbar: '#toolbarDemo'
+			,defaultToolbar: false
+			,title:'审批模块'
+			,url: "/adm/flow/modulelist"
+			,limit: 100
+			,page: false
+			,cellMinWidth: 60
+			,cols: [[
+					{field:'id',width:80, title: 'ID号', align:'center'}
+					,{field:'title',title: '模块名称'}
+					,{field:'sort',title: '排序',width:60, align:'center'}
+					,{field:'status', title: '状态',width:80,align:'center',templet: function(d){
+						var html1='<span class="green">正常</span>';
+						var html2='<span class="yellow">禁用</span>';
+						if(d.status==1){
+							return html1;
+						}
+						else{
+							return html2;
+						}
+					}}
+					,{width:90,title: '操作', align:'center',templet: function(d){
+						var html='';
+						var btn='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>';
+						var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
+						var btn2='<a class="layui-btn layui-btn-xs" lay-event="open">启用</a>';
+						if(d.status==1){
+							html = '<div class="layui-btn-group">'+btn+btn1+'</div>';
+						}
+						else{
+							html = '<div class="layui-btn-group">'+btn+btn2+'</div>';
+						}
+						return html;
+					}}
+				]]
+			});
+			
+			table.on('tool(test)',function (obj) {
+				if(obj.event === 'edit'){					
+					tool.side('/adm/flow/module_add?id='+obj.data.id);
+				}
+				if(obj.event === 'disable'){
+					layer.confirm('确定要禁用该模块吗?', {icon: 3, title:'提示'}, function(index){
+						let callback = function (e) {
+							layer.msg(e.msg);
+							if (e.code == 0) {
+								layui.pageTable.reload();
+							}
+						}
+						tool.post("/adm/flow/module_check", { id: obj.data.id,status: 0,title: obj.data.title}, callback);
+						layer.close(index);
+					});
+				}
+				if(obj.event === 'open'){
+					layer.confirm('确定要启用该模块吗?', {icon: 3, title:'提示'}, function(index){
+						let callback = function (e) {
+							layer.msg(e.msg);
+							if (e.code == 0) {
+								layui.pageTable.reload();
+							}
+						}
+						tool.post("/adm/flow/module_check", { id: obj.data.id,status: 1,title: obj.data.title}, callback);
+						layer.close(index);
+					});
+				}
+			});
+		}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 513 - 0
app/adm/view/flow/table.html

@@ -0,0 +1,513 @@
+{extend name="../../base/view/common/base" /}
+{block name="style"}
+<style>
+.layui-form-item{margin-bottom:0}
+</style>
+{/block}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">审批条件	<span id="addFlow2" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加审批层级</span></h3>
+	{eq name="$id" value="0"}
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray-2">
+				第1级
+				<span id="addFlow2" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加条件分支</span>
+			</td>
+			<td>
+				条件分支(优先级1)
+				<span id="addFlow2" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加条件组</span>
+				<div>
+					条件组1<span id="addFlow2" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加条件字段</span>
+					<div class="layui-form-item layui-form-pane">
+						<div class="layui-inline">
+						  <label class="layui-form-label" style="width:40px">当</label>
+						  <div class="layui-input-inline" style="width:132px">
+							<select name="columns[]" lay-filter="columns" lay-verify="required" lay-reqText="请选择字段">
+								<option value="">选择条件字段</option>
+								{volist name="$columns" id="vo"}
+								<option value="{$vo.Field}">{$vo.Comment|default=$vo.Field}</option>
+								{/volist}
+							</select>						
+						  </div>
+						  <div class="layui-input-inline" style="width:100px">
+								<select name="flow_cate" lay-filter="flowcate" lay-verify="required" lay-reqText="请选择审批模块">
+									<option value="1">等于</option>
+									<option value="2">小于</option>
+									<option value="3">小于等于</option>
+									<option value="4">大于</option>
+									<option value="5">大于等于</option>
+								</select>
+						  </div>
+						  <label class="layui-form-label" style="width:80px">审批人员</label>
+						  <div class="layui-input-inline" style="width:360px;">
+							<input type="text" name="unames[]" value="" autocomplete="off" placeholder="请选择审批人" readonly class="layui-input picker-admin">
+							<input type="hidden" name="uids[]" value="">
+						  </div>
+						</div>
+					</div>
+					且
+					<div class="layui-form-item layui-form-pane">
+						<div class="layui-inline">
+						  <label class="layui-form-label" style="width:40px">当</label>
+						  <div class="layui-input-inline" style="width:132px">
+							<select name="columns[]" lay-filter="columns" lay-verify="required" lay-reqText="请选择字段">
+								<option value="">选择条件字段</option>
+								{volist name="$columns" id="vo"}
+								<option value="{$vo.Field}">{$vo.Comment|default=$vo.Field}</option>
+								{/volist}
+							</select>						
+						  </div>
+						  <div class="layui-input-inline" style="width:100px">
+								<select name="flow_cate" lay-filter="flowcate" lay-verify="required" lay-reqText="请选择审批模块">
+									<option value="1">等于</option>
+									<option value="2">小于</option>
+									<option value="3">小于等于</option>
+									<option value="4">大于</option>
+									<option value="5">大于等于</option>
+								</select>
+						  </div>
+						  <label class="layui-form-label" style="width:80px">审批人员</label>
+						  <div class="layui-input-inline" style="width:360px;">
+							<input type="text" name="unames[]" value="" autocomplete="off" placeholder="请选择审批人" readonly class="layui-input picker-admin">
+							<input type="hidden" name="uids[]" value="">
+						  </div>
+						</div>
+					</div>
+				</div>
+				条件分支(优先级2)
+				<span id="addFlow2" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加条件组</span>
+				<div>
+					条件组1<span id="addFlow2" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加条件字段</span>
+					<div class="layui-form-item layui-form-pane">
+						<div class="layui-inline">
+						  <label class="layui-form-label" style="width:40px">当</label>
+						  <div class="layui-input-inline" style="width:132px">
+							<select name="columns[]" lay-filter="columns" lay-verify="required" lay-reqText="请选择字段">
+								<option value="">选择条件字段</option>
+								{volist name="$columns" id="vo"}
+								<option value="{$vo.Field}">{$vo.Comment|default=$vo.Field}</option>
+								{/volist}
+							</select>						
+						  </div>
+						  <div class="layui-input-inline" style="width:100px">
+								<select name="flow_cate" lay-filter="flowcate" lay-verify="required" lay-reqText="请选择审批模块">
+									<option value="1">等于</option>
+									<option value="2">小于</option>
+									<option value="3">小于等于</option>
+									<option value="4">大于</option>
+									<option value="5">大于等于</option>
+								</select>
+						  </div>
+						  <label class="layui-form-label" style="width:80px">审批人员</label>
+						  <div class="layui-input-inline" style="width:360px;">
+							<input type="text" name="unames[]" value="" autocomplete="off" placeholder="请选择审批人" readonly class="layui-input picker-admin">
+							<input type="hidden" name="uids[]" value="">
+						  </div>
+						</div>
+					</div>
+					且
+					<div class="layui-form-item layui-form-pane">
+						<div class="layui-inline">
+						  <label class="layui-form-label" style="width:40px">当</label>
+						  <div class="layui-input-inline" style="width:132px">
+							<select name="columns[]" lay-filter="columns" lay-verify="required" lay-reqText="请选择字段">
+								<option value="">选择条件字段</option>
+								{volist name="$columns" id="vo"}
+								<option value="{$vo.Field}">{$vo.Comment|default=$vo.Field}</option>
+								{/volist}
+							</select>						
+						  </div>
+						  <div class="layui-input-inline" style="width:100px">
+								<select name="flow_cate" lay-filter="flowcate" lay-verify="required" lay-reqText="请选择审批模块">
+									<option value="1">等于</option>
+									<option value="2">小于</option>
+									<option value="3">小于等于</option>
+									<option value="4">大于</option>
+									<option value="5">大于等于</option>
+								</select>
+						  </div>
+						  <label class="layui-form-label" style="width:80px">审批人员</label>
+						  <div class="layui-input-inline" style="width:360px;">
+							<input type="text" name="unames[]" value="" autocomplete="off" placeholder="请选择审批人" readonly class="layui-input picker-admin">
+							<input type="hidden" name="uids[]" value="">
+						  </div>
+						</div>
+					</div>
+				</div>				
+				默认情况分支(优先级3)
+				<div class="layui-form-item layui-form-pane" style="margin-bottom:0">
+					<div class="layui-input-inline" style="width:160px;">
+						<select name="types[]" lay-filter="flowtype">
+							<option value="1">当前部门负责人</option>
+							<option value="2">上一级部门负责人</option>
+							<option value="3">指定人员(多人或签)</option>
+							<option value="4">指定人员(多人会签)</option>
+						</select>
+					</div>
+					<label class="layui-form-label" style="width:80px">审批人员</label>
+					<div class="layui-input-inline" style="width:360px;">
+						<input type="text" name="unames[]" value="" autocomplete="off" placeholder="请选择审批人" readonly class="layui-input picker-admin">
+						<input type="hidden" name="uids[]" value="">
+					</div>
+					<span class="layui-label-inline">
+						如存在未满足其他分支条件的情况,则进入此分支
+					</span>				
+				</div>
+			</td>	
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				第2级
+				<span id="addFlow2" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加条件分支</span>
+			</td>
+			<td>
+				
+			</td>
+		</tr>
+	</table>
+	{else/}
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray">流程名称<font>*</font></td>
+			<td>
+				<input type="text" name="title" value="{$detail.title}" autocomplete="off" placeholder="请输入审批流程名称" lay-verify="required" lay-reqText="请输入审批流程名称" class="layui-input">
+			</td>
+			<td class="layui-td-gray">流程标识<font>*</font></td>
+			<td><input type="text" name="name" value="{$detail.name}" autocomplete="off" placeholder="请输入审批流程标识" lay-verify="required" lay-reqText="请输入审批流程标识" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">审批模块<font>*</font></td>
+			<td>
+				<select name="flow_cate" lay-filter="flowcate" lay-verify="required" lay-reqText="请选择审批模块">
+					<option value="">请选择审批模块</option>
+					{volist name=":get_base_data('flow_cate')" id="vo"}
+						<option value="{$vo.id}" {eq name="$vo.id" value="$detail.flow_cate"}selected{/eq}>{$vo.title}</option>
+					{/volist}
+				</select>
+			</td>
+			<td class="layui-td-gray">审批类型<font>*</font></td>
+			<td>
+				<select name="flow_item" lay-filter="flowitem" lay-verify="required" lay-reqText="请选择审批类型">
+				  <option value="">--请选择--</option>
+				  {volist name="$detail.flow_item_list" id="vo"}
+				  <option value="{$vo.id}" {eq name="$detail.flow_item" value="$vo.id"}selected=""{/eq}>{$vo.title}</option>
+				  {/volist}
+				</select>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">应用部门</td>
+			<td colspan="3">
+				<div class="layui-input-inline" style="width:80%;">
+					<select id="department_ids" name="department_ids" xm-selected="{$detail.department_ids}" xm-select="select1" xm-select-skin="default"></select>
+				</div>
+				<span class="red" style="font-size:12px;">(如果不选,默认是全公司)</span>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">流程说明</td>
+			<td colspan="3">
+				<textarea name="remark" placeholder="请输入流程说明" class="layui-textarea">{$detail.remark}</textarea>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">审批流类型<font>*</font></td>
+			<td colspan="3">
+				<input type="radio" name="check_type" lay-filter="checktype" value="1" title="自由审批流" {eq name="$detail.check_type" value="1"}checked{/eq}>
+				<input type="radio" name="check_type" lay-filter="checktype" value="2" title="固定审批流" {eq name="$detail.check_type" value="2"}checked{/eq}>
+				<input type="radio" name="check_type" lay-filter="checktype" value="3" title="可回退的审批流" {eq name="$detail.check_type" value="3"}checked{/eq}>
+				<input type="radio" name="check_type" lay-filter="checktype" value="4" title="条件审批流" {eq name="$detail.check_type" value="4"}checked{/eq}>
+			</td>
+		</tr>
+		<tr id="flowTr1" {neq name="$detail.check_type" value="1"}style="display:none"{/neq}>
+			<td class="layui-td-gray">审批流程<font>*</font></td>
+			<td colspan="3">
+				<div style="padding:10px; font-size:12px; background-color:#fffcf0">
+					<p><strong>温馨提示</strong></p>
+					<p>无需配置审批人,审批时,根据实际情况选择审批人即可,自由度最高。</p>
+				</div>
+			</td>
+		</tr>
+		<tr id="flowTr2" {neq name="$detail.check_type" value="2"}style="display:none"{/neq}>
+			<td class="layui-td-gray">审批流程<font>*</font></td>
+			<td colspan="3">
+				<div id="flowList2">
+					{eq name="$detail.check_type" value="2"}
+					{volist name="detail.flow_list" id="vo"}
+					<div class="layui-form-item layui-form-pane">
+						<div class="layui-inline">
+						  <label class="layui-form-label">第{$key+1}级</label>
+						  <div class="layui-input-inline">
+							<select name="flowType[]" lay-filter="flowtype">
+								<option value="1" {eq name="$vo.flow_type" value="1"}selected=""{/eq}>当前部门负责人</option>
+								<option value="2" {eq name="$vo.flow_type" value="2"}selected=""{/eq}>上一级部门负责人</option>
+								<option value="3" {eq name="$vo.flow_type" value="3"}selected=""{/eq}>指定人员(多人或签)</option>
+								<option value="4" {eq name="$vo.flow_type" value="4"}selected=""{/eq}>指定人员(多人会签)</option>
+							</select>
+						  </div>
+						</div>
+						<div class="layui-inline select-{$vo.flow_type}">
+						  <label class="layui-form-label">指定人员</label>
+						  <div class="layui-input-inline" style="width:360px;">
+							<input type="text" name="flowNamesA[]" value="{$vo.flow_unames}" autocomplete="off" readonly class="layui-input picker-more">
+							<input type="hidden" name="flowUidsA[]" value="{$vo.flow_uids}">
+						  </div>
+						</div>
+						{gt name="$key" value="0"}
+						<span class="layui-btn layui-btn-danger layui-btn-sm">删除</span>
+						{/gt}
+					</div>
+					{/volist}
+					{else/}
+					<div class="layui-form-item layui-form-pane">
+						<div class="layui-inline">
+						  <label class="layui-form-label">第1级</label>
+						  <div class="layui-input-inline">
+							<select name="flowType[]" lay-filter="flowtype">
+								<option value="1">当前部门负责人</option>
+								<option value="2">上一级部门负责人</option>
+								<option value="3">指定人员(多人或签)</option>
+								<option value="4">指定人员(多人会签)</option>
+							</select>
+						  </div>
+						</div>
+						<div class="layui-inline select-1">
+						  <label class="layui-form-label">指定人员</label>
+						  <div class="layui-input-inline" style="width:360px;">
+							<input type="text" name="flowNamesA[]" value="" autocomplete="off" readonly class="layui-input picker-more">
+							<input type="hidden" name="flowUidsA[]" value="">
+						  </div>
+						</div>
+					</div>
+					{/eq}
+				</div>
+				<span id="addFlow2" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加审批层级</span>
+				<div style="padding:10px; margin-top:10px; font-size:12px; background-color:#fffcf0">
+					<p><strong>温馨提示</strong></p>
+					<p>1、当选择<strong> “当前部门负责人” </strong>审批时。系统仅会通知当前部门的负责人。</p>
+					<p>2、当选择<strong> “上一级部门负责人” </strong>审批时。系统仅会通知当前部门的上一级部门的负责人。</p>
+					<p>3、当选择<strong> “指定人员(多人或签)” </strong>时,表示指定用户中任意一人审批即可,可单选或多选。</p>
+					<p>4、当选择<strong> “指定人员(多人会签)” </strong>时,表示指定人员中所有人都需要审批,可单选或多选。</p>
+					<p>5、如果指定用户没有分配查看审批模块的功能权限,系统会通知其审批,但是他无法查看此审批数据信息。</p>
+				</div>
+			</td>
+		</tr>
+		<tr id="flowTr3" {neq name="$detail.check_type" value="3"}style="display:none"{/neq}>
+			<td class="layui-td-gray">审批流程<font>*</font></td>
+			<td colspan="3">
+				<div id="flowList3">
+					{eq name="$detail.check_type" value="3"}
+					{volist name="detail.flow_list" id="vo"}
+					<div class="layui-form-item layui-form-pane">
+						<div class="layui-inline">
+						  <label class="layui-form-label">第{$key+1}级</label>
+						  <div class="layui-input-inline">
+							<input type="text" name="flowName[]" value="{$vo.flow_name}" autocomplete="off" placeholder="请输入流程名称" class="layui-input">
+						  </div>
+						</div>
+						<div class="layui-inline select-3">
+						  <label class="layui-form-label">指定人员</label>
+						  <div class="layui-input-inline" style="width:360px;">
+							<input type="text" name="flowNamesB[]" value="{$vo.flow_unames}" autocomplete="off" readonly class="layui-input picker-one">
+							<input type="hidden" name="flowUidsB[]" value="{$vo.flow_uids}">
+						  </div>
+						</div>
+						{gt name="$key" value="0"}
+						<span class="layui-btn layui-btn-danger layui-btn-sm">删除</span>
+						{/gt}
+					</div>
+					{/volist}
+					{else/}
+					<div class="layui-form-item layui-form-pane">
+						<div class="layui-inline">
+						  <label class="layui-form-label">第1级</label>
+						  <div class="layui-input-inline">
+							<input type="text" name="flowName[]" value="" autocomplete="off" placeholder="请输入流程名称" class="layui-input">
+						  </div>
+						</div>
+						<div class="layui-inline select-3">
+						  <label class="layui-form-label">指定人员</label>
+						  <div class="layui-input-inline" style="width:360px;">
+							<input type="text" name="flowNamesB[]" value="" autocomplete="off" readonly class="layui-input picker-one">
+							<input type="hidden" name="flowUidsB[]" value="">
+						  </div>
+						</div>
+					</div>
+					{/eq}
+				</div>
+				<span id="addFlow3" class="layui-btn layui-btn-xs layui-btn-normal">+ 添加审批层级</span>
+				<div style="padding:10px; margin-top:10px; font-size:12px; background-color:#fffcf0">
+					<p><strong>温馨提示</strong></p>
+					<p>1、<strong>指定人员</strong>单选。后期审批的时候,审批人只能该指定人员。</p>
+					<p>2、该审批流程可<strong>回退</strong>,当拒绝审核时,会自动回退到上一位审批人节点。</p>
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">抄送人</td>
+			<td colspan="3">
+				<input type="text" name="copy_unames" value="{$detail.copy_unames}" autocomplete="off" readonly class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="copy_uids" value="{$detail.copy_uids}">
+			</td>
+		</tr>
+	</table>
+	{/eq}
+	<div class="py-3">
+		<input type="hidden" name="id" value="{$id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','formSelects','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,formSelects = layui.formSelects;		  
+		//选择应用模块
+		form.on('select(flowcate)', function(data){
+			let callback = function (e) {
+				if (e.code == 0) {
+					if(e.data.length>0){
+						let ops='<option value="">--请选择--</option>';
+						for(var i=0;i<e.data.length;i++){
+							ops+='<option value="'+e.data[i].id+'">'+e.data[i].title+'</option>';
+						}
+						$('[name="flow_item"]').html(ops);
+						form.render();
+					}
+					else{
+						$('[name="flow_item"]').html('');
+						form.render();
+					}
+				}
+			}
+			tool.get("/adm/api/get_flow_item", {cate:data.value}, callback);
+		})
+		
+		//选择应用部门
+		var selcted = $('#department_ids').attr('xm-selected');
+		formSelects.data('select1', 'server', {
+			url: '/api/index/get_department_select',
+			keyword: selcted,
+		});
+		
+		
+		form.on('radio(checktype)', function(data){
+		  if(data.value==1){
+			$('#flowTr1').show();
+			$('#flowTr2').hide();
+			$('#flowTr3').hide();
+		  }
+		  else if(data.value==2){
+			$('#flowTr1').hide();
+			$('#flowTr2').show();
+			$('#flowTr3').hide();
+		  }
+		  else{
+			$('#flowTr1').hide();
+			$('#flowTr2').hide();
+			$('#flowTr3').show();
+		  }
+		});
+		
+		form.on('select(flowtype)', function(data){
+		  $(data.elem).parents('.layui-form-item').find('.layui-inline').eq(1).attr('class','layui-inline select-'+data.value);
+		});
+
+		//监听提交
+		form.on('submit(webform)', function(data){
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);					
+				}
+			}
+			tool.post("/adm/flow/add", data.field, callback);
+			return false;
+		});
+    
+		
+		$('#addFlow2').on('click',function(){
+			var len = $('#flowList2').find('.layui-form-item').length;
+			var index = len+1;
+			var timestamp=new Date().getTime();
+			var tem='<div class="layui-form-item  layui-form-pane">\
+						<div class="layui-inline">\
+						  <label class="layui-form-label label-index">第'+index+'级</label>\
+						  <div class="layui-input-inline">\
+							<select name="flowType[]" lay-filter="flowtype">\
+								<option value="1">当前部门负责人</option>\
+								<option value="2">上一级部门负责人</option>\
+								<option value="3">指定人员(多人或签)</option>\
+								<option value="4">指定人员(多人会签)</option>\
+							</select>\
+						  </div>\
+						</div>\
+						<div class="layui-inline select-1">\
+						  <label class="layui-form-label">指定人员</label>\
+						  <div class="layui-input-inline" style="width:360px;">\
+							<input type="text" name="flowNamesA[]" value="" autocomplete="off" readonly class="layui-input picker-admin" data-type="2">\
+							<input type="hidden" name="flowUidsA[]" value="">\
+						  </div>\
+						</div>\
+						<span class="layui-btn layui-btn-danger layui-btn-sm">删除</span>\
+					</div>';
+			$('#flowList2').append(tem);
+			form.render();
+		});
+		
+		$('#flowList2').on('click','.layui-btn-danger',function(){
+			$(this).parents('.layui-form-item').remove();
+			var items = $('.label-index').length;
+			if(items>0){
+				$('.label-index').each(function(index,item){
+					$(this).html('第'+(index+2)+'级');
+				})
+			}
+		});			
+		
+		//================================
+		$('#addFlow3').on('click',function(){
+			var len = $('#flowList3').find('.layui-form-item').length;
+			var index = len+1;
+			var timestamp=new Date().getTime();
+			var tem='<div class="layui-form-item  layui-form-pane">\
+						<div class="layui-inline">\
+						  <label class="layui-form-label label-index">第'+index+'级</label>\
+						  <div class="layui-input-inline">\
+							<input type="text" name="flowName[]" value="" autocomplete="off" placeholder="请输入流程名称" class="layui-input">\
+						  </div>\
+						</div>\
+						<div class="layui-inline select-3">\
+						  <label class="layui-form-label">指定人员</label>\
+						  <div class="layui-input-inline" style="width:360px;">\
+							<input type="text" name="flowNamesB[]" value="" autocomplete="off" readonly class="layui-input picker-one">\
+							<input type="hidden" name="flowUidsB[]" value="">\
+						  </div>\
+						</div>\
+						<span class="layui-btn layui-btn-danger layui-btn-sm">删除</span>\
+					</div>';
+			$('#flowList3').append(tem);
+			form.render();
+		});
+		
+		$('#flowList3').on('click','.layui-btn-danger',function(){
+			$(this).parents('.layui-form-item').remove();
+			var items = $('.label-index').length;
+			if(items>0){
+				$('.label-index').each(function(index,item){
+					$(this).html('第'+(index+2)+'级');
+				})
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 141 - 0
app/adm/view/flow/work_flow.html

@@ -0,0 +1,141 @@
+{extend name="../../base/view/common/base" /}
+{block name="style"}
+<style>
+.flow-content{position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 1;overflow-x: scroll;overflow-y: auto;padding:30px 0;background: #F5F5F7;user-select: none;}
+.flow-box *{margin: 0;padding: 0;box-sizing: border-box;}
+.remove-node{position: absolute; top: 6px; right: 8px; display: none; font-style:normal}
+.condition-priority{position: absolute; top: 6px; right: 8px;}
+.select-icon{position: absolute; top: 42px; right: 3px;}
+
+.top-left-cover-line{position: absolute;height: 3px;width: 50%;background-color: #f5f5f7;top: -2px;left: -1px;}
+.bottom-left-cover-line{position: absolute;height: 3px;width: 50%;background-color: #f5f5f7;bottom: -2px;left: -1px;}
+.top-right-cover-line{position: absolute;height: 3px;width: 50%;background-color: #f5f5f7;top: -2px;right: -1px;}
+.bottom-right-cover-line{position: absolute;height: 3px;width: 50%;background-color: #f5f5f7;bottom: -2px;right: -1px;}
+
+.flow-zoom{position: fixed; padding:10px; height: 32px;right: 36px;top: 36px; z-index: 10;font-size: 16px; box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .3);background: #FFFFFF;border-radius: 5px;}
+.flow-zoom span.zoom-num{padding:0 12px; display: inline-block; height: 30px; line-height:28px;}
+.flow-zoom span.zoom-ctrl{display: inline-block;width: 30px; height: 30px; line-height:30px; border-radius:50%; border:1px solid #666; font-size: 20px; text-align: center;color: #666;cursor: pointer;}
+.flow-zoom span.zoom-ctrl:hover{color:#1e9fff;border-color:#1e9fff}
+.flow-zoom .layui-btn-group{display: inline-block;vertical-align:top; margin-left:12px;}
+
+.node-wrap{display: inline-flex;flex-direction: column;align-items: center;width: 100%;padding: 0 50px;position: relative;}
+.node-wrap-box{width: 220px;display: inline-flex;align-items: center;flex-direction: column;background-color: #FFFFFF;border-radius: 5px;box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .1);cursor: pointer;border: 1px solid #F5F5F5;position: relative;}
+
+.node-wrap-box:hover{box-shadow: 0 3px 6px 0 rgba(0, 0, 0, .3);transition: all .3s;}
+.node-wrap-box::before{content: "";position: absolute;top: -8px;left: 50%;-webkit-transform: translateX(-50%);transform: translateX(-50%);width: 0;height: 4px;border-style: solid;border-width: 8px 6px 4px;border-color: #cacaca transparent transparent;background: #f5f5f7;}
+.node-start::before{display:none;}
+
+.node-wrap-box:hover .remove-node{display: block;}
+.node-wrap-box .user-edit{display: inline-block;}
+.node-wrap-box:hover .user-edit{}
+.node-wrap-box .node-title{border-radius: 4px 5px 0 0 }
+.node-wrap-box>div{width: 100%;}
+.node-wrap-box>div:nth-of-type(1){padding: 6px 10px;color: white;font-size: 12px;position: relative;}
+.node-wrap-box>div:nth-of-type(2){padding: 15px 10px;display: flex;justify-content: space-between;}
+
+.node-add-btn-box{position: relative;}
+.node-add-btn-box::before{content: "";position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: -1;margin: auto;width: 2px;height: 100%;background-color: #cacaca;}
+.add-node-btn{padding: 20px 0 24px;}
+.add-node-btn button.add-node{border-radius: 50%;background: #1e9fff;font-size: 25px;border-color: #1e9fff;width: 32px;line-height: 30px;padding: 0;margin: 0;color: #fff;display: inline-block;font-weight: 400;text-align: center;white-space: nowrap;vertical-align: middle;touch-action: manipulation;cursor: pointer;border: 1px solid transparent;}
+.add-node-btn button.add-node:hover{transform: scale(1.2);transition:all .2s }
+
+.branch-box{display: flex;border-bottom: 2px solid #cccccc;border-top: 2px solid #cccccc;position: relative;}
+.branch-box-wrap{display: inline-flex;flex-direction: column;align-items: center;width: 100%;}
+.add-branch{position: absolute;display: inline-block;left: 50%;top: -15px;z-index: 1;border-radius: 15px;color: rgb(50, 150, 250);border: none;box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .1);background: #FFFFFF;padding: 5px 10px;font-size: 12px;cursor: pointer;line-height: 20px;transform: translateX(-50%);}
+
+.col-box{display: inline-flex;background: #f5f5f7;;flex-direction: column;align-items: center;position: relative;}
+.col-box::before{content: "";position: absolute;top: 0;left: 0;right: 0;bottom: 0;z-index: 0;margin: auto;width: 2px;height: 100%;background-color: #cacaca;}
+
+.condition-judge{background-color: #FFFFFF;border-radius: 5px;width: 220px;position: relative;box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .1);cursor: pointer;border: 1px solid #FFFFFF;}
+.condition-judge:hover{border: 1px solid #16b777;transition:all .3s}
+.condition-judge:hover .remove-node{display: block;}
+.condition-judge:hover .condition-priority{display:none;}
+.condition-judge>div:nth-of-type(2){padding: 15px 10px;}
+
+.condition-node-box{display: inline-flex;flex-direction: column;align-items: center;position: relative;padding: 30px 30px 0 30px;}
+.condition-node-box::before{content: "";position: absolute;top: 0;left: 0;right: 0;bottom: 0;margin: auto;width: 2px;height: 100%;background-color: #cacaca;}
+.condition-input{line-height: 19px;height: 18px;display: inline-block;width:150 px;padding: 0;padding-left: 5px;font-size: 12px;border: none;}
+.condition-title{padding: 5px 0;background-color: #ffffff;border-radius: 5px 5px 0 0;color: #15bc83;font-size: 12px;position: relative;}
+
+.end-node{border-radius: 50%;font-size: 14px;color: rgba(25, 31, 37, .4);text-align: left;}
+.end-node-circle{width: 10px;height: 10px;margin: auto;border-radius: 50%;background: #dbdcdc;}.end-node-text{margin-top: 5px;text-align: center;}
+</style>
+{/block}
+<!-- 主体 -->
+{block name="body"}
+<div class="flow-content">
+	<div id="flowBar" class="flow-zoom" data-zoom="10">               
+		<span class="zoom-ctrl" data-type="1"><strong>-</strong></span>         
+		<span class="zoom-num">100%</span>         
+		<span class="zoom-ctrl" data-type="2">+</span>
+		<div class="layui-btn-group">
+		  <button type="button" class="layui-btn layui-btn-sm">预览</button>
+		  <button type="button" class="layui-btn layui-btn-sm layui-bg-blue">发布</button>
+		</div>
+	</div>
+		
+	<div id="flowBox" class="flow-box" style="transform: scale(1); transform-origin: 50% 0px 0px;">
+		<!-- 发起人 -->
+		<div>
+			<div class="node-wrap">
+				<div class="node-wrap-box node-start">
+					<div class="node-title" style="background: #2f363c;">
+						<span>发起人</span>
+					</div>
+					<div>
+						<span>请设置发起人</span>
+						<i class="select-icon"><?xml version="1.0" encoding="UTF-8"?><svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 12L31 24L19 36" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></i>
+					</div>
+				</div>
+				<!-- 箭头 -->
+				<div class="node-add-btn-box">
+					<div class="add-node-btn">
+						<button class="add-node">+</button>
+					</div>
+				</div>
+			</div>
+		</div>
+		<!-- 审核人 -->
+		<div>
+			<div class="node-wrap">
+				<div class="node-wrap-box">
+					<div class="node-title" style="background:#ffb800">
+						<span class="user-edit">审核人</span>
+						<i class="remove-node">✖</i>
+					</div>
+					<div>
+						<span>请设置审核人</span>
+						<i class="select-icon"><?xml version="1.0" encoding="UTF-8"?><svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 12L31 24L19 36" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></i>
+					</div>
+				</div>
+				<!-- 箭头 -->
+				<div class="node-add-btn-box">
+					<div class="add-node-btn">
+						<button class="add-node">+</button>
+					</div>
+				</div>
+			</div> 
+		</div>
+		<!-- 流程结束 -->
+		<div class="end-node">
+			<div class="end-node-circle"></div>
+			<div class="end-node-text">
+				结束流程
+			</div>
+		</div>
+	</div>
+</div>
+{/block}
+<!-- /主体 -->
+{block name="copyright"}{/block}
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','oaFlow','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,oaFlow = layui.oaFlow;
+		oaFlow.init();		
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 103 - 0
app/adm/view/meeting/add.html

@@ -0,0 +1,103 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page" lay-filter="form-outs">
+	<h3 class="pb-2">会议室预定</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray-2">会议主题<font>*</font></td>
+			<td colspan="3"><input name="title" class="layui-input" value="{$detail.title|default=''}" lay-verify="required" placeholder="请输入会议主题" lay-reqText="请输入会议主题"></td>
+			<td class="layui-td-gray">会议地点<font>*</font></td>
+			<td>
+				<input type="text" name="room" value="{$detail.room|default=''}" readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择会议室" class="layui-input picker-oa" data-types="room">
+				<input type="hidden" name="room_id" value="{$detail.room_id|default=''}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">开始时间<font>*</font></td>
+			<td><input id="start_date" name="start_date" class="layui-input" value="{$detail.start_time|default=''}" readonly lay-verify="required" placeholder="请选择开始时间" lay-reqText="请选择开始时间"></td>
+			<td class="layui-td-gray">结束时间<font>*</font></td>
+			<td><input id="end_date" name="end_date" class="layui-input" value="{$detail.end_time|default=''}" readonly lay-verify="required" placeholder="请选择结束时间" lay-reqText="请选择结束时间"></td>
+			<td class="layui-td-gray">会议人数<font>*</font></td>
+			<td><input name="num" class="layui-input" value="{$detail.num|default=''}" lay-verify="required|number" placeholder="请完善会议人数" lay-reqText="请完善会议人数"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">会议需求<font>*</font></td>
+			<td colspan="5">
+				{empty name="detail"}
+				{volist name="$requirements" id="v"}
+				<input type="checkbox" name="requirement[]" title="{$v.title}" value="{$v.id}" lay-skin="primary">
+				{/volist}
+				{else/}
+				{volist name="$requirements" id="v"}
+				<input type="checkbox" name="requirement[]" title="{$v.title}" value="{$v.id}" lay-skin="primary" {eq name="$v.checked" value="1" }checked{/eq}>
+				{/volist}
+				{/empty}
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">其他要求</td>
+			<td colspan="5">
+				<input name="remark" class="layui-input" value="{$detail.remark|default=''}" placeholder="请输入其他要求">
+			</td>
+		</tr>
+	</table>
+	<div id="checkBox" data-status="{$detail.check_status|default=0}" data-id="{$detail.id|default=0}" data-checkflowid="{$detail.check_flow_id|default=0}" class="pt-3"></div>
+	<div class="pt-4">
+		<input type="hidden" name="id" value="{$detail.id|default=0}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+	</div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','oaCheck'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,oaCheck=layui.oaCheck,laydate=layui.laydate;
+		oaCheck.init({
+			check_name:'meeting_order',
+			check_btn:0
+		});
+		
+		laydate.render({
+			elem: '#start_date',
+			fullPanel :true,
+			type: 'datetime',
+			format: 'yyyy-MM-dd HH:mm'
+		});
+		
+		laydate.render({
+			elem: '#end_date',
+			fullPanel :true,
+			type: 'datetime',
+			format: 'yyyy-MM-dd HH:mm'
+		});
+	
+		//监听提交
+		form.on('submit(webform)', function (data) {
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					let checkCallback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							tool.sideClose(1000);				
+						}
+					}
+					data.field.check_name = 'meeting_order';
+					data.field.action_id = e.data.return_id;
+					oaCheck.submit(data.field,checkCallback);
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/meeting/add", data.field, callback,clickbtn);
+			return false;
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 100 - 0
app/adm/view/meeting/datalist.html

@@ -0,0 +1,100 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="table_meeting" lay-filter="table_meeting"></table>
+</div>
+
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-group">
+  	<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/adm/meeting/add">+ 添加会议室预定</button>
+  </div>
+</script>
+
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','tablePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool;
+		
+		layui.pageTable = table.render({
+			elem: "#table_meeting"
+			, toolbar: "#toolbarDemo"
+			,url: "/adm/meeting/datalist"
+			,page: true
+			,limit: 20
+			,cellMinWidth: 80
+			,height: 'full-114'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{
+					field:'check_status',title: '审批状态',width:110, align:'center',templet: function(d){
+						var html = '<span class="check-status-color-'+d.check_status+'">『'+d.check_status_str+'』</span>';
+						return html;
+					}
+				}
+				,{field:'title',title: '会议主题',minWidth: 240}
+				,{field:'meeting_date',title: '会议日期/时间',width: 280,align:'center'}
+				,{field:'room',title: '会议室',minWidth: 240}
+				,{field:'num',title: '会议人数',width: 80,align:'center'}
+				,{field: 'check_user', width: 100,title: '当前审核人'}
+				,{field:'admin_name',title: '申请人',width:90,align:'center'}
+				,{field:'create_time', title: '创建时间',width:150,align:'center'}
+				,{width:120,fixed:'right',title: '操作', align:'center',ignoreExport:true,templet:function(d){
+						var html='<div class="layui-btn-group">';
+						var btn1='<span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详情</span>';
+						var btn2='<span class="layui-btn layui-btn-xs" lay-event="edit">编辑</span>';
+						var btn3='<span class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</span>';
+						html+=btn1;
+						if((d.check_status==0 ||d.check_status==4) && d.admin_id==login_admin){
+							html+=btn2+btn3;
+						}
+						html+='</div>';
+						return html;
+				}}
+			]]
+		});
+			
+		table.on('tool(table_meeting)',function (obj) {
+			var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
+			var data = obj.data;
+			if (obj.event === 'view') {
+				tool.side("/adm/meeting/view?id="+data.id);
+				return;
+			}
+			if (obj.event === 'edit') {
+				tool.side("/adm/meeting/add?id="+data.id);
+				return;
+			}
+			if (obj.event === 'del') {
+				layer.confirm('确定要删除该内容吗?', { icon: 3, title: '提示' }, function (index) {
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							obj.del();
+						}
+					}
+					tool.delete("/adm/meeting/del", { id: data.id }, callback);
+					layer.close(index);
+				});
+				return;
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 128 - 0
app/adm/view/meeting/records.html

@@ -0,0 +1,128 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<style>
+.layui-table-tool-temp{padding-right:0}
+</style>
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-x border-t" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px;">
+			<input type="text" class="layui-input" id="diff_time" placeholder="会议日期" readonly name="diff_time">
+		</div>
+		<div class="layui-input-inline" style="width:110px;">
+			<input type="text" name="anchor"  placeholder="主持人" class="layui-input picker-admin" readonly />
+			<input type="text" name="anchor_id" value="" style="display:none" />	
+		</div>
+		<div class="layui-input-inline" style="width:220px;">
+			<input type="text" name="keywords" placeholder="会议主题" class="layui-input"/>
+		</div>	
+		<div class="layui-input-inline" style="width:150px;">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form> 
+	<table class="layui-hide" id="test" lay-filter="test"></table>
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+    <span class="layui-btn layui-btn-sm tool-add" data-href="/adm/meeting/records_add">+ 会议纪要</span>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','oaPicker','laydatePlus','tablePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool ,form = layui.form, laydatePlus = layui.laydatePlus;	
+		//日期范围
+		var diff_time = new laydatePlus({'target':'diff_time'});
+		
+		layui.pageTable = table.render({
+			elem: '#test',
+			title: '会议纪要列表',
+			toolbar: '#toolbarDemo',
+			defaultToolbar: false,
+			page: true, //开启分页
+			limit: 20,
+			height: 'full-114',
+			url: "/adm/meeting/records", //数据接口		
+			cols: [
+				[
+					{type:'checkbox',fixed:'left'},
+					{
+						field: 'id',
+						title: '序号',
+						align: 'center',
+						width: 80
+					}, {
+						field: 'meeting_date',
+						title: '会议日期',
+						align: 'center',
+						width: 100
+					},{
+						field: 'title',
+						title: '会议主题',
+						minWidth:240
+					},{
+						field: 'did_name',
+						title: '主办部门',
+						align: 'center',
+						width: 90
+					},{
+						field: 'anchor',
+						title: '主持人',
+						align: 'center',
+						width: 90
+					},{
+						field: 'recorder_name',
+						title: '记录人',
+						align: 'center',
+						width: 90
+					},{
+						field: 'right',
+						title: '操作',
+						width: 124,
+						align: 'center',
+						templet: function(d){
+							var btn='<div class="layui-btn-group"><span class="layui-btn layui-btn-xs layui-bg-blue" lay-event="view">查看</span><span class="layui-btn layui-btn-xs" lay-event="edit">编辑</span><span class="layui-btn layui-btn-xs layui-bg-red" lay-event="del">删除</span></div>';
+							return btn;
+						}
+					}
+				]
+			]
+		});
+
+		//监听行工具事件
+		table.on('tool(test)', function(obj) {
+			var data = obj.data;
+			if (obj.event === 'view') {
+				tool.side("/adm/meeting/records_view?id="+data.id);
+				return;
+			}
+			if (obj.event === 'edit') {
+				tool.side("/adm/meeting/records_add?id="+data.id);
+				return;
+			}
+			if (obj.event === 'del') {
+				layer.confirm('确定删除该会议纪要吗?', {
+					icon: 3,
+					title: '提示'
+				}, function(index) {
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							obj.del();
+						}
+					}
+					tool.delete("/adm/meeting/records_del", {id: data.id}, callback);
+					layer.close(index);
+				});
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 106 - 0
app/adm/view/meeting/records_add.html

@@ -0,0 +1,106 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-4">
+	<h3 class="pb-3">新增会议纪要</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">会议时间<font>*</font></td>
+			<td><input type="text" name="meeting_date" lay-verify="required" readonly lay-reqText="请选择会议时间" placeholder="请选择会议时间" class="layui-input tool-time" data-type="datetime" data-format ="yyyy-MM-dd HH:mm"></td>
+			<td class="layui-td-gray">主持人<font>*</font></td>
+			<td>
+				<input type="text" name="anchor" lay-verify="required" readonly lay-reqText="请选择主持人" placeholder="请选择主持人" class="layui-input picker-admin">
+				<input type="hidden" name="anchor_id">
+			</td>
+			<td class="layui-td-gray">记录人<font>*</font></td>
+			<td>
+				<input type="text" name="recorder" lay-verify="required" readonly lay-reqText="请选择记录人" placeholder="请选择记录人" class="layui-input picker-admin">
+				<input type="hidden" name="recorder_id">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">会 议 室<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="room_name" autocomplete="off" readonly placeholder="请选择" lay-verify="required" readonly lay-reqText="请选择会议室" class="layui-input picker-oa" data-types="room">
+				<input type="hidden" name="room_id">
+			</td>
+			<td class="layui-td-gray">主办部门<font>*</font></td>
+			<td>
+				<input type="text" name="did_name" autocomplete="off" readonly placeholder="请选择" lay-verify="required" readonly lay-reqText="请选择主办部门" class="layui-input picker-oa" data-types="department">
+				<input type="hidden" name="did">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">参会人员<font>*</font></td>
+			<td colspan="5">
+				<input type="text" name="join" lay-verify="required" readonly lay-reqText="请选择参会人员" placeholder="请选择参会人员" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="join_uids">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">会议主题<font>*</font></td>
+			<td colspan="5"><input type="text" name="title" lay-verify="required" lay-reqText="请输入会议主题" placeholder="请输入会议主题" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">会议内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入内容" class="layui-textarea" lay-verify="required" lay-reqText="请输入会议内容"></textarea>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2" style="vertical-align:top;">下一步<br>工作计划<font>*</font></td>
+			<td colspan="5">
+				<textarea name="plans" placeholder="请输入内容" class="layui-textarea" lay-verify="required" lay-reqText="请输入下一步工作计划"></textarea>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">参会人员签字<font>*</font></td>
+			<td colspan="5">
+				<input type="text" name="sign" lay-verify="required" readonly lay-reqText="请选择" placeholder="请选择" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="sign_uids">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">共享给谁<font>*</font></td>
+			<td colspan="5">
+				<input type="text" name="share" lay-verify="required" readonly lay-reqText="请选择" placeholder="请选择" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="share_uids">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">备注信息</td>
+			<td colspan="5">
+				<textarea name="remarks" placeholder="请输入内容" class="layui-textarea"></textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="py-3">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+	</div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool;		
+		//监听提交
+		form.on('submit(webform)', function (data) {
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/meeting/records_add", data.field, callback,clickbtn);
+			return false;
+		});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 107 - 0
app/adm/view/meeting/records_edit.html

@@ -0,0 +1,107 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-4">
+	<h3 class="pb-3">新增会议纪要</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">会议时间<font>*</font></td>
+			<td><input type="text" name="meeting_date" value="{$detail.meeting_date|date='Y-m-d H:i:s'}" lay-verify="required" readonly lay-reqText="请选择会议时间" placeholder="请选择会议时间" class="layui-input tool-time" data-type="datetime" data-format ="yyyy-MM-dd HH:mm"></td>
+			<td class="layui-td-gray">主持人<font>*</font></td>
+			<td>
+				<input type="text" name="anchor" value="{$detail.anchor_name}" lay-verify="required" readonly lay-reqText="请选择主持人" placeholder="请选择主持人" class="layui-input picker-admin">
+				<input type="hidden" name="anchor_id" value="{$detail.anchor_id}">
+			</td>
+			<td class="layui-td-gray">记录人<font>*</font></td>
+			<td>
+				<input type="text" name="recorder" value="{$detail.recorder_name}" lay-verify="required" readonly lay-reqText="请选择记录人" placeholder="请选择记录人" class="layui-input picker-admin">
+				<input type="hidden" name="recorder_id" value="{$detail.recorder_id}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">会 议 室<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="room_name" value="{$detail.room}" autocomplete="off" readonly placeholder="请选择" lay-verify="required" readonly lay-reqText="请选择会议室" class="layui-input picker-oa" data-types="room">
+				<input type="hidden" name="room_id" value="{$detail.room_id}">
+			</td>
+			<td class="layui-td-gray">主办部门<font>*</font></td>
+			<td>
+				<input type="text" name="did_name" value="{$detail.did_name|default=''}" autocomplete="off" readonly placeholder="请选择"  lay-verify="required" readonly lay-reqText="请选择主办部门" class="layui-input picker-oa" data-types="department">
+				<input type="hidden" name="did" value="{$detail.did}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">参会人员<font>*</font></td>
+			<td colspan="5">
+				<input type="text" name="join" value="{$detail.join_names}" lay-verify="required" readonly lay-reqText="请选择参会人员" placeholder="请选择参会人员" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="join_uids" value="{$detail.join_uids}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">会议主题<font>*</font></td>
+			<td colspan="5"><input type="text" name="title" value="{$detail.title}" lay-verify="required" lay-reqText="请输入会议主题" placeholder="请输入会议主题" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">会议内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入内容" class="layui-textarea" lay-verify="required" lay-reqText="请输入会议内容">{$detail.content}</textarea>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2" style="vertical-align:top;">下一步<br>工作计划<font>*</font></td>
+			<td colspan="5">
+				<textarea name="plans" placeholder="请输入内容" class="layui-textarea" lay-verify="required" lay-reqText="请输入下一步工作计划">{$detail.plans}</textarea>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">参会人员签字<font>*</font></td>
+			<td colspan="5">
+				<input type="text" name="sign" value="{$detail.sign_names}" lay-verify="required" readonly lay-reqText="请选择" placeholder="请选择" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="sign_uids" value="{$detail.sign_uids}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">共享给谁<font>*</font></td>
+			<td colspan="5">
+				<input type="text" name="share" value="{$detail.share_names}" lay-verify="required" readonly lay-reqText="请选择" placeholder="请选择" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="share_uids" value="{$detail.share_uids}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">备注信息</td>
+			<td colspan="5">
+				<textarea name="remarks" placeholder="请输入内容" class="layui-textarea">{$detail.remarks|default=''}</textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="py-3">
+		<input type="hidden" name="id" value="{$detail.id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+	</div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool;		
+		//监听提交
+		form.on('submit(webform)', function (data) {
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/meeting/records_add", data.field, callback,clickbtn);
+			return false;
+		});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 67 - 0
app/adm/view/meeting/records_view.html

@@ -0,0 +1,67 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">会议纪要</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">会议时间</td>
+			<td>{$detail.meeting_date|date='Y-m-d H:i'}</td>
+			<td class="layui-td-gray">主持人</td>
+			<td>{$detail.anchor_name}</td>
+			<td class="layui-td-gray">记录人</td>
+			<td>{$detail.recorder_name}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">会 议 室</td>
+			<td colspan="3">{$detail.room}</td>
+			<td class="layui-td-gray">主办部门</td>
+			<td>{$detail.did_name|default=""}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">参会人员</td>
+			<td colspan="5">{$detail.join_names}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">会议主题</td>
+			<td colspan="5">{$detail.title}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">会议内容</td>
+			<td colspan="5">{$detail.content}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2" style="vertical-align:top;">下一步<br>工作计划</td>
+			<td colspan="5">{$detail.plans}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">参会人员签字</td>
+			<td colspan="5">{$detail.sign_names}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">共享给谁</td>
+			<td colspan="5">{$detail.share_names}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">备注信息</td>
+			<td colspan="5">{$detail.remarks|default=''}</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		<a href="/api/export/pdf?types=meeting&id={$detail.id}" class="layui-btn" target="_blank"><i class="layui-icon layui-icon-print"></i>导出打印</a>
+	</div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool;		
+
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 114 - 0
app/adm/view/meeting/room.html

@@ -0,0 +1,114 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="输入关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="roomTable" lay-filter="roomTable"></table>
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm tool-add" data-href="/adm/meeting/room_add">+ 会议室</button>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+<!-- 脚本 -->
+{block name="script"}
+	<script>
+	const moduleInit = ['tool','tablePlus','laydatePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool,form = layui.form,laydatePlus = layui.laydatePlus;	
+		var diff_time = new laydatePlus({'target':'diff_time'});		
+		
+		layui.pageTable = table.render({
+			elem: '#roomTable'
+			,toolbar: '#toolbarDemo'
+			,title:'会议室列表'
+			,url: "/adm/meeting/room"
+			,is_excel: true
+			,page: true
+			,cellMinWidth: 60
+			,height: 'full-114'
+			,cols: [[
+					{field:'id',width:80, title: 'ID号', align:'center'}
+					,{field:'title',title: '会议室名称',width:150}
+					,{field:'num',title: '可容纳人数',width:100, align:'center'}
+					,{field:'keep_name',title: '管理员',width:80, align:'center'}
+					,{field:'address',title: '会议室地址',width:300}
+					,{field:'device',title: '会议室设备',minWidth:240,}
+					,{field:'status', title: '状态',width:60,align:'center',templet: function(d){
+						var html1='<span class="green">正常</span>';
+						var html2='<span class="yellow">禁用</span>';
+						if(d.status==1){
+							return html1;
+						}
+						else{
+							return html2;
+						}
+					}}
+					,{width:180,title: '操作', align:'center',templet: function(d){
+						var html='';
+						var btn='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">查看</a>';
+						var btn1='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>';
+						var btn2='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
+						var btn3='<a class="layui-btn layui-btn-xs layui-bg-purple" lay-event="open">启用</a>';
+						var btn4='<a class="layui-btn layui-btn-xs layui-bg-blue" lay-event="use">使用情况</a>';
+						if(d.status==1){
+							html = '<div class="layui-btn-group">'+btn+btn1+btn2+btn4+'</div>';
+						}
+						else{
+							html = '<div class="layui-btn-group">'+btn+btn1+btn3+btn4+'</div>';
+						}
+						return html;
+					}}
+				]]
+		});
+		
+		table.on('tool(roomTable)',function (obj) {
+			var that = this;
+			if(obj.event === 'edit'){					
+				tool.side("/adm/meeting/room_add?id="+obj.data.id);
+			}
+			if(obj.event === 'view'){					
+				tool.side("/adm/meeting/room_view?id="+obj.data.id);
+			}
+			if(obj.event === 'use'){					
+				tool.side("/adm/meeting/room_use?id="+obj.data.id);
+			}
+			if(obj.event === 'disable'){
+				layer.confirm('确定要禁用该会议室吗?', {icon: 3, title:'提示'}, function(index){
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							layui.pageTable.reload();
+						}
+					}
+					tool.post("/adm/meeting/room_check", { id: obj.data.id,status: 0,title: obj.data.title}, callback);
+					layer.close(index);
+				});
+			}
+			if(obj.event === 'open'){
+				layer.confirm('确定要启用该会议室吗?', {icon: 3, title:'提示'}, function(index){
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							layui.pageTable.reload();
+						}
+					}
+					tool.post("/adm/meeting/room_check", { id: obj.data.id,status: 1,title: obj.data.title}, callback);
+					layer.close(index);
+				});
+			}
+		});
+	}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 71 - 0
app/adm/view/meeting/room_add.html

@@ -0,0 +1,71 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">新增会议室</h3>
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray-2">会议室名称<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="title" autocomplete="off" lay-verify="required" lay-reqText="请完善会议室名称" placeholder="请完善会议室名称" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">地址(楼层)<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="address" autocomplete="off" lay-verify="required" lay-reqText="请完善会议室地址(楼层)" placeholder="请输入会议室地址(楼层)" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">管 理 员<font>*</font></td>
+			<td>
+				<input type="text" name="keep_name" autocomplete="off" readonly lay-verify="required" lay-reqText="请选择会议室管理员" placeholder="请选择" class="layui-input picker-admin">
+				<input type="hidden" name="keep_uid">
+			</td>
+			<td class="layui-td-gray-2">可容纳人数<font>*</font></td>
+			<td><input type="text" name="num" autocomplete="off" placeholder="请输入可容纳人数" lay-verify="required|number" lay-reqText="请输入可容纳人数" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">内置设备<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="device" autocomplete="off" lay-verify="required" lay-reqText="请完善会议室内置设备" placeholder="请输入会议室内置设备" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">相关描述</td>
+			<td colspan="3">
+				<textarea name="remark" placeholder="请输入会议室相关描述" class="layui-textarea"></textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-2">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool;
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000);				
+			}
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/meeting/room_add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 72 - 0
app/adm/view/meeting/room_edit.html

@@ -0,0 +1,72 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">编辑会议室</h3>
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray-2">会议室名称<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="title" value="{$detail.title}" autocomplete="off" lay-verify="required" lay-reqText="请完善会议室名称" placeholder="请完善会议室名称" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">地址(楼层)<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="address" value="{$detail.address}" autocomplete="off" lay-verify="required" lay-reqText="请完善会议室地址(楼层)" placeholder="请输入会议室地址(楼层)" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">管 理 员<font>*</font></td>
+			<td>
+				<input type="text" name="keep_name" value="{$detail.keep_name}" autocomplete="off" readonly lay-verify="required" lay-reqText="请选择会议室管理员" placeholder="请选择" class="layui-input picker-admin">
+				<input type="hidden" name="keep_uid" value="{$detail.keep_uid}">
+			</td>
+			<td class="layui-td-gray-2">可容纳人数<font>*</font></td>
+			<td><input type="text" name="num" autocomplete="off" value="{$detail.num}" placeholder="请输入费用金额" lay-verify="required|number" lay-reqText="请输入费用金额" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">内置设备<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="device" value="{$detail.device}" autocomplete="off" lay-verify="required" lay-reqText="请完善会议室内置设备" placeholder="请输入会议室内置设备" class="layui-input">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">相关描述</td>
+			<td colspan="3">
+				<textarea name="remark" placeholder="请输入会议室相关描述" class="layui-textarea">{$detail.remark|default=''}</textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-2">
+		<input type="hidden" name="id" value="{$detail.id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool;
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000);				
+			}
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/meeting/room_add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 157 - 0
app/adm/view/meeting/room_use.html

@@ -0,0 +1,157 @@
+{extend name="../../base/view/common/base" /}
+{block name="style"}
+<link rel="stylesheet" href="{__GOUGU__}/third_party/fullcalendar/main.min.css"/>
+<style>
+#calendar {width: 100%;margin: 0 auto; background-color:#fff;
+-moz-user-select: none; /*火狐*/
+-webkit-user-select: none; /*webkit浏览器*/
+}
+.fc .fc-toolbar.fc-header-toolbar{margin-bottom:0;border:1px solid #eeeeee; border-bottom:none;padding:15px 12px;}
+.fc-col-header{background-color:#fafafa;}
+.fc .fc-button-primary {color: #fff; background-color: #1E9FFF; border-color: #1E9FFF;}
+.fc .fc-button-primary:not(:disabled).fc-button-active, .fc .fc-button-primary:not(:disabled):active { color: #fff; background-color: #FBBC05; border-color: #FBBC05;}
+.fc .fc-button-primary:focus, .fc .fc-button-primary:not(:disabled).fc-button-active:focus, .fc .fc-button-primary:not(:disabled):active:focus {box-shadow: 0 0 0 0;}
+.fc .fc-button-primary:hover{color:#fff; background-color:#52B5FF; border-color:#52B5FF;}
+.fc-daygrid-event-harness{cursor:pointer;}
+.fc .fc-daygrid-week-number{font-size:12px;}
+.fc-daygrid-block-event .fc-event-time{font-weight:800}
+.fc-h-event .fc-event-main{color:#111111}
+.fc-theme-standard .fc-scrollgrid,.fc-theme-standard td, .fc-theme-standard th{border-color:#eee;}
+.fc-v-event .fc-event-main-frame{color:#333}
+/*今天背景色和字体颜色 */
+.fc .fc-daygrid-day.fc-day-today .fc-event-title,.fc .fc-daygrid-day.fc-day-today .fc-event-time,.fc .fc-daygrid-day.fc-day-today .fc-daygrid-day-number{font-weight:800;color:#FF5722;}
+.calendar-select{width:100px; height:40px; position:absolute; top:31px; right:262px; z-index:100;}
+.calendar-select .layui-input{height: 36px; line-height: 1.2;}
+.layui-tags-span {padding: 3px 6px;font-size: 12px; background-color:#fff; border-radius: 3px; margin:2px 0; margin-right: 5px; border: 1px solid #e6e6e6; display: inline-block;}
+.layui-layer-content .layui-table-view .layui-table td,.layui-layer-content .layui-table-view .layui-table th{padding:1px 0;}
+.layui-unselect dl {max-height:188px;}
+</style>
+{/block}
+<!-- 主体 -->
+{block name="body"}
+<script src="{__GOUGU__}/third_party/fullcalendar/main.min.js"></script>
+<div class="p-page">
+	<div id="calendar"></div>
+</div>
+<!-- /主体 -->
+{/block}
+{block name="copyright"}{/block}
+<!-- 脚本 -->
+{block name="script"}
+<script type="text/javascript">
+	var id={$detail.id};	
+	function addZero(num){
+		if(num<10){
+			num='0'+num;
+		}
+		return num;
+	}
+	const moduleInit = ['tool','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool, oaPicker = layui.oaPicker,laydate = layui.laydate,dropdown = layui.dropdown;				
+		//日历
+		var calendarEl = document.getElementById('calendar');
+		var calendar = new FullCalendar.Calendar(calendarEl, {
+			views: {
+				dayGrid: {
+					viewDidMount:function(arg){
+						calendar.setOption('height', window.innerHeight-30);
+					}
+				},
+				timeGrid: {
+					viewDidMount:function(arg){
+						calendar.setOption('height', 'auto');
+					}
+				},
+				week: {
+					viewDidMount:function(arg){
+						calendar.setOption('height', 'auto');
+					}
+				},
+				day: {
+					viewDidMount:function(arg){
+						calendar.setOption('height', 'auto');
+					}
+				}
+			},
+			//initialDate: '2020-09-12',//默认显示日期
+			initialView: 'dayGridMonth',//默认显示月视图
+			headerToolbar: {
+				left: 'prev,next',//prev,next today add
+				center: 'title',
+				right: 'dayGridMonth,timeGridWeek,listWeek' //clear dayGridMonth,timeGridWeek,timeGridDay,listWeek
+			},
+			height: 'auto',//自动高度
+			navLinks: true, // can click day/week names to navigate views
+			editable: true,//确定是否可以拖拉调整日历事件的时间。
+			eventResize:function(ev) {
+				var arg = ev.event
+				console.log(arg);
+			},
+			eventDrop:function(ev) {
+				var arg = ev.event
+				console.log(arg);
+			},
+			selectable: true,//拖拉选择日期
+			selectMirror: true,//是否在用户拖动时绘制"占位符"事件。
+			select: function(arg) {
+				console.log(arg);	
+			},
+			nowIndicator: true,
+			firstDay: 1,
+			weekNumbers: true,// 是否开启周数
+			displayEventEnd: false, //所有视图显示结束时间
+			eventTimeFormat: { // 事件的时间格式,like '14:30:00'
+				hour: '2-digit',
+				minute: '2-digit',
+				//second: '2-digit',
+				meridiem: false,
+				hour12: false //设置时间为24小时
+			},
+			slotLabelFormat: { // 列表视图左边的时间格式,like '14:30:00'
+				hour: '2-digit',
+				minute: '2-digit',
+				//second: '2-digit',
+				meridiem: false,
+				hour12: false //设置时间为24小时
+			},
+			locale: 'zh-cn',//语言
+			buttonText: {
+				//按钮文本
+				today: '今天',
+				month: '月',
+				week: '周',
+				day: '日',
+				list: '预定列表',
+			},
+			weekText: '周',
+			allDayText: '全天',
+			moreLinkText: function(n) {
+				return '另外 ' + n + ' 个'
+			},
+			noEventsText: '没有预定记录',
+			events: function(fetchInfo, successCallback, failureCallback ){
+				$.ajax({
+					type:"POST",
+					url: "/adm/meeting/room_use",
+					dataType:"json",
+					data:{start:fetchInfo.startStr,end:fetchInfo.endStr,id:id},
+					success:function(result){
+						//console.info(result);
+						successCallback(result);
+					},
+					error:function(){
+						failureCallback();
+					}
+				})
+			},
+			eventClick: function(info) {
+				//console.log(info.event);
+				tool.side('/adm/meeting/view?id='+info.event.id);
+			}
+		});
+		calendar.render();
+	}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 44 - 0
app/adm/view/meeting/room_view.html

@@ -0,0 +1,44 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">会议室信息</h3>
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray-2">会议室名称</td>
+			<td colspan="3">{$detail.title}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">地址(楼层)</td>
+			<td colspan="3">{$detail.address}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">管 理 员</td>
+			<td>{$detail.keep_name}</td>
+			<td class="layui-td-gray-2">可容纳人数</td>
+			<td>{$detail.num}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">内置设备</td>
+			<td colspan="3">{$detail.device}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">相关描述</td>
+			<td colspan="3">{$detail.remark|default=''}</td>
+		</tr>
+	</table>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool;
+
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 52 - 0
app/adm/view/meeting/view.html

@@ -0,0 +1,52 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+	<h3 class="pb-2">会议室预定</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray-2">会议主题</td>
+			<td colspan="3">{$detail.title|default=''}</td>
+			<td class="layui-td-gray">会议地点</td>
+			<td>{$detail.room|default=''}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">开始时间</td>
+			<td>{$detail.start_time|default=''}</td>
+			<td class="layui-td-gray">结束时间</td>
+			<td>{$detail.end_time|default=''}</td>
+			<td class="layui-td-gray">会议人数</td>
+			<td>{$detail.num|default=''}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">会议需求</td>
+			<td colspan="5">
+				{volist name="$detail.requirements_array" id="v"}
+				{eq name="$v.checked" value="1" }<span class="layui-badge layui-bg-blue">{$v.title}</span>{/eq}
+				{/volist}
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">其他要求</td>
+			<td colspan="5">{$detail.remark|default=''}</td>
+		</tr>
+	</table>
+	<div id="checkBox" data-status="{$detail.check_status}" data-id="{$detail.id}" data-checkflowid="{$detail.check_flow_id}" class="pt-3"></div>
+</div>
+{/block}
+<!-- /主体 -->
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	var moduleInit = ['tool','oaCheck'];
+
+	function gouguInit() {
+		var tool = layui.tool,oaCheck = layui.oaCheck;
+		//审批相关
+        oaCheck.init({
+            check_name:'meeting_order',
+        });
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 94 - 0
app/adm/view/news/add.html

@@ -0,0 +1,94 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-4">
+	{eq name="$id" value="0"}
+	<h3 class="pb-3">新增公司新闻</h3>
+	{else/}
+	<h3 class="pb-3">编辑公司新闻</h3>
+	{/eq}
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">新闻标题<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="title" lay-verify="required" lay-reqText="请输入新闻标题" placeholder="请输入新闻标题" class="layui-input" value="{$detail.title|default=''}">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">关联链接</td>
+			<td><input type="text" name="src" placeholder="请输入链接" class="layui-input" value="{$detail.src|default=''}"></td>
+			<td class="layui-td-gray">排序</td>
+			<td><input type="text" name="sort" placeholder="请输入排序,数字" class="layui-input" value="{$detail.sort|default=0}"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids|default=''}">
+					{notempty name="$detail.file_ids"}
+					{volist name="$detail.file_array" id="vo"}
+						<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo)}</div>
+					{/volist}
+					{/notempty}
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">新闻内容<font>*</font></td>
+			<td colspan="3">
+				<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container" style="border:0;padding:0">{$detail.content|default=''}</textarea>
+			</td>
+		</tr>
+	</table>
+
+	<div class="pt-4">
+		<input type="hidden" name="id" value="{$id}" />
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+	</div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','uploadPlus','tinymce'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus;
+		//相关附件上传
+		var attachment = new uploadPlus();
+		//编辑器初始化
+		var editor = layui.tinymce;
+		var edit = editor.render({
+			selector: "#container",
+			images_upload_url: '/api/index/upload/sourse/tinymce',//图片上传接口
+			height: 500
+		});
+		
+		//监听提交
+		form.on('submit(webform)', function (data) {
+			data.field.content = tinyMCE.editors['container'].getContent();
+			if (data.field.content == '') {
+				layer.msg('请先完善新闻内容');
+				return false;
+			}
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/news/add", data.field, callback,clickbtn);
+			return false;
+		});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 86 - 0
app/adm/view/news/datalist.html

@@ -0,0 +1,86 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="table_news" lay-filter="table_news"></table>
+</div>
+
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/adm/news/add">+ 添加公司新闻</button>
+  </div>
+</script>
+
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','tablePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool;
+		
+		layui.pageTable = table.render({
+			elem: "#table_news"
+			, toolbar: "#toolbarDemo"
+			,url: "/adm/news/datalist"
+			,page: true
+			,limit: 20
+			,cellMinWidth: 80
+			,height: 'full-114'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'title',title: '名称'}
+				,{field:'admin_name',title: '创建人',width:90,align:'center'}
+				,{field:'create_time', title: '创建时间',width:150,align:'center'}
+				,{width:120,fixed:'right',title: '操作', align:'center',ignoreExport:true,templet: function(d){
+					var html='';
+					var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>';
+					var btn2='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>';
+					var btn3='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>';
+					html = '<div class="layui-btn-group">'+btn1+btn2+btn3+'</div>';
+					return html;
+				}}
+			]]
+		});
+			
+		table.on('tool(table_news)',function (obj) {
+			var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
+			var data = obj.data;
+			if (obj.event === 'view') {
+				tool.side("/adm/news/view?id="+data.id);
+				return;
+			}
+			if (obj.event === 'edit') {
+				tool.side("/adm/news/add?id="+data.id);
+				return;
+			}
+			if (obj.event === 'del') {
+				layer.confirm('确定要删除该内容吗?', { icon: 3, title: '提示' }, function (index) {
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							obj.del();
+						}
+					}
+					tool.delete("/adm/news/del", { id: data.id }, callback);
+					layer.close(index);
+				});
+				return;
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 63 - 0
app/adm/view/news/view.html

@@ -0,0 +1,63 @@
+{extend name="../../base/view/common/base" /}
+{block name="style"}
+<link rel="stylesheet" href="{__GOUGU__}/third_party/prism/prism.css"/>
+<style>
+.text-detial-ops{line-height: 30px; color:#999; font-size: 12px; padding: 12px 0;}
+.text-detial-ops span{margin-right: 20px;}
+.text-detial-ops a{margin-right:10px;}
+.text-detial-content{padding: 8px 0; color:#333; word-break: break-all; border-top:1px solid #e8e8e8;font-size: 16px!important; line-height: 1.72!important;}
+.text-detial-content p{padding: 8px 0;}
+.text-detial-content img{max-width:98%!important; margin:0 auto; display:block; border: 1px solid #e6e6e6; -webkit-box-shadow: 0 2px 6px rgba(26,26,26,.08); box-shadow: 0 2px 6px rgba(26,26,26,.08); border-radius: 4px;}
+.text-detial-content h1,.text-detial-content h2,.text-detial-content h3,.text-detial-content h4,.text-detial-content h5{margin-top:10px;}
+.text-detial-content a{color:#186AF2; font-style:italic;}
+.text-detial-content a:hover{text-decoration:underline;}
+
+.text-detial-content p code,.blog-detial-content pre{margin:0 3px;font-size: 14px; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; background: #f6f6f6; padding: 10px; border-radius: 2px;}
+.text-detial-content p code{border: 1px solid #eee;padding: 2px 4px;}
+.text-detial-content table {border-collapse: collapse; border-spacing: 0; display: block; width: 100%; overflow: auto;  word-break: normal;word-break: keep-all; margin-top: 0;margin-bottom: 16px;}
+.text-detial-content table tr {background-color: #fff;border-top: 1px solid #ccc;}
+.text-detial-content table tr:nth-child(2n) {background-color: #f8f8f8;}
+.text-detial-content table td, .blog-detial-content table th { padding: 6px 12px;border: 1px solid #ddd; font-size:14px; }
+.text-detial-content table th {font-weight: 800;}
+.text-detial-content li {list-style: initial;margin-left: 20px;}
+:not(pre)>code[class*=language-], pre[class*=language-]{background:#fff!important;border:1px solid #e8e8e8!important; border-radius:3px;}
+.upload-file{padding:12px; background-color:#fff; border:1px solid #eee; margin-bottom:12px;}
+.upload-file h3{margin-bottom:12px;}
+</style>
+{/block}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-4">
+	<h1>{$detail.title}</h1>
+	<div class="text-detial-ops">
+		<span>{$detail.admin_name}发表于:{$detail.create_time | date='Y-m-d H:i:s'}</span>
+	</div>
+	<div class="text-detial-content">
+	{$detail.content|raw}
+	</div>
+	{notempty name="$detail.src"}
+	<div class="py-3" style="font-size:16px;">
+		关联链接:<a class="blue" href="{$detail.src}" target="_blank">{$detail.src}</a>
+	</div>
+	{/notempty}
+	{notempty name="$detail.file_ids"}
+	<div class="upload-file layui-row">
+		<h3>相关附件</h3>
+		{volist name="$detail.file_array" id="vo"}
+			<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo,'view')}</div>
+		{/volist}
+	</div>
+	{/notempty}	
+</div>
+{/block}
+<!-- 脚本 -->
+{block name="script"}
+<script src="{__GOUGU__}/third_party/prism/prism.js"></script>
+<script>
+	const moduleInit = ['tool'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool;	
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 124 - 0
app/adm/view/note/add.html

@@ -0,0 +1,124 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	{eq name="$id" value="0"}
+	<h3 class="pb-2">新增公告</h3>
+	{else/}
+	<h3 class="pb-2">编辑公告</h3>
+	{/eq}
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">公告标题<font>*</font></td>
+			<td>
+				<input type="text" name="title" lay-verify="required" lay-reqText="请输入公告标题" placeholder="请输入公告标题" class="layui-input" value="{$detail.title|default=''}">
+			</td>
+			<td class="layui-td-gray">公告分类<font>*</font></td>
+			<td>
+				<select name="cate_id" lay-verify="required" lay-reqText="请选择分类">
+					<option value="">请选择分类</option>
+					{if condition="$id eq 0"}
+						{volist name=":get_base_data('note_cate')" id="v"}
+						<option value="{$v.id}">{$v.title}</option>
+						{/volist}
+					{else/}
+						{volist name=":get_base_data('note_cate')" id="v"}
+						<option value="{$v.id}" {eq name="$detail.cate_id" value="$v.id" }selected{/eq}>{$v.title}</option>
+						{/volist}
+					{/if}
+				</select>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">排序</td>
+			<td><input type="text" name="sort" placeholder="排序,数字越大越靠前" class="layui-input" value="{$detail.sort|default=0}"></td>
+			<td class="layui-td-gray">状态<font>*</font></td>
+			<td>
+				{if condition="$id eq 0"}
+				<input type="radio" name="status" value="1" title="正常" checked>
+				<input type="radio" name="status" value="0" title="禁用">
+				{else/}
+				<input type="radio" name="status" value="1" title="正常" {eq name="$detail.status" value="1" } checked{/eq}>
+				<input type="radio" name="status" value="0" title="禁用" {eq name="$detail.status" value="0" } checked{/eq}>
+				{/if}
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">关联链接</td>
+			<td colspan="3"><input type="text" name="src" placeholder="请输入链接" class="layui-input" value="{$detail.src|default=''}"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="3">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids|default=''}">
+					{notempty name="$detail.file_ids"}
+					{volist name="$detail.file_array" id="vo"}
+						<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo)}</div>
+					{/volist}
+					{/notempty}
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">公告内容<font>*</font></td>
+			<td colspan="3">
+				<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container{$detail.sourse|default=1}">{$detail.content|default=''}</textarea>
+			</td>
+		</tr>
+	</table>
+
+	<div class="pt-3">
+		<input type="hidden" name="id" value="{$id}" />
+		<input type="hidden" name="sourse" value="{$detail.sourse|default=1}" />
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+	</div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','uploadPlus','tinymce'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,laydate = layui.laydate,uploadPlus = layui.uploadPlus;
+		//相关附件上传
+		var attachment = new uploadPlus();
+		//编辑器初始化
+		var editor = layui.tinymce;
+		var edit = editor.render({
+			selector: "#container1",
+			images_upload_url: '/api/index/upload/sourse/tinymce',//图片上传接口
+			height: 500
+		});
+		
+		//监听提交
+		form.on('submit(webform)', function (data) {
+			if (data.field.sourse == 1) {
+				data.field.content = tinyMCE.editors['container1'].getContent();
+			}
+			if (data.field.content == '') {
+				layer.msg('请先完善公告内容');
+				return false;
+			}
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/note/add", data.field, callback,clickbtn);
+			return false;
+		});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 103 - 0
app/adm/view/note/datalist.html

@@ -0,0 +1,103 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="table_note" lay-filter="table_note"></table>
+</div>
+
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/adm/note/add">+ 添加公告通知</button>
+  </div>
+</script>
+
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','tablePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool;
+		
+		layui.pageTable = table.render({
+			elem: "#table_note"
+			, toolbar: "#toolbarDemo"
+			,url: "/adm/note/datalist"
+			,page: true
+			,limit: 20
+			,cellMinWidth: 80
+			,height: 'full-114'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'title',title: '公告主题'}
+				,{field:'cate',title: '所属分类',width:120,align:'center'}
+				,{field:'course', title: '状态',width:80,align:'center',templet: function(d){
+					if(d.status==1){
+						return '<span class="green">正常</span>';
+					}
+					else{
+						return '<span class="red">禁用</span>';
+					}
+				}}
+				,{field:'admin_name',title: '创建人',width:90,align:'center'}
+				,{field:'create_time', title: '创建时间',width:150,align:'center'}
+				,{field:'sourse', title: '来源',width:120,align:'center',templet: function(d){
+					if(d.sourse==1){
+						return '发布于PC端';
+					}
+					else{
+						return '发布于手机端';
+					}
+				}}
+				,{width:120,fixed:'right',title: '操作', align:'center',ignoreExport:true,templet: function(d){
+					var html='';
+					var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>';
+					var btn2='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>';
+					var btn3='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>';
+					html = '<div class="layui-btn-group">'+btn1+btn2+btn3+'</div>';
+					return html;
+				}}
+			]]
+		});
+			
+		table.on('tool(table_note)',function (obj) {
+			var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
+			var data = obj.data;
+			if (obj.event === 'view') {
+				tool.side("/adm/note/view?id="+data.id);
+				return;
+			}
+			if (obj.event === 'edit') {
+				tool.side("/adm/note/add?id="+data.id);
+				return;
+			}
+			if (obj.event === 'del') {
+				layer.confirm('确定要删除该内容吗?', { icon: 3, title: '提示' }, function (index) {
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							obj.del();
+						}
+					}
+					tool.delete("/adm/note/del", { id: data.id }, callback);
+					layer.close(index);
+				});
+				return;
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 67 - 0
app/adm/view/note/view.html

@@ -0,0 +1,67 @@
+{extend name="../../base/view/common/base" /}
+{block name="style"}
+<link rel="stylesheet" href="{__GOUGU__}/third_party/prism/prism.css"/>
+<style>
+.text-detial-ops{line-height: 30px; color:#999; font-size: 12px; padding: 12px 0;}
+.text-detial-ops span{margin-right: 20px;}
+.text-detial-ops a{margin-right:10px;}
+.text-detial-content{padding: 8px 0; color:#333; word-break: break-all; border-top:1px solid #e8e8e8;font-size: 16px!important; line-height: 1.72!important;}
+.text-detial-content p{padding: 8px 0;}
+.text-detial-content img{max-width:98%!important; margin:0 auto; display:block; border: 1px solid #e6e6e6; -webkit-box-shadow: 0 2px 6px rgba(26,26,26,.08); box-shadow: 0 2px 6px rgba(26,26,26,.08); border-radius: 4px;}
+.text-detial-content h1,.text-detial-content h2,.text-detial-content h3,.text-detial-content h4,.text-detial-content h5{margin-top:10px;}
+.text-detial-content a{color:#186AF2; font-style:italic;}
+.text-detial-content a:hover{text-decoration:underline;}
+
+.text-detial-content p code,.blog-detial-content pre{margin:0 3px;font-size: 14px; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; background: #f6f6f6; padding: 10px; border-radius: 2px;}
+.text-detial-content p code{border: 1px solid #eee;padding: 2px 4px;}
+.text-detial-content table {border-collapse: collapse; border-spacing: 0; display: block; width: 100%; overflow: auto;  word-break: normal;word-break: keep-all; margin-top: 0;margin-bottom: 16px;}
+.text-detial-content table tr {background-color: #fff;border-top: 1px solid #ccc;}
+.text-detial-content table tr:nth-child(2n) {background-color: #f8f8f8;}
+.text-detial-content table td, .blog-detial-content table th { padding: 6px 12px;border: 1px solid #ddd; font-size:14px; }
+.text-detial-content table th {font-weight: 800;}
+.text-detial-content li {list-style: initial;margin-left: 20px;}
+:not(pre)>code[class*=language-], pre[class*=language-]{background:#fff!important;border:1px solid #e8e8e8!important; border-radius:3px;}
+.upload-file{padding:12px; background-color:#fff; border:1px solid #eee; margin-bottom:12px;}
+.upload-file h3{margin-bottom:12px;}
+</style>
+{/block}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-5">
+	<h1>{$detail.title}</h1>
+	<div class="text-detial-ops">
+		<span>{$detail.admin_name}发表于:{$detail.create_time | date='Y-m-d H:i:s'} {$detail.sourse==1?'PC端':'手机端'}</span><span>公告分类:{$detail.cate}</span>
+	</div>
+	<div class="text-detial-content">
+		{eq name="$detail.sourse" value="1"}
+		{$detail.content|raw}
+		{else/}
+		<pre style="font-family:inherit;white-space: pre-wrap;">{$detail.content}</pre>
+		{/eq}
+	</div>
+	{notempty name="$detail.src"}
+	<div class="py-3" style="font-size:16px;">
+		关联链接:<a class="blue" href="{$detail.src}" target="_blank">{$detail.src}</a>
+	</div>
+	{/notempty}
+	{notempty name="$detail.file_ids"}
+	<div class="upload-file layui-row">
+		<h3>相关附件</h3>
+		{volist name="$detail.file_array" id="vo"}
+			<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo,'view')}</div>
+		{/volist}
+	</div>
+	{/notempty}	
+</div>
+{/block}
+<!-- 脚本 -->
+{block name="script"}
+<script src="{__GOUGU__}/third_party/prism/prism.js"></script>
+<script>
+	const moduleInit = ['tool'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool;	
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 49 - 0
app/adm/view/notecate/add.html

@@ -0,0 +1,49 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-3">公告类别</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">公告类别名称<font>*</font></td>
+			<td>
+				<input type="text" name="title" lay-verify="required" autocomplete="off" placeholder="请输入公告类别名称" lay-reqText="请输入公告类别名称"class="layui-input" value="{$detail.title|default=''}">
+			</td>
+			<td class="layui-td-gray">排序</td>
+			<td>
+				<input type="text" name="sort" placeholder="请输入排序,数字" autocomplete="off" class="layui-input" value="{$detail.sort|default=''}">
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		<input type="hidden" name="id" value="{$detail.id|default=0}"/>
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+	</div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	var moduleInit = ['tool'];
+
+	function gouguInit() {
+		var form = layui.form, tool = layui.tool;
+		//监听提交
+		form.on('submit(webform)', function (data) {
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/notecate/add", data.field, callback,clickbtn);
+			return false;
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 124 - 0
app/adm/view/notecate/datalist.html

@@ -0,0 +1,124 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+
+<div class="p-page">
+	<table class="layui-hide" id="table_note_cate" lay-filter="table_note_cate"></table>
+</div>
+
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm add-new" type="button">+ 添加公告类别</button>
+  </div>
+</script>
+
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool'];
+	function gouguInit() {
+		var table = layui.table, tool = layui.tool;
+		
+		layui.pageTable = table.render({
+			elem: "#table_note_cate"
+			,toolbar: '#toolbarDemo'
+			,url: "/adm/notecate/datalist"
+			,page: false
+			,limit: 999
+			,cellMinWidth: 80
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'title',title: '类型名称'}
+				,{field:'status', title: '状态',width:80,align:'center',templet: function(d){
+					var html1='<span class="green">正常</span>';
+					var html2='<span class="yellow">禁用</span>';
+					if(d.status==1){
+						return html1;
+					}
+					else{
+						return html2;
+					}
+				}}
+				,{width:100,title: '操作', align:'center',ignoreExport:true,templet: function(d){
+					var html='';
+					var btn='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>';
+					var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
+					var btn2='<a class="layui-btn layui-btn-xs" lay-event="open">启用</a>';
+					if(d.status==1){
+						html = '<div class="layui-btn-group">'+btn+btn1+'</div>';
+					}
+					else{
+						html = '<div class="layui-btn-group">'+btn+btn2+'</div>';
+					}
+					return html;
+				}}
+			]]
+		});
+			
+		table.on('tool(table_note_cate)',function (obj) {
+			if(obj.event === 'edit'){					
+				add_cate(obj.data.id,obj.data.title);
+			}
+			if(obj.event === 'disable'){
+				layer.confirm('确定要禁用该记录吗?', {icon: 3, title:'提示'}, function(index){
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							layui.pageTable.reload();
+						}
+					}
+					tool.post("/adm/notecate/set", {id:obj.data.id,status: 0}, callback);
+					layer.close(index);
+				});
+			}
+			if(obj.event === 'open'){
+				layer.confirm('确定要启用该记录吗?', {icon: 3, title:'提示'}, function(index){
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							layui.pageTable.reload();
+						}
+					}
+					tool.post("/adm/notecate/set", {id:obj.data.id,status:1}, callback);
+					layer.close(index);
+				});
+			}
+		});
+		
+		$('body').on('click','.add-new',function(){
+			add_cate(0,'');	
+		});
+		
+		function add_cate(id,val){
+			var title = '新增类型';
+			if(id>0){
+				title = '编辑类型';
+			}
+			layer.prompt({
+				title: title,
+				value: val,
+				yes: function(index, layero) {
+					// 获取文本框输入的值
+					var value = layero.find(".layui-layer-input").val();
+					if (value) {
+						let callback = function (e) {
+							layer.msg(e.msg);
+							if (e.code == 0) {
+								layui.pageTable.reload();				
+							}
+						}
+						tool.post("/adm/notecate/add", {id: id,title: value}, callback);
+						layer.close(index);
+					} else {
+						layer.msg('请填写类型名称');
+					}
+				}
+			})
+		}
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 16 - 0
app/adm/view/notecate/view.html

@@ -0,0 +1,16 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+	<h3 class="pb-3">公告类别详情</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">公告类别名称</td>
+			<td>{$detail.title|default=''}"></td>
+			<td class="layui-td-gray">排序</td>
+			<td>{$detail.sort|default=0}</td>
+		</tr>
+	</table>
+</div>
+{/block}
+<!-- /主体 -->

+ 130 - 0
app/adm/view/official/add.html

@@ -0,0 +1,130 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">添加公文</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">公文名称<font>*</font></td>
+			<td colspan="3"><input type="text" name="title" autocomplete="off" placeholder="请输入公文名称" lay-verify="required" lay-reqText="请输入公文名称" class="layui-input"></td>
+			<td class="layui-td-gray">公文文号<font>*</font></td>
+			<td><input type="text" name="code" autocomplete="off" placeholder="请输入公文文号" lay-verify="required" lay-reqText="请输入公文文号" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">拟稿人<font>*</font></td>
+			<td>
+				<input type="text" name="draft_name" value='' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择拟稿人" class="layui-input picker-admin">
+				<input type="hidden" name="draft_uid" value=''>
+			</td>
+			<td class="layui-td-gray">拟稿部门<font>*</font></td>
+			<td>
+				<input type="text" name="draft_dame" value='' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择拟稿部门" class="layui-input picker-oa" data-types="department">
+				<input type="hidden" name="did" value=''>
+			</td>
+			<td class="layui-td-gray">拟稿日期<font>*</font></td>
+			<td><input type="text" name="draft_time" value='' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择拟稿日期" class="layui-input tool-time"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">主送人员<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="send_names" value='' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择主送人员" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="send_uids" value=''>
+			</td>
+			<td class="layui-td-gray">抄送人员</td>
+			<td>
+				<input type="text" name="copy_names" value='' readonly placeholder="请选择" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="copy_uids" value=''>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">共享可查阅人</td>
+			<td>
+				<input type="text" name="share_names" value='' readonly placeholder="请选择" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="share_uids" value=''>
+			</td>
+			<td class="layui-td-gray">密级程度<font>*</font></td>
+			<td>
+				<input type="radio" name="secrets" value="1" title="公开">
+				<input type="radio" name="secrets" value="2" title="秘密">
+				<input type="radio" name="secrets" value="3" title="机密">
+			</td>
+			<td class="layui-td-gray">紧急程度<font>*</font></td>
+			<td>
+				<input type="radio" name="urgency" value="1" title="普通">
+				<input type="radio" name="urgency" value="2" title="紧急">
+				<input type="radio" name="urgency" value="3" title="加急">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="">
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">公文内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container" style="border:0;padding:0"></textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','uploadPlus','oaPicker','tinymce'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,uploadPlus= layui.uploadPlus,tinymce= layui.tinymce;	
+		//编辑器初始化
+		var editor = layui.tinymce;
+		var edit = editor.render({
+			selector: "#container",
+			images_upload_url: '/api/index/upload/sourse/tinymce',//图片上传接口
+			height: 500
+		});
+
+		//相关附件上传
+		var attachment = new uploadPlus();
+		//监听提交
+		form.on('submit(webform)', function(data){
+			data.field.content = tinyMCE.editors['container'].getContent();
+			if (data.field.content == '') {
+				layer.msg('请先完善公文内容');
+				return false;
+			}
+			if (!data.field.secrets || data.field.secrets == '') {
+				layer.msg('请选择密级程度');
+				return false;
+			}
+			if (!data.field.urgency || data.field.urgency == '') {
+				layer.msg('请选择紧急程度');
+				return false;
+			}
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);				
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/official/add", data.field, callback,clickbtn);
+			return false;
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 147 - 0
app/adm/view/official/datalist.html

@@ -0,0 +1,147 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+
+<div class="p-page">
+	<div class="layui-card border-x border-t" style="margin-bottom:0; box-shadow:0 0 0 0 rgb(5 32 96 / 0%)">
+		<div class="body-table layui-tab layui-tab-brief" lay-filter="tab">
+			<ul class="layui-tab-title">
+				<li class="layui-this">全部公文</li>
+				<li>我发的公文</li>
+				<li>我收到的公文</li>
+				<li>抄送给我的公文</li>
+				<li>共享查阅的公文</li>
+			</ul>
+		</div>
+	</div>
+	<form class="layui-form gg-form-bar border-x" id="barsearchform">
+		<div class="layui-input-inline" style="width:128px">
+			<select name="secrets">
+				<option value="">选择秘密程度</option>
+				{volist name="$secrets" id="vo"}
+				{gt name="$key" value="0"}
+				<option value="{$key}">{$vo}</option>
+				{/gt}
+				{/volist}
+			</select>
+		</div>
+		<div class="layui-input-inline" style="width:128px">
+			<select name="urgency">
+				<option value="">选择重要程度</option>
+				{volist name="$urgency" id="vo"}
+				{gt name="$key" value="0"}
+				<option value="{$key}">{$vo}</option>
+				{/gt}
+				{/volist}
+			</select>
+		</div>
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<input type="hidden" name="tab" value="0" />
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="table_official" lay-filter="table_official"></table>
+</div>
+
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/adm/official/add">+ 添加公文</button>
+  </div>
+</script>
+
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','tablePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool, element = layui.element;
+		//tab切换
+		element.on('tab(tab)', function(data){
+			$('[name="tab"]').val(data.index);
+			$("#barsearchform")[0].reset();
+			layui.pageTable.reload({where:{tab:data.index},page:{curr:1}});
+			return false;
+		});
+		
+		layui.pageTable = table.render({
+			elem: "#table_official"
+			, toolbar: "#toolbarDemo"
+			,url: "/adm/official/datalist"
+			,page: true
+			,limit: 20
+			,cellMinWidth: 60
+			,height: 'full-154'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'check_status',title: '审核状态',width:110, align:'center',templet: function(d){
+					var html = '<span class="check-status-color-'+d.check_status+'">『'+d.check_status_str+'』</span>';
+					return html;
+				}}
+				,{field:'title',title: '公文主题',minWidth:240}
+				,{field:'code',title: '公文编号',width:160}
+				,{field:'secrets_str',title: '密级程度',width:80, align:'center'}
+				,{field:'urgency_str',title: '紧急程度',width:80, align:'center'}
+				,{field:'draft_name',title: '拟稿人',width:80, align:'center'}
+				,{field:'draft_time',title: '拟稿日期',width:100, align:'center'}
+				,{field:'draft_dname',title: '拟稿部门',width:100, align:'center'}
+				,{field:'create_time', title: '创建时间',width:150,align:'center'}
+				,{width:120,fixed:'right',title: '操作', align:'center',templet: function(d){
+					var html='';
+					var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>';
+					var btn2='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>';
+					var btn3='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>';
+					if((d.check_status==0 || d.check_status==4)&& d.admin_id == login_admin){
+						html = '<div class="layui-btn-group">'+btn1+btn2+btn3+'</div>';
+					}
+					else{
+						html = '<div class="layui-btn-group">'+btn1+'</div>';
+					}
+					return html;
+				}}
+			]]
+		});
+		
+		//表头工具栏事件
+		table.on('toolbar(table_official)', function(obj){
+			if (obj.event === 'add') {
+				tool.side("/adm/official/add");
+				return;
+			}
+		});	
+			
+		table.on('tool(table_official)',function (obj) {
+			var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
+			var data = obj.data;
+			if (obj.event === 'view') {
+				tool.side("/adm/official/view?id="+data.id);
+				return;
+			}
+			if (obj.event === 'edit') {
+				tool.side("/adm/official/add?id="+data.id);
+				return;
+			}
+			if (obj.event === 'del') {
+				layer.confirm('确定要删除该内容吗?', { icon: 3, title: '提示' }, function (index) {
+					let callback = function (e) {
+						layer.msg(e.msg);
+						if (e.code == 0) {
+							obj.del();
+						}
+					}
+					tool.delete("/adm/official/del", { id: data.id }, callback);
+					layer.close(index);
+				});
+				return;
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 128 - 0
app/adm/view/official/edit.html

@@ -0,0 +1,128 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-2">编辑公文</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">公文名称<font>*</font></td>
+			<td colspan="3"><input type="text" name="title" value="{$detail.title}" autocomplete="off" placeholder="请输入公文名称" lay-verify="required" lay-reqText="请输入公文名称" class="layui-input"></td>
+			<td class="layui-td-gray">公文文号<font>*</font></td>
+			<td><input type="text" name="code" value="{$detail.code}" autocomplete="off" placeholder="请输入公文文号" lay-verify="required" lay-reqText="请输入公文文号" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">拟稿人<font>*</font></td>
+			<td>
+				<input type="text" name="draft_name" value='{$detail.draft_name}' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择拟稿人" class="layui-input picker-admin">
+				<input type="hidden" name="draft_uid" value='{$detail.draft_uid}'>
+			</td>
+			<td class="layui-td-gray">拟稿部门<font>*</font></td>
+			<td>
+				<input type="text" name="draft_dame" value='{$detail.draft_dame}' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择拟稿部门" class="layui-input picker-oa" data-types="department">
+				<input type="hidden" name="did" value='{$detail.did}'>
+			</td>
+			<td class="layui-td-gray">拟稿日期<font>*</font></td>
+			<td><input type="text" name="draft_time" value='{$detail.draft_time|date="Y-m-d"}' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择拟稿日期" class="layui-input tool-time"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">主送人员<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="send_names" value='{$detail.send_names}' readonly placeholder="请选择" lay-verify="required" lay-reqText="请选择主送人员" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="send_uids" value='{$detail.send_uids}'>
+			</td>
+			<td class="layui-td-gray">抄送人员</td>
+			<td>
+				<input type="text" name="copy_names" value='{$detail.copy_names}' readonly placeholder="请选择" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="copy_uids" value='{$detail.copy_uids}'>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">共享可查阅人</td>
+			<td>
+				<input type="text" name="share_names" value='{$detail.share_names}' readonly placeholder="请选择" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="share_uids" value='{$detail.share_uids}'>
+			</td>
+			<td class="layui-td-gray">密级程度<font>*</font></td>
+			<td>
+				<input type="radio" name="secrets" value="1" title="公开" {eq name="$detail.secrets" value="1"} checked{/eq}>
+				<input type="radio" name="secrets" value="2" title="秘密" {eq name="$detail.secrets" value="2"} checked{/eq}>
+				<input type="radio" name="secrets" value="3" title="机密" {eq name="$detail.secrets" value="3"} checked{/eq}>
+			</td>
+			<td class="layui-td-gray">紧急程度<font>*</font></td>
+			<td>
+				<input type="radio" name="urgency" value="1" title="普通" {eq name="$detail.urgency" value="1"} checked{/eq}>
+				<input type="radio" name="urgency" value="2" title="紧急" {eq name="$detail.urgency" value="2"} checked{/eq}>
+				<input type="radio" name="urgency" value="3" title="加急" {eq name="$detail.urgency" value="3"} checked{/eq}>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids}">
+					{notempty name="$detail.file_array"}
+					{volist name="$detail.file_array" id="vo"}
+					<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo)}</div>
+					{/volist}
+					{/notempty}
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">公文内容<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container" style="border:0;padding:0">{$detail.content}</textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-4">
+		<input type="hidden" name="id" value="{$detail.id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','uploadPlus','oaPicker','tinymce'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,uploadPlus= layui.uploadPlus,tinymce= layui.tinymce;	
+		//编辑器初始化
+		var editor = layui.tinymce;
+		var edit = editor.render({
+			selector: "#container",
+			images_upload_url: '/api/index/upload/sourse/tinymce',//图片上传接口
+			height: 500
+		});
+
+		//相关附件上传
+		var attachment = new uploadPlus();
+		//监听提交
+		form.on('submit(webform)', function(data){
+			data.field.content = tinyMCE.editors['container'].getContent();
+			if (data.field.content == '') {
+				layer.msg('请先完善公文内容');
+				return false;
+			}
+			let callback = function (e) {
+				layer.msg(e.msg);
+				if (e.code == 0) {
+					tool.sideClose(1000);				
+				}
+			}
+			let clickbtn = $(this);
+			tool.post("/adm/official/add", data.field, callback,clickbtn);
+			return false;
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 64 - 0
app/adm/view/official/pending.html

@@ -0,0 +1,64 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="table_official" lay-filter="table_official"></table>
+</div>
+
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','tablePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool;
+		
+		layui.pageTable = table.render({
+			elem: "#table_official"
+			,toolbar: false
+			,url: "/adm/official/pending"
+			,page: true
+			,limit: 20
+			,cellMinWidth: 60
+			,height: 'full-114'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'title',title: '公文主题',minWidth:240}
+				,{field:'code',title: '公文编号',width:160}
+				,{field:'secrets_str',title: '密级程度',width:80, align:'center'}
+				,{field:'urgency_str',title: '紧急程度',width:80, align:'center'}
+				,{field:'draft_name',title: '拟稿人',width:80, align:'center'}
+				,{field:'draft_time',title: '拟稿日期',width:100, align:'center'}
+				,{field:'draft_dname',title: '拟稿部门',width:100, align:'center'}
+				,{field:'create_time', title: '创建时间',width:150,align:'center'}
+				,{width:80,fixed:'right',title: '操作', align:'center',templet: function(d){
+					var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>';
+					return btn1;
+				}}
+			]]
+		});
+			
+		table.on('tool(table_official)',function (obj) {
+			var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
+			var data = obj.data;
+			if (obj.event === 'view') {
+				tool.side("/adm/official/view?id="+data.id);
+				return;
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 64 - 0
app/adm/view/official/reviewed.html

@@ -0,0 +1,64 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+
+<div class="p-page">
+	<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+		<div class="layui-input-inline" style="width:300px">
+			<input type="text" name="keywords" placeholder="关键字" class="layui-input" autocomplete="off" />
+		</div>
+		<div class="layui-input-inline" style="width:150px">
+			<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+			<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
+		</div>
+	</form>
+	<table class="layui-hide" id="table_official" lay-filter="table_official"></table>
+</div>
+
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	const moduleInit = ['tool','tablePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool;
+		
+		layui.pageTable = table.render({
+			elem: "#table_official"
+			,toolbar: false
+			,url: "/adm/official/reviewed"
+			,page: true
+			,limit: 20
+			,cellMinWidth: 60
+			,height: 'full-114'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'title',title: '公文主题',minWidth:240}
+				,{field:'code',title: '公文编号',width:160}
+				,{field:'secrets_str',title: '密级程度',width:80, align:'center'}
+				,{field:'urgency_str',title: '紧急程度',width:80, align:'center'}
+				,{field:'draft_name',title: '拟稿人',width:80, align:'center'}
+				,{field:'draft_time',title: '拟稿日期',width:100, align:'center'}
+				,{field:'draft_dname',title: '拟稿部门',width:100, align:'center'}
+				,{field:'create_time', title: '创建时间',width:150,align:'center'}
+				,{width:80,fixed:'right',title: '操作', align:'center',templet: function(d){
+					var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>';
+					return btn1;
+				}}
+			]]
+		});
+			
+		table.on('tool(table_official)',function (obj) {
+			var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
+			var data = obj.data;
+			if (obj.event === 'view') {
+				tool.side("/adm/official/view?id="+data.id);
+				return;
+			}
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 110 - 0
app/adm/view/official/view.html

@@ -0,0 +1,110 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page">
+	<h3 class="pb-2">公文详情</h3>
+	<table class="layui-table layui-table-form">
+		<tr>
+			<td class="layui-td-gray">公文名称</td>
+			<td colspan="3">{$detail.title}</td>
+			<td class="layui-td-gray">公文文号</td>
+			<td>{$detail.code}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">拟稿人</td>
+			<td>{$detail.draft_name}</td>
+			<td class="layui-td-gray">拟稿部门</td>
+			<td>{$detail.draft_dame}</td>
+			<td class="layui-td-gray">拟稿日期</td>
+			<td>{$detail.draft_time|date="Y-m-d"}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">主送人员</td>
+			<td colspan="3">{$detail.send_names}</td>
+			<td class="layui-td-gray">抄送人员</td>
+			<td>{$detail.copy_names|default='-'}</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">共享可查阅人</td>
+			<td>{$detail.share_names|default='-'}
+				{eq name="$auth_office" value="1"}
+				<span id="shares" data-ids="{$detail.share_uids}" data-names="{$detail.share_names}" class="layui-btn layui-btn-xs layui-btn-normal ml-1">更改</span>
+				{/eq}
+			</td>
+			<td class="layui-td-gray">密级程度</td>
+			<td>
+				{eq name="$detail.secrets" value="1"}公开{/eq}
+				{eq name="$detail.secrets" value="2"}秘密{/eq}
+				{eq name="$detail.secrets" value="3"}机密{/eq}
+			</td>
+			<td class="layui-td-gray">紧急程度</td>
+			<td>
+				{eq name="$detail.urgency" value="1"}普通{/eq}
+				{eq name="$detail.urgency" value="2"}紧急{/eq}
+				{eq name="$detail.urgency" value="3"}加急{/eq}
+			</td>
+		</tr>
+		{notempty name="$detail.file_ids"}
+		<tr>
+			<td class="layui-td-gray-2">相关附件</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					{volist name="$detail.file_array" id="vo"}
+					<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo,'view')}</div>
+					{/volist}
+				</div>
+			</td>
+		</tr>
+		{/notempty}
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">公文内容</td>
+			<td colspan="5">{$detail.content|raw}</td>
+		</tr>
+	</table>
+	
+	<div id="checkBox" data-status="{$detail.check_status|default=0}" data-id="{$detail.id|default=0}" data-checkflowid="{$detail.check_flow_id|default=0}" class="pt-3"></div>
+</div>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+	var detail_id = {$detail.id};
+	const moduleInit = ['tool','oaCheck','oaPicker'];
+	function gouguInit() {
+		var form = layui.form,tool=layui.tool,oaCheck=layui.oaCheck,oaPicker=layui.oaPicker;	
+		oaCheck.init({
+			check_name:'official_docs',
+			check_copy:0
+		});
+		
+		let eventCallback = function (e) {
+			layer.msg(e.msg);
+			parent.layui.pageTable.reload();
+			setTimeout(function(){
+				location.reload();
+			},1200)					
+		}
+		//选择共享成员弹窗	
+		$('body').on('click','#shares',function () {
+			let that = $(this);
+			let ids=$(this).data('ids')+'',names = $(this).data('names')+'';
+			oaPicker.employeeInit({
+				ids:ids,
+				names:names,
+				type:2,//1是单选,2是多选
+				callback:function(data){
+					let select_id=[],select_name=[];
+					for(var a=0; a<data.length;a++){
+						select_id.push(data[a].id);
+						select_name.push(data[a].name);
+					}
+					tool.post("/adm/official/add", {'id':detail_id,'share_uids':select_id.join(','),'scene':'change'}, eventCallback);
+				}
+			});
+		});
+	}
+</script>
+{/block}
+<!-- /脚本 -->

+ 184 - 0
app/adm/view/property/add.html

@@ -0,0 +1,184 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">新增资产</h3>
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray">资产名称<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="title"  placeholder="请输入资产名称" lay-verify="required" lay-reqText="请输入资产名称" class="layui-input">
+			</td>
+			<td class="layui-td-gray-2" rowspan="5">
+			资产缩略图
+			<button type="button" class="layui-btn layui-btn-sm" id="uploadImg">+ 上传图片</button>
+			</td>
+			<td rowspan="5" style="width:252px;">
+				  <div id="demo1" style="width: 240px; height:136px; overflow: hidden;">
+					<img src="" style="max-width: 100%; height:136px;" />
+					<input type="hidden" name="thumb" value="">
+				  </div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">资产编码<font>*</font></td>
+			<td>
+				<input type="text" name="code"  value="{:get_codeno('ZC')}" class="layui-input" lay-verify="required">
+			</td>
+			<td class="layui-td-gray">资产型号<font>*</font></td>
+			<td><input type="text" name="model"  value="" class="layui-input" lay-verify="required"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">资产分类<font>*</font></td>
+			<td>
+			  <select name="cate_id" lay-verify="required" lay-reqText="请选择资产分类">
+				<option value="">请选择大分类</option>
+				{volist name=":set_recursion(get_base_data('PropertyCate'))" id="v"}
+				<option value="{$v.id}">{$v.title}</option>
+				{/volist}
+			  </select>
+			</td>
+			<td class="layui-td-gray">资产品牌<font>*</font></td>
+			<td>
+				<select name="brand_id" lay-verify="required" lay-reqText="请选择品牌">
+				<option value="">请选择品牌</option>
+				{volist name=":get_base_data('PropertyBrand')" id="v"}
+				<option value="{$v.id}">{$v.title}</option>
+				{/volist}
+			  </select>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">质保到期日<font>*</font></td>
+			<td><input type="text" name="quality_time"  readonly placeholder="请选择质保到期日" class="layui-input tool-time" lay-verify="required" lay-reqText="请完善质保到期日"></td>
+			<td class="layui-td-gray">资产单位<font>*</font></td>
+			<td>
+				<select name="unit_id" lay-verify="required" lay-reqText="请选择资产单位">
+				<option value="">请选择单位</option>
+				{volist name=":get_base_data('PropertyUnit')" id="v"}
+				<option value="{$v.id}">{$v.title}</option>
+				{/volist}
+			  </select>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">使用人员</td>
+			<td>
+				<input type="text" name="users_name"  readonly placeholder="请选择使用人员" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="user_ids" value="">
+			</td>
+			<td class="layui-td-gray">使用部门</td>
+			<td><select id="user_dids" name="user_dids" xm-selected="" xm-select="select1" xm-select-skin="default"></select></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">购买价格<font>*</font></td>
+			<td><input type="text" name="price"  placeholder="请输入购买价格" lay-verify="required|number" lay-reqText="请输入购买价格" class="layui-input"></td>
+			<td class="layui-td-gray">购买日期<font>*</font></td>
+			<td><input type="text" name="buy_time"  readonly placeholder="请选择购买日期" lay-verify="required" lay-reqText="请选择购买日期" class="layui-input tool-time"></td>
+			<td class="layui-td-gray">年折旧率(%)<font>*</font></td>
+			<td><input type="text" name="rate"  placeholder="请输入年折旧率,不需要输入%" lay-verify="required|number" lay-reqText="请输入年折旧率,不需要%" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">资产状态<font>*</font></td>
+			<td colspan="5">
+				{volist name="$status" id="vo"}
+				<input type="radio" name="status" value="{$key}" title="{$vo}">
+				{/volist}
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">资产来源<font>*</font></td>
+			<td colspan="5">
+				{volist name="$source" id="vo"}
+				{gt name="$key" value="0"}
+				<input type="radio" name="source" value="{$key}" title="{$vo}">
+				{/gt}
+				{/volist}
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">放置地址</td>
+			<td colspan="5"><input type="text" name="address"  placeholder="请输入放置地址" class="layui-input"></td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="">
+				</div>
+			</td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">资产描述</td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container"></textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-2">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','formSelects','uploadPlus','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus, formSelects = layui.formSelects;
+	
+	//选择部门
+	var selected = $('#department_ids').attr('xm-selected');
+	formSelects.data('select1', 'server', {
+		url: '/api/index/get_department_select',
+		keyword: selected
+	});
+    //单图上传
+	var photoUpload = new uploadPlus({
+		'use':'single',
+		'target':'uploadImg',
+		'callback':function(res){
+			layer.msg(res.msg);
+			if (res.code == 0) {
+				//上传成功
+				$('#demo1 input').attr('value', res.data.id);
+				$('#demo1 img').attr('src', res.data.filepath);
+			}
+		}
+	});
+
+	//相关附件上传
+	var attachment = new uploadPlus();
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000);				
+			}
+		}
+		if(!data.field.status){
+			layer.msg('请选择资产状态');
+			return false;
+		}
+		if(!data.field.source){
+			layer.msg('请选择资产来源');
+			return false;
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/property/add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 164 - 0
app/adm/view/property/datalist.html

@@ -0,0 +1,164 @@
+{extend name="../../base/view/common/base" /}
+{block name="style"}
+  <style>
+	.tree-left{width:220px; float:left; height:calc(100% - 40px); overflow: scroll; border:1px solid #eeeeee; background-color:#fff; padding:12px 12px 12px 5px;}
+	.tree-left h3{font-size:16px; height:30px; padding-left:10px; font-weight:800}
+  </style>
+{/block}
+<!-- 主体 -->
+{block name="body"}
+<div class="p-page" style="height:100%; box-sizing: border-box;">
+	<div class="tree-left">
+		<h3>资产分类</h3>
+		<div id="cate"></div>
+	</div>
+	<div class="body-table" style="margin-left:248px; overflow:hidden;">
+		<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
+			<div class="layui-input-inline" style="width:120px">
+				<select name="brand_id">
+					<option value="">资产品牌</option>
+					{volist name=":get_base_data('PropertyBrand')" id="v"}
+					<option value="{$v.id}">{$v.title}</option>
+					{/volist}
+				</select>
+			</div>
+			<div class="layui-input-inline" style="width:100px">
+				<select name="status">
+					<option value="">资产状态</option>
+					{volist name="$status" id="vo"}
+					<option value="{$key}">{$vo}</option>
+					{/volist}
+				</select>
+			</div>
+			<div class="layui-input-inline" style="width:300px">
+				<input type="text" name="keywords" placeholder="输入关键字" class="layui-input" autocomplete="off" />
+			</div>
+			<div class="layui-input-inline" style="width:150px">
+				<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
+				<button type="reset" class="layui-btn layui-btn-reset" lay-filter="reset">重置</button>
+			</div>
+		</form>
+		<table class="layui-hide" id="test" lay-filter="test"></table>
+	</div>
+</div>
+<script type="text/html" id="toolbarDemo">
+  <div class="layui-btn-container">
+  	<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/adm/property/add">+ 添加资产</button>
+  </div>
+</script>
+{/block}
+<!-- /主体 -->
+{block name="copyright"}{/block}
+<!-- 脚本 -->
+{block name="script"}
+	<script>
+	const status_types = [{"id":0,"title":"闲置"},{"id":1,"title":"在用"},{"id":2,"title":"维修"},{"id":3,"title":"报废"},{"id":4,"title":"丢失"}];
+	const moduleInit = ['tool','tablePlus'];
+	function gouguInit() {
+		var table = layui.tablePlus, tool = layui.tool,tree = layui.tree,form = layui.form,dropdown = layui.dropdown;			
+		$.ajax({
+			url: "/adm/api/get_propertycate_tree",
+			type:'get',
+			success:function(res){					
+				//仅节点左侧图标控制收缩
+				tree.render({
+					elem: '#cate',
+					data: res.trees,
+					onlyIconControl: true,  //是否仅允许节点左侧图标控制展开收缩
+					click: function(obj){
+						//layer.msg(JSON.stringify(obj.data));
+						$('#cate').find('.layui-tree-main').removeClass('on');
+						$(obj.elem).find('.layui-tree-main').eq(0).addClass('on');
+						layui.pageTable.reload({
+						   where: {cate_id: obj.data.id},
+						   page:{curr:1}
+						});
+						$('[name="keywords"]').val('');
+						$('[name="brand_id"]').val('');
+						$('[name="status"]').val('');
+						form.render();
+					}
+				});	
+			}
+		})
+		
+		$('[lay-filter="reset"]').click(function(){
+			$('#cate').find('.layui-tree-main').removeClass('on');
+		});
+		
+		layui.pageTable = table.render({
+			elem: '#test'
+			,toolbar: '#toolbarDemo'
+			,title:'资产列表'
+			,url: "/adm/property/datalist"
+			,is_excel: true
+			,page: true
+			,cellMinWidth: 60
+			,height: 'full-88'
+			,cols: [[
+				{field:'id',width:80, title: 'ID号', align:'center'}
+				,{field:'code',width:160, title: '资产编码', align:'center'}
+				,{field:'cate',width:120, title: '资产分类', align:'center'}
+				,{field:'title',minWidth:240,title: '资产名称'}
+				,{field:'brand',title: '品牌',align: 'center',width: 100}
+				,{field:'model',title: '型号',align: 'center',width: 100}
+				,{field:'unit',title: '单位',align: 'center',width: 60}
+				,{field:'price',width:100, title: '价格(元)', align:'center',style:"color:#16b777"}
+				,{field:'status_str', title: '状态',width:60,align:'center'}
+				,{field:'create_name',title: '创建人',align: 'center',width: 80}
+				,{field:'create_time',title: '创建时间',align: 'center',width: 150}
+				,{field:'update_name',title: '最后修改人',align: 'center',width: 100}
+				,{field:'update_time_str',title: '最后修改时间',align: 'center',width: 150}
+				,{width:200,fixed:'right', title: '操作', align:'center',templet: function(d){
+					var html='';
+					var btn='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a><a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详情</a>';
+					var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="set">设置状态 <i class="layui-icon layui-icon-down layui-font-12"></i></a>';
+					var btn2='<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="repair">维修</a>';
+						html = '<div class="layui-btn-group">'+btn+btn1+btn2+'</div>';
+					return html;
+				}}
+			]]
+		});
+		
+		table.on('tool(test)',function (obj) {
+			var that = this;
+			if(obj.event === 'edit'){					
+				tool.side("/adm/property/add?id="+obj.data.id);
+			}
+			if(obj.event === 'view'){					
+				tool.side("/adm/property/view?id="+obj.data.id);
+			}
+			if(obj.event === 'repair'){					
+				tool.side("/adm/property/repair_add?pid="+obj.data.id);
+			}
+			if(obj.event === 'set'){
+				dropdown.render({
+					elem: that,
+					show: true, // 外部事件触发即显示
+					data: status_types,
+					click: function(item){
+						layer.confirm('确定要修改该资产状态为【'+item.title+'】吗?', {icon: 3, title:'提示'}, function(index){
+							let callback = function (e) {
+								layer.msg(e.msg);
+								if (e.code == 0) {
+									layui.pageTable.reload();
+								}
+							}
+							tool.post("/adm/property/check", { id: obj.data.id,status: item.id}, callback);
+							layer.close(index);
+						});
+					}
+				});
+				return;
+			}
+		});
+		
+		//监听搜索提交
+		form.on('submit(webform)', function(data){
+			layui.pageTable.reload({where:data.field,page:{curr:1}});
+			return false;
+		});
+	}
+	</script>
+{/block}
+<!-- /脚本 -->

+ 190 - 0
app/adm/view/property/edit.html

@@ -0,0 +1,190 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-4">
+	<h3 class="pb-1">编辑资产</h3>
+	<table class="layui-table">
+		<tr>
+			<td class="layui-td-gray">资产名称<font>*</font></td>
+			<td colspan="3">
+				<input type="text" name="title" value="{$detail.title}"  placeholder="请输入资产名称" lay-verify="required" lay-reqText="请输入资产名称" class="layui-input">
+			</td>
+			<td class="layui-td-gray-2" rowspan="5">
+			缩略图
+			<button type="button" class="layui-btn layui-btn-xs" id="uploadImg">+ 上传缩略图</button>
+			</td>
+			<td rowspan="5" style="width:252px;">
+				<div class="layui-upload-list" id="demo1" style="width: 240px; height:136px; overflow: hidden;">
+					<img src="{:get_file($detail.thumb)}" style="max-width: 100%; height:136px;" />
+					<input type="hidden" name="thumb" value="{$detail.thumb}">
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">资产编码<font>*</font></td>
+			<td>
+				<input type="text" name="code" value="{$detail.code}" class="layui-input" lay-verify="required">
+			</td>
+			<td class="layui-td-gray">资产型号<font>*</font></td>
+			<td><input type="text" name="model"  value="{$detail.model}"  class="layui-input" lay-verify="required"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">资产分类<font>*</font></td>
+			<td>
+			  <select name="cate_id" lay-verify="required" lay-reqText="请选择分类">
+				<option value="">请选择分类</option>
+				{volist name=":set_recursion(get_base_data('PropertyCate'))" id="v"}
+				<option value="{$v.id}" {eq name="$v.id" value="$detail.cate_id"} selected{/eq}>{$v.title}</option>
+				{/volist}
+			  </select>
+			</td>
+			<td class="layui-td-gray">资产品牌<font>*</font></td>
+			<td>
+				<select name="brand_id" lay-verify="required" lay-reqText="请选择品牌">
+				<option value="">请选择品牌</option>
+				{volist name=":get_base_data('PropertyBrand')" id="v"}
+				<option value="{$v.id}" {eq name="v.id" value="$detail.brand_id"} selected{/eq}>{$v.title}</option>
+				{/volist}
+			  </select>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">质保到期日<font>*</font></td>
+			<td><input type="text" name="quality_time" value="{$detail.quality_time|date='Y-m-d'}" readonly placeholder="请选择质保到期日" class="layui-input tool-time" lay-verify="required" lay-reqText="请完善质保到期日"></td>
+			<td class="layui-td-gray">单位<font>*</font></td>
+			<td>
+				<select name="unit_id" lay-verify="required" lay-reqText="请选择单位">
+				<option value="">请选择单位</option>
+				{volist name=":get_base_data('PropertyUnit')" id="v"}
+				<option value="{$v.id}" {eq name="v.id" value="$detail.unit_id"} selected{/eq}>{$v.title}</option>
+				{/volist}
+			  </select>
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">使用人员</td>
+			<td>
+				<input type="text" name="users_name" value="{$detail.users_name|default=''}"  readonly placeholder="请选择使用人员" class="layui-input picker-admin" data-type="2">
+				<input type="hidden" name="user_ids" value="{$detail.user_ids}">
+			</td>
+			<td class="layui-td-gray">使用部门</td>
+			<td><select id="user_dids" name="user_dids" xm-selected="{$detail.user_dids}" xm-select="select1" xm-select-skin="default"></select></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">购买价格<font>*</font></td>
+			<td><input type="text" name="price" value="{$detail.price}"  placeholder="请输入购买价格" lay-verify="required|number" lay-reqText="请输入购买价格" class="layui-input"></td>
+			<td class="layui-td-gray">购买日期<font>*</font></td>
+			<td><input type="text" name="buy_time" value="{$detail.buy_time|date='Y-m-d'}"  readonly placeholder="请选择购买日期" lay-verify="required" lay-reqText="请选择购买日期" class="layui-input tool-time"></td>
+			<td class="layui-td-gray">年折旧率(%)<font>*</font></td>
+			<td><input type="text" name="rate" value="{$detail.rate}"  placeholder="请输入年折旧率,不需要输入%" lay-verify="required|number" lay-reqText="请输入年折旧率,不需要%" class="layui-input"></td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">资产状态<font>*</font></td>
+			<td colspan="5">
+				{volist name="$status" id="vo"}
+				<input type="radio" name="status" value="{$key}" title="{$vo}" {eq name="$key" value="$detail.status"} checked{/eq}>
+				{/volist}
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">资产来源<font>*</font></td>
+			<td colspan="5">
+				{volist name="$source" id="vo"}
+				{gt name="$key" value="0"}
+				<input type="radio" name="source" value="{$key}" title="{$vo}" {eq name="$key" value="$detail.source"} checked{/eq}>
+				{/gt}
+				{/volist}
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray">放置地址</td>
+			<td colspan="5"><input type="text" name="address" value="{$detail.address}"  placeholder="请输入放置地址" class="layui-input"></td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">资产附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids}">
+					{notempty name="$detail.fileArray"}
+					{volist name="$detail.fileArray" id="vo"}
+					<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo)}</div>
+					{/volist}
+					{/notempty}
+				</div>			
+			</td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">资产描述</td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container">{$detail.content}</textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-2">
+		<input type="hidden" name="id" value="{$detail.id}">
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','formSelects','uploadPlus','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus, formSelects = layui.formSelects;
+	
+	//选择部门
+	var selected = $('#user_dids').attr('xm-selected');
+	formSelects.data('select1', 'server', {
+		url: '/api/index/get_department_select',
+		keyword: selected
+	});
+    //单图上传
+	var photoUpload = new uploadPlus({
+		'use':'single',
+		'target':'uploadImg',
+		'callback':function(res){
+			layer.msg(res.msg);
+			if (res.code == 0) {
+				//上传成功
+				$('#demo1 input').attr('value', res.data.id);
+				$('#demo1 img').attr('src', res.data.filepath);
+			}
+		}
+	});
+
+	//相关附件上传
+	var attachment = new uploadPlus();
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000);				
+			}
+		}
+		if(!data.field.status){
+			layer.msg('请选择资产状态');
+			return false;
+		}
+		if(!data.field.source){
+			layer.msg('请选择资产来源');
+			return false;
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/property/add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 87 - 0
app/adm/view/property/repair_add.html

@@ -0,0 +1,87 @@
+{extend name="../../base/view/common/base" /}
+<!-- 主体 -->
+{block name="body"}
+<form class="layui-form p-page">
+	<h3 class="pb-1">新增资产维修记录</h3>
+	<table class="layui-table">
+		{eq name="$pid" value="0"}
+		<tr>
+			<td class="layui-td-gray">资产名称<font>*</font></td>
+			<td colspan="5">
+				<input type="text" name="property_name" readonly lay-verify="required" lay-reqText="请选择资产" placeholder="请选择" class="layui-input picker-oa" data-types="property">
+				<input type="hidden" name="property_id" value="">
+			</td>
+		</tr>
+		{else/}
+		<tr>
+			<td class="layui-td-gray">资产名称</td>
+			<td colspan="5">{$property.title}</td>
+		</tr>
+		{/eq}
+		<tr>
+			<td class="layui-td-gray">维修日期<font>*</font></td>
+			<td><input type="text" name="repair_time" readonly placeholder="请选择维修日期" class="layui-input tool-time"></td>
+			<td class="layui-td-gray">维修费用<font>*</font></td>
+			<td><input type="text" name="cost" placeholder="请输入维修费用" lay-verify="required|number" lay-reqText="请输入维修费用" class="layui-input"></td>
+			<td class="layui-td-gray">跟进人<font>*</font></td>
+			<td>
+				<input type="text" name="director_name" readonly lay-verify="required" lay-reqText="请选择负责人" placeholder="请选择" class="layui-input picker-admin">
+				<input type="hidden" name="director_id">
+			</td>
+		</tr>
+		<tr>
+			<td class="layui-td-gray-2">
+				<div class="layui-input-inline">相关附件</div>
+				<div class="layui-input-inline">
+					<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
+				</div>
+			</td>
+			<td colspan="5">
+				<div class="layui-row" id="uploadBox">
+					<input type="hidden" data-type="file" name="file_ids" value="">
+				</div>
+			</td>
+		</tr> 
+		<tr>
+			<td class="layui-td-gray" style="vertical-align:top;">维修原因<font>*</font></td>
+			<td colspan="5">
+				<textarea name="content" placeholder="请输入内容" class="layui-textarea" lay-verify="required" lay-reqText="请完善维修原因"></textarea>
+			</td>
+		</tr>
+	</table>
+	<div class="pt-2">
+		{gt name="$pid" value="0"}
+		<input type="hidden" name="property_id" value="{$pid}">
+		{/gt}
+		<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
+		<button type="reset" class="layui-btn layui-btn-primary">重置</button>
+    </div>
+</form>
+{/block}
+<!-- /主体 -->
+
+<!-- 脚本 -->
+{block name="script"}
+<script>
+const moduleInit = ['tool','uploadPlus','oaPicker'];
+function gouguInit() {
+	var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus;
+	//相关附件上传
+	var attachment = new uploadPlus();
+	
+	//监听提交
+	form.on('submit(webform)', function(data){
+		let callback = function (e) {
+			layer.msg(e.msg);
+			if (e.code == 0) {
+				tool.sideClose(1000);				
+			}
+		}
+		let clickbtn = $(this);
+		tool.post("/adm/property/repair_add", data.field, callback,clickbtn);
+		return false;
+	});
+}
+</script>
+{/block}
+<!-- /脚本 -->

+ 0 - 0
app/adm/view/property/repair_edit.html


Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä