edit.html 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323
  1. {extend name="common/common2" /}
  2. {block name="main"}
  3. <style>
  4. .ctable td{
  5. min-width: 150px!important;
  6. max-width: 300px!important;
  7. }
  8. </style>
  9. <div class="row">
  10. <div class="col-sm-12">
  11. <div class="ibox float-e-margins">
  12. <div class="ibox-content" id="vue-plan">
  13. <p><br></p>
  14. <div class="row">
  15. <div class="col-xs-6 col-xs-offset-3">
  16. <el-steps :active="step" align-center finish-status="success">
  17. <el-step title="配置地点"></el-step>
  18. <el-step title="配置排班"></el-step>
  19. <el-step title="任务确认"></el-step>
  20. </el-steps>
  21. </div>
  22. </div>
  23. <p><br></p>
  24. <form method="post" class="form-horizontal">
  25. <div v-if="step == 0">
  26. <div class="form-group">
  27. <label class="col-sm-2 control-label">任务名称<span class="text-danger">*</span></label>
  28. <div class="col-sm-8">
  29. <input type="text" class="form-control" v-model="title" value="" placeholder="请输入任务名称">
  30. </div>
  31. </div>
  32. <div class="form-group">
  33. <label class="col-sm-2 control-label">计划时间<span class="text-danger">*</span></label>
  34. <div class="col-sm-8">
  35. <el-date-picker
  36. style="width: 100%"
  37. size="small"
  38. v-model="date"
  39. type="daterange"
  40. range-separator="至"
  41. value-format="yyyy-MM-dd"
  42. start-placeholder="开始日期"
  43. end-placeholder="结束日期">
  44. </el-date-picker>
  45. </div>
  46. </div>
  47. <div class="form-group" {if $mode==4} style="display: block" {else} style="display: none" {/if}>
  48. <label class="col-sm-2 control-label">选择分类<span class="text-danger">*</span></label>
  49. <div class="col-sm-8">
  50. <el-select clearable multiple filterable v-model="cate" placeholder="请选择分类">
  51. <el-option
  52. v-for="item in cateList"
  53. :key="item.id"
  54. :label="item.title"
  55. :value="item.id.toString()">
  56. </el-option>
  57. </el-select>
  58. </div>
  59. </div>
  60. <div class="form-group">
  61. <label class="col-sm-2 control-label">地点<span class="text-danger">*</span></label>
  62. <div class="col-sm-8">
  63. <button class="btn btn-sm btn-primary" type="button" @click="selectAddr()">添加地点</button>
  64. <button class="btn btn-sm btn-primary" type="button" @click="selectForm()">设置检查内容</button>
  65. <button class="btn btn-sm btn-danger" type="button" @click="delAddrs">移除</button>
  66. <button class="btn btn-sm btn-primary" type="button" @click="sortAddrs">确定排序</button>
  67. <el-table
  68. v-if="tableData.length > 0"
  69. :data="tableData"
  70. height="350"
  71. border
  72. @selection-change="handleSelectionChange"
  73. style="width: 100%">
  74. <el-table-column
  75. type="selection"
  76. width="60">
  77. </el-table-column>
  78. <el-table-column
  79. prop="addrTitle"
  80. label="地点名称"
  81. width="180">
  82. </el-table-column>
  83. <el-table-column prop="formTitle" label="检查内容">
  84. <template slot-scope="scope">
  85. <span v-for="(item,index) in scope.row.forms" :key="index">{{item.title}};</span>
  86. </template>
  87. </el-table-column>
  88. <el-table-column prop="sorts" label="排序">
  89. <template slot-scope="scope">
  90. <input type="number" step="1" class="form-control" v-model="scope.row.sorts">
  91. </template>
  92. </el-table-column>
  93. <!-- <el-table-column label="操作" width="180">-->
  94. <!-- <template slot-scope="scope">-->
  95. <!-- <button class="btn btn-sm" type="button" @click="moveUp(scope.$index, scope.row)">上移</button>-->
  96. <!-- <button class="btn btn-sm" type="button" @click="moveDown(scope.$index, scope.row)">下移</button>-->
  97. <!-- </template>-->
  98. <!-- </el-table-column>-->
  99. </el-table>
  100. </div>
  101. </div>
  102. <div class="form-group">
  103. <label class="col-sm-2 control-label">是否按顺序执行<span class="text-danger">*</span></label>
  104. <div class="col-sm-8" style="padding-top: 7px;">
  105. <el-radio v-model="inOrder" :label="0">否</el-radio>
  106. <el-radio v-model="inOrder" :label="1">是</el-radio>
  107. </div>
  108. </div>
  109. <div class="form-group" v-if="inOrder === 1 && lines.length > 0">
  110. <label class="col-sm-2 control-label">路线时间设置</label>
  111. <div class="col-sm-8" style="padding-top: 7px;">
  112. <table class="table table-bordered ctable text-center">
  113. <tr>
  114. <th class="text-center">路线</th>
  115. <th class="text-center">时间跨度(分钟)</th>
  116. <th class="text-center">浮动时间(分钟)</th>
  117. </tr>
  118. <tr v-for="(item,index) in lines" :key="index">
  119. <td>{{item.st}} ~ {{item.et}}</td>
  120. <td><el-input type="number" v-model="item.kd" size="small" style="width: 140px" placeholder=""></el-input></td>
  121. <td><el-input type="number" v-model="item.fd" size="small" style="width: 140px" placeholder=""></el-input></td>
  122. </tr>
  123. </table>
  124. </div>
  125. </div>
  126. </div>
  127. <div v-if="step == 1">
  128. <div class="form-group">
  129. <label class="col-sm-2 control-label">设置人员<span class="text-danger">*</span></label>
  130. <div class="col-sm-8">
  131. <el-select
  132. clearable filterable
  133. v-model="userIds"
  134. multiple
  135. collapse-tags
  136. style="width: 100%"
  137. size="small"
  138. placeholder="请选择">
  139. <el-option
  140. v-for="item in users"
  141. :key="item.id"
  142. :label="item.title"
  143. :value="item.id">
  144. </el-option>
  145. </el-select>
  146. </div>
  147. </div>
  148. <div class="form-group">
  149. <label class="col-sm-2 control-label">时间段配置<span class="text-danger">*</span></label>
  150. <div class="col-sm-8">
  151. <el-select v-model="dateType" placeholder="请选择" style="width: 100px;" size="small">
  152. <el-option
  153. v-for="item in dateTypes"
  154. :key="item.id"
  155. :label="item.title"
  156. :value="item.id">
  157. </el-option>
  158. </el-select>
  159. <span v-if="dateType == 3">
  160. <el-date-picker
  161. style="width: 130px"
  162. size="small"
  163. v-model="dateFrom"
  164. type="date"
  165. value-format="yyyy-MM-dd"
  166. placeholder="请选择日期">
  167. </el-date-picker>
  168. 开始,工作
  169. <el-input type="number" @input="changePlay" v-model="datePlay" size="small" style="width: 80px;" placeholder="请输入天数"></el-input>
  170. 天,
  171. 暂停
  172. <el-input type="number" @input="changePause" v-model="datePause" size="small" style="width: 80px;" placeholder="请输入天数"></el-input>
  173. 天,每天的
  174. </span>
  175. <button v-if="dateType == 2" class="btn btn-sm btn-default" type="button" @click="selectWeek">添加周</button>
  176. <button class="btn btn-sm btn-default" type="button" @click="selectTime">添加时间段</button>
  177. 开始任务
  178. <div v-if="dateType == 2" style="padding: 5px 0">
  179. 已选择周:
  180. <el-tag
  181. style="margin-right: 5px;cursor: pointer"
  182. v-for="item in dateWeeks"
  183. size="small"
  184. :key="item.id"
  185. :type="item.type"
  186. effect="dark"
  187. >
  188. {{ item.title }}
  189. </el-tag>
  190. </div>
  191. <div style="padding: 5px 0">
  192. 已选择时间段:
  193. <el-tag
  194. style="margin-right: 5px;margin-bottom: 5px"
  195. :key="index"
  196. v-for="(item,index) in dateTimes"
  197. size="small"
  198. >
  199. {{item.stime}} ~ <span v-if="item.stype == 1">{{item.sday}}天后</span>{{item.etime}}
  200. </el-tag>
  201. </div>
  202. <el-button @click="createClass" size="small">生成任务表</el-button>
  203. <div style="padding: 5px 0">
  204. <div class="table-responsive" v-if="tasks.list.length > 0">
  205. <table class="table table-bordered ctable text-center">
  206. <tr>
  207. <td></td>
  208. <td v-for="(item,index) in tasks.days" :key="index">{{item}}</td>
  209. </tr>
  210. <tr v-for="(vo,idx) in tasks.list" :key="idx">
  211. <td>{{vo.time.stime}} ~ <span v-if="vo.time.stype == 1">{{vo.time.sday}}天后</span>{{vo.time.etime}}</td>
  212. <td v-for="(item,index) in tasks.days" :key="index">
  213. <template v-for="(v,id) in vo.list">
  214. <span v-if="item == v.day" :key="id">{{v.userNames}}</span>
  215. </template>
  216. </td>
  217. </tr>
  218. </table>
  219. </div>
  220. </div>
  221. </div>
  222. </div>
  223. </div>
  224. <div v-if="step == 2">
  225. <div style="padding: 5px 0">
  226. <div class="table-responsive" v-if="tasks.list.length > 0">
  227. <table class="table table-bordered ctable text-center">
  228. <tr>
  229. <td></td>
  230. <td></td>
  231. <td v-for="(item,index) in tasks.days" :key="index"><a href="javascript:;" @click="delDay(item)">删除列</a></td>
  232. </tr>
  233. <tr>
  234. <td></td>
  235. <td></td>
  236. <td v-for="(item,index) in tasks.days" :key="index">{{item}}</td>
  237. </tr>
  238. <tr v-for="(vo,idx) in tasks.list" :key="idx">
  239. <td><a href="javascript:;" @click="delTimes(vo.time)">删除行</a></td>
  240. <td>{{vo.time.stime}} ~ <span v-if="vo.time.stype == 1">{{vo.time.sday}}日后</span>{{vo.time.etime}}</td>
  241. <td v-for="(item,index) in tasks.days" :key="index">
  242. <template v-for="(v,id) in vo.list">
  243. <span v-if="item == v.day" :key="id">{{v.userNames}}</span>
  244. </template>
  245. </td>
  246. </tr>
  247. </table>
  248. </div>
  249. </div>
  250. </div>
  251. <div class="hr-line-dashed"></div>
  252. <div class="form-group">
  253. <div class="col-sm-6 col-sm-offset-2">
  254. <button v-if="step == 2" class="btn btn-primary" target-form="form-horizontal" type="button" id="saveSubmit" @click="saveSubmit">保 存</button>
  255. <button v-if="step == 1||step == 2" class="btn btn-default" type="button" @click="pre">上一步</button>
  256. <button v-if="step == 0||step == 1" class="btn btn-info" type="button" @click="next">下一步</button>
  257. </div>
  258. </div>
  259. </form>
  260. <el-dialog
  261. title="选择地点"
  262. :visible.sync="dialogVisibleAddr"
  263. width="500px"
  264. :before-close="handleClose"
  265. >
  266. <el-input
  267. placeholder="请输入"
  268. v-model="addrkeyword"
  269. @input="searchAddr"
  270. clearable>
  271. </el-input>
  272. <el-table
  273. ref="singleTable"
  274. :data="addrs"
  275. height="300"
  276. @selection-change="handleSelectionChangeAddr"
  277. style="width: 100%">
  278. <el-table-column
  279. type="selection"
  280. width="60">
  281. </el-table-column>
  282. <el-table-column
  283. property="title"
  284. label="名称"
  285. >
  286. </el-table-column>
  287. </el-table>
  288. <span slot="footer" class="dialog-footer">
  289. <el-button @click="dialogVisibleAddr = false">取 消</el-button>
  290. <el-button type="primary" @click="saveAddr">确 定</el-button>
  291. </span>
  292. </el-dialog>
  293. <el-dialog
  294. title="选择检查内容"
  295. :visible.sync="dialogVisibleForm"
  296. width="500px"
  297. :before-close="handleCloseForm"
  298. >
  299. <el-input
  300. placeholder="请输入"
  301. v-model="formkeyword"
  302. @input="searchForm"
  303. clearable>
  304. </el-input>
  305. <el-table
  306. v-if="dialogVisibleForm"
  307. ref="singleTable2"
  308. :data="forms"
  309. height="300"
  310. @selection-change="handleCurrentChange"
  311. style="width: 100%">
  312. <el-table-column
  313. type="selection"
  314. width="60">
  315. </el-table-column>
  316. <el-table-column
  317. property="title"
  318. label="名称"
  319. >
  320. </el-table-column>
  321. </el-table>
  322. <span slot="footer" class="dialog-footer">
  323. <el-button @click="handleCloseForm">取 消</el-button>
  324. <el-button type="primary" @click="saveForm">确 定</el-button>
  325. </span>
  326. </el-dialog>
  327. <el-dialog
  328. title="选择周"
  329. :visible.sync="dialogVisibleWeek"
  330. width="500px"
  331. :before-close="handleCloseWeek"
  332. >
  333. <div class="text-center">
  334. <el-tag
  335. style="margin-right: 5px;cursor: pointer"
  336. v-for="item in weeks"
  337. size="small"
  338. :key="item.id"
  339. :type="item.type"
  340. effect="dark"
  341. @click="handleWeek(item)"
  342. >
  343. {{ item.title }}
  344. </el-tag>
  345. </div>
  346. <span slot="footer" class="dialog-footer">
  347. <el-button @click="dialogVisibleWeek = false">取 消</el-button>
  348. <el-button type="primary" @click="saveWeek">确 定</el-button>
  349. </span>
  350. </el-dialog>
  351. <el-dialog
  352. title="时间段选择"
  353. :visible.sync="dialogVisibleTime"
  354. width="700px"
  355. :before-close="handleCloseTime"
  356. >
  357. <div style="padding: 5px 0">
  358. <el-tabs v-model="activeTabName">
  359. <el-tab-pane label="逐个添加" name="first"></el-tab-pane>
  360. <el-tab-pane label="批量添加" name="second"></el-tab-pane>
  361. </el-tabs>
  362. </div>
  363. <div style="padding: 5px 0">
  364. 选择时段:
  365. <span v-if="activeTabName === 'first'">
  366. <el-time-picker style="width:130px" v-model="stime" format="HH:mm" value-format="HH:mm" size="small" key="first01" placeholder="请选择时间"></el-time-picker>
  367. <el-select style="width:80px" v-model="stype" placeholder="请选择" size="small">
  368. <el-option label="今日" :value="0"></el-option>
  369. <el-option label="其他" :value="1"></el-option>
  370. </el-select>
  371. <el-input v-if="stype == 1" @input="changeSday" type="number" v-model="sday" size="small" style="width: 70px;" placeholder="天数"></el-input> 天后
  372. <el-time-picker style="width:130px" v-model="etime" format="HH:mm" value-format="HH:mm" size="small" key="first02" placeholder="请选择时间"></el-time-picker>
  373. <el-button @click="addTime" size="small">添加</el-button>
  374. </span>
  375. <span v-if="activeTabName === 'second'">
  376. <el-time-picker
  377. style="width:290px"
  378. is-range
  379. v-model="setime"
  380. key="second01"
  381. format="HH:mm"
  382. value-format="HH:mm"
  383. size="small"
  384. range-separator="至"
  385. start-placeholder="开始时间"
  386. end-placeholder="结束时间"
  387. placeholder="选择时间范围"
  388. ></el-time-picker>
  389. 每隔
  390. <el-input type="number" v-model="snums" size="small" style="width: 70px;" placeholder="天数"></el-input> 小时执行一次
  391. <el-button @click="addBatchTime" size="small">添加</el-button>
  392. </span>
  393. </div>
  394. <div style="padding: 5px 0">
  395. 已选择时间段:
  396. <el-tag
  397. style="margin-right: 5px;margin-bottom: 5px"
  398. size="small"
  399. :key="index"
  400. v-for="(item,index) in selTimes"
  401. closable
  402. @close="handleCloseTimes(item)">
  403. {{item.stime}} ~ <span v-if="item.stype == 1">{{item.sday}}天后</span>{{item.etime}}
  404. </el-tag>
  405. </div>
  406. <span slot="footer" class="dialog-footer">
  407. <el-button @click="dialogVisibleTime = false">取 消</el-button>
  408. <el-button type="primary" @click="saveTime">确 定</el-button>
  409. </span>
  410. </el-dialog>
  411. </div>
  412. </div>
  413. </div>
  414. </div>
  415. {/block}
  416. {block name="script"}
  417. <script>
  418. var ads = {:json_encode($address)};
  419. var frs = {:json_encode($patrolForm)};
  420. var us = {:json_encode($user)};
  421. var cateList = {:json_encode($cateList)};
  422. var mode = {$mode};
  423. {empty name="info"}
  424. var info = null;
  425. {else /}
  426. var info = {:json_encode($info)};
  427. {/empty}
  428. new Vue({
  429. el: '#vue-plan',
  430. data: function() {
  431. return {
  432. title: '',
  433. dialogVisible: false,
  434. step: 0,
  435. date: '',
  436. tableData: [],
  437. selAddrForms: [], // 选择的地址表单
  438. addrs: ads,
  439. selAddrs:[], // 选择地址
  440. dialogVisibleAddr: false,
  441. addrkeyword: '',
  442. forms: frs,
  443. selForm: [],
  444. formkeyword: '',
  445. dialogVisibleForm: false,
  446. users: us, // 人员列表
  447. userIds:[], // 选择的人员
  448. dateTypes: [
  449. {id: 1,title: '天'},
  450. {id: 2,title: '周'},
  451. {id: 4,title: '月'},
  452. {id: 3,title: '自定义'},
  453. ],
  454. dateType: 1,
  455. dateFrom: '', // 自定义类型从哪天开始
  456. datePlay: 1,
  457. datePause: 1,
  458. dateWeeks: [], // 已选择的周
  459. dateTimes: [], // 已添加的时间段
  460. weeks: [
  461. {id:1,title:'周一',type: 'info'},
  462. {id:2,title:'周二',type: 'info'},
  463. {id:3,title:'周三',type: 'info'},
  464. {id:4,title:'周四',type: 'info'},
  465. {id:5,title:'周五',type: 'info'},
  466. {id:6,title:'周六',type: 'info'},
  467. {id:0,title:'周日',type: 'info'},
  468. ],
  469. selWeeks: [],
  470. dialogVisibleWeek: false,
  471. dialogVisibleTime: false,
  472. stime: '',
  473. etime: '',
  474. stype: 0,
  475. sday: 1,
  476. selTimes: [], // 弹框已选的时间段
  477. tasks: { // 任务
  478. days: [],
  479. list: [],
  480. },
  481. activeTabName: 'first',
  482. setime: '',
  483. snums: 1,
  484. inOrder: 0,
  485. lines: [],
  486. cateList:cateList,
  487. cate:[],
  488. frs:frs
  489. }
  490. },
  491. watch: {
  492. cate: function (newVal, oldVal) {
  493. if(parseInt('{$mode}')==4) {
  494. var that = this;
  495. $.post('{:url("PatrolForm/getByCate")}', {id: newVal}, function (res) {
  496. that.frs = res.data;
  497. })
  498. }
  499. },
  500. addrIds() { // 以保存的地址id
  501. console.log('tableData',this.tableData);
  502. let lines = [];
  503. if(this.tableData.length >= 2){
  504. for (let i in this.tableData){
  505. if(i < this.tableData.length - 1){
  506. lines.push({
  507. s: this.tableData[i].addrId,
  508. st: this.tableData[i].addrTitle,
  509. e: this.tableData[Number(i)+1].addrId,
  510. et: this.tableData[Number(i)+1].addrTitle,
  511. kd: 0,
  512. fd: 0,
  513. })
  514. }
  515. }
  516. }
  517. this.lines = JSON.parse(JSON.stringify(lines));
  518. console.log('lines',this.lines);
  519. },
  520. },
  521. computed: {
  522. addrIds() { // 以保存的地址id
  523. let ids = [];
  524. this.tableData.forEach((item) => {
  525. ids.push(item.addrId);
  526. });
  527. return ids;
  528. },
  529. },
  530. created(){
  531. if(info){
  532. this.title = info.title;
  533. this.cate = info.cate_id;
  534. this.date = [info.start_time,info.end_time];
  535. this.tableData = info.content.addrForms;
  536. this.userIds = info.content.userIds;
  537. this.dateType = info.content.dateType;
  538. this.dateForm = info.content.dateForm;
  539. this.datePlay = info.content.datePlay;
  540. this.datePause = info.content.datePause;
  541. this.dateWeeks = info.content.dateWeeks;
  542. this.dateTimes = info.content.dateTimes;
  543. this.datePause = info.content.datePause;
  544. this.datePause = info.content.datePause;
  545. this.lines = info.lines;
  546. this.inOrder = info.in_order;
  547. }
  548. },
  549. methods: {
  550. next() {
  551. if(this.step == 0){ // 检查必填项
  552. if(!this.title){
  553. this.$message.error('请输入任务名称');
  554. return false;
  555. }
  556. if(!this.date){
  557. this.$message.error('请选择任务时间');
  558. return false;
  559. }
  560. if(this.tableData.length == 0){
  561. this.$message.error('请选择任务地点');
  562. return false;
  563. }
  564. let ff = false;
  565. this.tableData.forEach((item) => {
  566. if(item.forms.length == 0){
  567. ff = true;
  568. }
  569. });
  570. if(ff){
  571. this.$message.error('任务地点未配置检查内容');
  572. return false;
  573. }
  574. } else if(this.step == 1){
  575. if(this.userIds.length <= 0){
  576. this.$message.error('未设置人员');
  577. return false;
  578. }
  579. if(this.dateType == 2 && this.dateWeeks.length <= 0){ // 周
  580. this.$message.error('未选择周');
  581. return false;
  582. }
  583. if(this.dateTimes.length <= 0){
  584. this.$message.error('未选择时间段');
  585. return false;
  586. }
  587. if(this.dateType == 3){ // 自定义
  588. if(!this.dateFrom){
  589. this.$message.error('未选择自定义开始日期');
  590. return false;
  591. }
  592. if(this.datePlay <= 0){
  593. this.$message.error('任务天数必须大于0');
  594. return false;
  595. }
  596. if(this.datePause < 0){
  597. this.$message.error('暂停天数必须大于等于0');
  598. return false;
  599. }
  600. }
  601. // 重新生成任务
  602. this.createClass();
  603. }
  604. if (this.step++ > 2) this.step = 0;
  605. },
  606. pre() {
  607. if (this.step-- < 0) this.step = 2;
  608. },
  609. handleSelectionChange(val){
  610. this.selAddrForms = val;
  611. console.log('selAddrForms',this.selAddrForms);
  612. },
  613. handleClose(){
  614. this.dialogVisibleAddr = false;
  615. },
  616. handleSelectionChangeAddr(val){
  617. this.selAddrs = val;
  618. },
  619. selectAddr(){
  620. this.dialogVisibleAddr = true;
  621. this.addrkeyword = '';
  622. this.addrs = ads.filter((item) => {
  623. return !this.addrIds.includes(item.id);
  624. });
  625. this.selAddrs = [];
  626. },
  627. sortAddrs(){
  628. let ll = JSON.parse(JSON.stringify(this.tableData));
  629. ll.sort((a, b) => {
  630. return Number(a.sorts) > Number(b.sorts) ? 1 : -1;
  631. });
  632. console.log('ll',ll);
  633. this.tableData = [];
  634. this.$nextTick(() => {
  635. this.tableData = JSON.parse(JSON.stringify(ll));
  636. });
  637. },
  638. searchAddr(){
  639. this.addrs= [];
  640. this.$nextTick(() => {
  641. if(this.addrkeyword){
  642. this.addrs = ads.filter((item) => {
  643. return item.title.indexOf(this.addrkeyword) !== -1;
  644. });
  645. }else{
  646. this.addrs = ads;
  647. }
  648. });
  649. },
  650. saveAddr(){
  651. const tbs = this.tableData;
  652. this.selAddrs.forEach((item) => {
  653. if(!this.addrIds.includes(item.id)){
  654. tbs.push({
  655. 'addrId': item.id,
  656. 'addrTitle': item.title,
  657. 'forms': [],
  658. 'sorts': 0
  659. });
  660. }
  661. });
  662. this.dialogVisibleAddr = false;
  663. this.$nextTick(() => {
  664. this.tableData = tbs;
  665. });
  666. },
  667. moveUp(idx,obj){
  668. if(idx > 0){
  669. let old = JSON.parse(JSON.stringify(this.tableData[idx]));
  670. let up = JSON.parse(JSON.stringify(this.tableData[idx - 1]));
  671. let tbs = this.tableData;
  672. this.tableData = [];
  673. this.$nextTick(() => {
  674. tbs[idx] = up;
  675. tbs[idx - 1] = old;
  676. this.tableData = tbs;
  677. })
  678. }
  679. },
  680. moveDown(idx,obj){ // 下移
  681. let length = this.tableData.length;
  682. if(idx < length - 1){
  683. let old = JSON.parse(JSON.stringify(this.tableData[idx]));
  684. let up = JSON.parse(JSON.stringify(this.tableData[idx + 1]));
  685. let tbs = this.tableData;
  686. this.tableData = [];
  687. this.$nextTick(() => {
  688. tbs[idx] = up;
  689. tbs[idx + 1] = old;
  690. this.tableData = tbs;
  691. })
  692. }
  693. },
  694. delAddrs(){ // 移除
  695. let sids = [];
  696. this.selAddrForms.forEach((item) => {
  697. sids.push(item.addrId);
  698. });
  699. if(sids.length == 0){
  700. this.$message.error('未选择地点');
  701. return false;
  702. }
  703. let tbs = this.tableData;
  704. this.tableData = [];
  705. this.$nextTick(() => {
  706. this.tableData = tbs.filter((item) => {
  707. return !sids.includes(item.addrId);
  708. });
  709. this.selAddrForms = [];
  710. });
  711. },
  712. handleCurrentChange(val){ // 选中检查内容
  713. this.selForm = val;
  714. },
  715. handleCloseForm(){
  716. this.dialogVisibleForm = false;
  717. },
  718. searchForm(){
  719. this.forms= [];
  720. this.$nextTick(() => {
  721. if(this.formkeyword){
  722. this.forms = this.frs.filter((item) => {
  723. return item.title.indexOf(this.formkeyword) !== -1;
  724. });
  725. }else{
  726. this.forms = this.frs;
  727. }
  728. });
  729. },
  730. saveForm(){
  731. const tbs = this.tableData;
  732. this.tableData = [];
  733. let sids = [];
  734. this.selAddrForms.forEach((item) => {
  735. sids.push(item.addrId);
  736. });
  737. tbs.forEach((item) => {
  738. if(sids.includes(item.addrId)){
  739. // item.formId = this.selForm?this.selForm.id:0;
  740. // item.formTitle = this.selForm?this.selForm.title:'';
  741. const ffs = [];
  742. this.selForm.forEach((fitem) => {
  743. ffs.push({
  744. id: fitem.id,
  745. title: fitem.title
  746. });
  747. });
  748. item.forms = JSON.parse(JSON.stringify(ffs));
  749. }
  750. });
  751. this.dialogVisibleForm = false;
  752. this.$nextTick(() => {
  753. this.tableData = tbs;
  754. this.selAddrForms = [];
  755. });
  756. },
  757. selectForm(){
  758. let sids = [];
  759. this.selAddrForms.forEach((item) => {
  760. sids.push(item.addrId);
  761. });
  762. if(sids.length == 0){
  763. this.$message.error('未选择地点');
  764. return false;
  765. }
  766. console.log('ss',this.selAddrForms);
  767. this.dialogVisibleForm = true;
  768. this.forms = this.frs;
  769. this.selForm = null;
  770. },
  771. handleCloseWeek(){
  772. this.dialogVisibleWeek = false;
  773. },
  774. saveWeek(){
  775. let ll = [];
  776. this.weeks.forEach((item) => {
  777. if(this.selWeeks.includes(item.id)){
  778. ll.push({
  779. id: item.id,
  780. title: item.title,
  781. type: 'primary'
  782. })
  783. }
  784. });
  785. this.dateWeeks = ll;
  786. this.dialogVisibleWeek = false;
  787. },
  788. handleWeek(obj){
  789. console.log(obj);
  790. if(this.selWeeks.includes(obj.id)){
  791. this.selWeeks = this.selWeeks.filter((item) => {
  792. return item !== obj.id;
  793. });
  794. }else{
  795. this.selWeeks.push(obj.id);
  796. }
  797. this.weeks.forEach((item) => {
  798. if(this.selWeeks.includes(item.id)){
  799. item.type = 'primary';
  800. }else{
  801. item.type = 'info';
  802. }
  803. });
  804. },
  805. selectWeek(){
  806. this.selWeeks = [];
  807. this.dateWeeks.forEach((item) => {
  808. this.selWeeks.push(item.id);
  809. });
  810. this.weeks.forEach((item) => {
  811. if(this.selWeeks.includes(item.id)){
  812. item.type = 'primary';
  813. }else{
  814. item.type = 'info';
  815. }
  816. });
  817. this.dialogVisibleWeek = true;
  818. },
  819. handleCloseTime(){
  820. this.dialogVisibleTime = false;
  821. },
  822. addTime(){
  823. if(!this.stime || !this.etime){
  824. this.$message.error('请选择时间段');
  825. return false;
  826. }
  827. if(this.stype == 0 && this.stime >= this.etime){
  828. this.$message.error('时间段错误');
  829. return false;
  830. }
  831. if(this.stype == 1 && this.sday < 1){
  832. this.$message.error('天数必须大于0');
  833. return false;
  834. }
  835. // 检查时间段是否重复
  836. let ff = false;
  837. this.selTimes.forEach((item) => {
  838. if(item.stype == this.stype &&item.sday == this.sday && item.stime == this.stime && item.etime == this.etime){
  839. ff = true;
  840. }
  841. });
  842. if(ff){
  843. this.$message.error('该时间段已存在');
  844. return false;
  845. }
  846. this.selTimes.push({
  847. stime: this.stime,
  848. etime: this.etime,
  849. stype: this.stype,
  850. sday: this.sday
  851. })
  852. },
  853. addBatchTime(){
  854. if(!this.setime || this.setime.length !== 2){
  855. this.$message.error('请选择时间段');
  856. return false;
  857. }
  858. if(this.snums <= 0){
  859. this.$message.error('请输入间隔小时数');
  860. return false;
  861. }
  862. // let min = 0;
  863. // let max = 23*50 + 59;
  864. let st = this.timeToNum(this.setime[0]);
  865. let et = this.timeToNum(this.setime[1]);
  866. let times = [];
  867. let start = this.timeToNum(this.setime[0]);
  868. let end = this.timeToNum(this.setime[0]);
  869. let i = 1;
  870. while (true){
  871. end = this.timeToNum(this.setime[0]) + 60*this.snums*i;
  872. let jg = et - start;
  873. if(end > et && jg < 10){
  874. break;
  875. }else if(end > et && jg > 10){
  876. end = et;
  877. }
  878. this.stime = this.numToTime(start);
  879. this.etime = this.numToTime(end);
  880. this.stype = 0;
  881. this.sday = 0;
  882. // 检查时间段是否重复
  883. let ff = false;
  884. this.selTimes.forEach((item) => {
  885. if(item.stype == this.stype &&item.sday == this.sday && item.stime == this.stime && item.etime == this.etime){
  886. ff = true;
  887. }
  888. });
  889. if(ff){
  890. this.$message.error('该时间段已存在');
  891. return false;
  892. }
  893. this.selTimes.push({
  894. stime: this.stime,
  895. etime: this.etime,
  896. stype: this.stype,
  897. sday: this.sday
  898. });
  899. start = this.timeToNum(this.setime[0]) + 60*this.snums*i;
  900. i++;
  901. }
  902. console.log('this.selTimes',this.selTimes);
  903. },
  904. timeToNum(time){ // time格式12:30
  905. let ts = time.split(':');
  906. if(ts.length !== 2){
  907. return 0;
  908. }
  909. return Number(ts[0])*60 + Number(ts[1]);
  910. },
  911. numToTime(num){ // 数字转时间
  912. let h = parseInt(num/60);
  913. let m = num - h*60;
  914. let str = '';
  915. if(h < 10){
  916. str += '0' + h + ':';
  917. }else{
  918. str += h + ':';
  919. }
  920. if(m < 10){
  921. str += '0' + m;
  922. }else{
  923. str += m;
  924. }
  925. return str;
  926. },
  927. saveTime(){
  928. this.dateTimes = JSON.parse(JSON.stringify(this.selTimes));
  929. this.handleCloseTime();
  930. },
  931. handleCloseTimes(obj){
  932. this.selTimes = this.selTimes.filter((item) => {
  933. return item.stime != obj.stime || item.etime != obj.etime || item.stype != obj.stype || item.sday != obj.sday;
  934. })
  935. },
  936. selectTime(){
  937. this.dialogVisibleTime = true;
  938. this.selTimes = JSON.parse(JSON.stringify(this.dateTimes));
  939. this.stime = '';
  940. this.etime = '';
  941. this.stype = 0;
  942. this.sday = 1;
  943. },
  944. changeSday(){
  945. if (this.sday) {
  946. // 限制整数
  947. this.sday = this.sday.replace(/[^\d]/g, '');
  948. }
  949. },
  950. createClass(){
  951. if(this.userIds.length <= 0){
  952. this.$message.error('未设置人员');
  953. return false;
  954. }
  955. if(this.dateType == 2 && this.dateWeeks.length <= 0){ // 周
  956. this.$message.error('未选择周');
  957. return false;
  958. }
  959. if(this.dateTimes.length <= 0){
  960. this.$message.error('未选择时间段');
  961. return false;
  962. }
  963. if(this.dateType == 3){ // 自定义
  964. if(!this.dateFrom){
  965. this.$message.error('未选择自定义开始日期');
  966. return false;
  967. }
  968. if(this.datePlay <= 0){
  969. this.$message.error('任务天数必须大于0');
  970. return false;
  971. }
  972. if(this.datePause < 0){
  973. this.$message.error('暂停天数必须大于等于0');
  974. return false;
  975. }
  976. }
  977. let days = this.formatDays();
  978. this.formatTasks(days);
  979. },
  980. formatTasks(days){
  981. this.tasks = {
  982. days: days,
  983. list: [],
  984. };
  985. let list = [];
  986. this.dateTimes.forEach((item) => {
  987. let ts = [];
  988. days.forEach((item2) => {
  989. ts.push({
  990. day: item2,
  991. userIds: this.userIds,
  992. userNames: this.getUserNames(),
  993. });
  994. });
  995. list.push({
  996. time: item,
  997. list: ts,
  998. })
  999. });
  1000. this.tasks = {
  1001. days: days,
  1002. list: list,
  1003. };
  1004. console.log('tasks',this.tasks);
  1005. },
  1006. delDay(day){ // 删除列
  1007. let ts = JSON.parse(JSON.stringify(this.tasks));
  1008. this.tasks = null;
  1009. let days = ts.days.filter((item) => {
  1010. return item != day;
  1011. });
  1012. this.formatTasks(days);
  1013. },
  1014. delTimes(obj){ // 删除行
  1015. let days = JSON.parse(JSON.stringify(this.tasks.days));
  1016. this.tasks = null;
  1017. this.dateTimes = this.dateTimes.filter((item) => {
  1018. return item.stime != obj.stime || item.etime != obj.etime || item.stype != obj.stype || item.sday != obj.sday;
  1019. });
  1020. this.formatTasks(days);
  1021. },
  1022. saveSubmit(){ // 表单提交
  1023. if(this.tasks.days.length <= 0||this.tasks.list.length <= 0){
  1024. this.$message.error('未设置任务');
  1025. return false;
  1026. }
  1027. let content = {
  1028. addrForms: this.tableData,
  1029. userIds: this.userIds,
  1030. dateType: this.dateType,
  1031. dateFrom: this.dateType == 3?this.dateFrom:'',
  1032. datePlay: this.dateType == 3?this.datePlay:0,
  1033. datePause: this.dateType == 3?this.datePause:0,
  1034. dateWeeks: this.dateType == 2?this.dateWeeks:[],
  1035. dateTimes: this.dateTimes,
  1036. tasks: this.tasks,
  1037. };
  1038. let json = {
  1039. title: this.title,
  1040. start_time: this.date[0],
  1041. end_time: this.date[1],
  1042. content: JSON.stringify(content),
  1043. mode: mode,
  1044. cate_id: this.cate,
  1045. id:'{$id}',
  1046. in_order: this.inOrder,
  1047. lines: this.lines.length > 0?JSON.stringify(this.lines):''
  1048. };
  1049. let that = this;
  1050. $('#saveSubmit').attr("disabled", true).html('保 存 中');
  1051. $.ajax({
  1052. url: "{:url('PatrolPlan/add')}",
  1053. type: 'POST',
  1054. data: json,
  1055. success: function(ret){
  1056. if(ret.code == 1){
  1057. that.$message.success('操作成功');
  1058. parent.layer.closeAll();
  1059. }else{
  1060. that.$message.error(ret.msg);
  1061. }
  1062. $('#saveSubmit').attr("disabled", false).html('保 存');
  1063. },
  1064. error: function (){
  1065. that.$message.error('请求失败');
  1066. $('#saveSubmit').attr("disabled", false).html('保 存');
  1067. }
  1068. });
  1069. },
  1070. getUserNames(){
  1071. let ns = [];
  1072. this.userIds.forEach((item) => {
  1073. this.users.forEach((item2) => {
  1074. if(item2.id == item){
  1075. ns.push(item2.title);
  1076. }
  1077. });
  1078. });
  1079. return ns.join(',');
  1080. },
  1081. formatDays(){ // 格式化任务日期
  1082. let days = this.getDateAll(this.date[0],this.date[1]);
  1083. let nday = [];
  1084. let ws = [];
  1085. this.dateWeeks.forEach((item) => {
  1086. ws.push(item.id);
  1087. });
  1088. let i = 0;
  1089. let j = 0;
  1090. if(this.dateType==4){
  1091. days = this.dateCutByMonth(this.date[0],this.date[1]);
  1092. }
  1093. days.forEach((item) => {
  1094. if(this.dateType == 1){ // 日
  1095. nday.push(item);
  1096. }else if(this.dateType == 2){ // 周
  1097. let ww = this.getWeekByDay(item);
  1098. if(ws.includes(ww)){
  1099. nday.push(item);
  1100. }
  1101. }else if(this.dateType == 3){ // 自定义
  1102. if(this.dateFrom <= item){
  1103. if(i + j < this.datePlay){
  1104. nday.push(item);
  1105. i++;
  1106. }else if((i + j) >= this.datePlay && (i+j) < this.datePause){
  1107. j++;
  1108. }else{
  1109. i = 0;
  1110. j = 0;
  1111. }
  1112. }
  1113. }else if(this.dateType == 4){ // 月
  1114. nday.push(item);
  1115. }
  1116. });
  1117. return nday;
  1118. },
  1119. changePlay(){
  1120. if (this.datePlay) {
  1121. // 限制整数
  1122. this.datePlay = this.datePlay.replace(/[^\d]/g, '');
  1123. }
  1124. },
  1125. changePause(){
  1126. if (this.datePause) {
  1127. // 限制整数
  1128. this.datePause = this.datePause.replace(/[^\d]/g, '');
  1129. }
  1130. },
  1131. getDateAll(starDay, endDay) { // 获取两个时间段的所有日期
  1132. var arr = [];
  1133. var dates = [];
  1134. // 设置两个日期UTC时间
  1135. var db = new Date(starDay);
  1136. var de = new Date(endDay);
  1137. // 获取两个日期GTM时间
  1138. var s = db.getTime() - 24 * 60 * 60 * 1000;
  1139. var d = de.getTime() - 24 * 60 * 60 * 1000;
  1140. // 获取到两个日期之间的每一天的毫秒数
  1141. for (var i = s; i <= d; ) {
  1142. i = i + 24 * 60 * 60 * 1000;
  1143. arr.push(parseInt(i));
  1144. }
  1145. // 获取每一天的时间 YY-MM-DD
  1146. for (var j in arr) {
  1147. var time = new Date(arr[j]);
  1148. var year = time.getFullYear(time);
  1149. var mouth =
  1150. time.getMonth() + 1 >= 10
  1151. ? time.getMonth() + 1
  1152. : "0" + (time.getMonth() + 1);
  1153. var day =
  1154. time.getDate() >= 10
  1155. ? time.getDate()
  1156. : "0" + time.getDate();
  1157. var YYMMDD = year + "-" + mouth + "-" + day;
  1158. dates.push(YYMMDD);
  1159. }
  1160. return dates;
  1161. },
  1162. getWeekByDay(dateString,t=0) { // 获取某天是周几
  1163. var dateArray = dateString.split("-");
  1164. date = new Date(dateArray[0], parseInt(dateArray[1] - 1), dateArray[2]);
  1165. if(t == 1){
  1166. return "周" + "日一二三四五六".charAt(date.getDay());
  1167. }else{
  1168. return date.getDay();
  1169. }
  1170. },
  1171. dateCutByMonth(beginDate, endDate) {
  1172. //分割好的数组
  1173. var dateCutList = new Array();
  1174. var b_date = new Date(beginDate);
  1175. var e_date = new Date(endDate);
  1176. //获取各个的年份
  1177. var b_year = parseInt(b_date.getFullYear());
  1178. var e_year = parseInt(e_date.getFullYear());
  1179. //获取各个的月份
  1180. var b_month = parseInt(b_date.getMonth()) + 1;
  1181. var e_month = parseInt(e_date.getMonth()) + 1;
  1182. //获取日期之间想差的月数;
  1183. var month_list = this.monthList();
  1184. //按月份分割日期
  1185. if(month_list.length==1){
  1186. dateCutList.push(beginDate+'~'+endDate);
  1187. }else {
  1188. for (var i = 0; i < month_list.length; i++) {
  1189. //当前月开始日期:第一天
  1190. var i_b_date = new Date(month_list[i]);
  1191. i_b_date.setDate(1);
  1192. //当前月最后一天
  1193. var i_e_date = new Date(month_list[i]);
  1194. i_e_date.setMonth(i_e_date.getMonth() + 1);
  1195. i_e_date.setDate(1);
  1196. i_e_date.setDate(i_e_date.getDate() - 1);
  1197. //第一次循环:开始月份
  1198. if (i == 0) {
  1199. var i_e_ymd = this.parseTime(i_e_date).split(" ")[0];
  1200. dateCutList.push(beginDate+'~'+i_e_ymd);
  1201. //除第一次和最后一次循环:中间月份
  1202. } else if (i != 0 && i != month_list.length - 1) {
  1203. var i_b_ymd = this.parseTime(i_b_date).split(" ")[0];
  1204. var i_e_ymd = this.parseTime(i_e_date).split(" ")[0];
  1205. dateCutList.push(i_b_ymd+'~'+i_e_ymd);
  1206. // //最后一次循环:结束月份
  1207. } else if (i == month_list.length - 1) {
  1208. var i_b_ymd = this.parseTime(i_b_date).split(" ")[0];
  1209. dateCutList.push(i_b_ymd+'~'+endDate);
  1210. }
  1211. }
  1212. }
  1213. return dateCutList;
  1214. },
  1215. monthList() {
  1216. //相差的月份总数
  1217. var result = new Array();
  1218. var b_date = new Date(this.date[0]);
  1219. var e_date = new Date(this.date[1]);
  1220. //获取各个的年份
  1221. var b_year = parseInt(b_date.getFullYear());
  1222. var e_year = parseInt(e_date.getFullYear());
  1223. //获取各个的月份
  1224. var b_month = parseInt(b_date.getMonth()) + 1;
  1225. var e_month = parseInt(e_date.getMonth()) + 1;
  1226. var b = new Date(b_year, b_month - 1, 1);
  1227. var e = new Date(e_year, e_month - 1, 1);
  1228. while (b < e) {
  1229. result.push(b.getFullYear() + "-" + (b.getMonth() + 1));
  1230. b.setMonth(b.getMonth() + 1);
  1231. }
  1232. result.push(e_year + "-" + e_month);
  1233. return result;
  1234. },
  1235. parseTime(time, pattern) {
  1236. if (arguments.length === 0 || !time) {
  1237. return null
  1238. }
  1239. const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  1240. let date
  1241. if (typeof time === 'object') {
  1242. date = time
  1243. } else {
  1244. if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
  1245. time = parseInt(time)
  1246. } else if (typeof time === 'string') {
  1247. time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm),'');
  1248. }
  1249. if ((typeof time === 'number') && (time.toString().length === 10)) {
  1250. time = time * 1000
  1251. }
  1252. date = new Date(time)
  1253. }
  1254. const formatObj = {
  1255. y: date.getFullYear(),
  1256. m: date.getMonth() + 1,
  1257. d: date.getDate(),
  1258. h: date.getHours(),
  1259. i: date.getMinutes(),
  1260. s: date.getSeconds(),
  1261. a: date.getDay()
  1262. }
  1263. const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
  1264. let value = formatObj[key]
  1265. // Note: getDay() returns 0 on Sunday
  1266. if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
  1267. if (result.length > 0 && value < 10) {
  1268. value = '0' + value
  1269. }
  1270. return value || 0
  1271. })
  1272. return time_str
  1273. }
  1274. }
  1275. })
  1276. </script>
  1277. {/block}