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