editask.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. <template>
  2. <div class="editaskBox">
  3. <van-nav-bar :title="title" left-text="返回" @click-left="back" fixed left-arrow />
  4. <div class="content">
  5. <van-form>
  6. <div v-if="showOrNot">
  7. <van-cell title="所属项目" :value="select_project" @click="select_project_show = true,select_project_show_searchText = '',onSearchProject()"></van-cell>
  8. <van-popup v-model="select_project_show" position="bottom">
  9. <van-search v-model.trim="select_project_show_searchText" placeholder="输入项目名称搜索" @input="onSearchProject"></van-search>
  10. <div style="minHeight:300px;">
  11. <van-radio-group v-model="taskform.projectId">
  12. <van-radio v-for="uitem in select_project_array" :key="uitem.id" :name="uitem" style="padding:10px">
  13. <span>{{uitem.projectName}}</span>
  14. </van-radio>
  15. </van-radio-group>
  16. <van-button style="width:100%;position: -webkit-sticky;position: sticky;bottom: 0;" @click="selectProject()">确定</van-button>
  17. </div>
  18. </van-popup>
  19. <van-cell title="所属任务分组" :value="select_grouping" @click="select_grouping_show = true"></van-cell>
  20. <van-popup v-model="select_grouping_show" position="bottom">
  21. <van-picker
  22. show-toolbar
  23. :columns="select_grouping_array"
  24. @confirm="selectGrouping"
  25. @cancel="select_grouping_show = false;$forceUpdate();">
  26. <template #option="item">
  27. {{item.name}}
  28. </template>
  29. </van-picker>
  30. </van-popup>
  31. <van-cell title="所属任务列表" :value="select_list" @click="select_list_show = true"></van-cell>
  32. <van-popup v-model="select_list_show" position="bottom">
  33. <van-picker
  34. show-toolbar
  35. :columns="select_list_array"
  36. @confirm="selectList"
  37. @cancel="select_list_show = false;$forceUpdate();">
  38. <template #option="item">
  39. {{item.stagesName}}
  40. </template>
  41. </van-picker>
  42. </van-popup>
  43. </div>
  44. <!-- 类型 -->
  45. <van-field v-model="taskform.taskType" label="类型" @click="taskType.show = true" readonly clickable>
  46. <template #input><span>{{taskType.list[taskform.taskType]}}</span></template>
  47. </van-field>
  48. <van-popup v-model="taskType.show" position="bottom" v-if="canEdit">
  49. <van-picker
  50. show-toolbar
  51. :columns="taskType.list"
  52. @confirm="tasktypeChange"
  53. @cancel="taskType.show = false;$forceUpdate();"/>
  54. </van-popup>
  55. <!-- 任务内容 -->
  56. <van-field v-model="taskform.name" label="任务内容" placeholder="请输入任务内容" :rules="[{ required: true, message: '请输入任务内容' }]" type="textarea" :disabled="!canEdit" :maxlength="40" show-word-limit></van-field>
  57. <!-- 开始时间 -->
  58. <van-field v-if="taskform.type != 1" v-model="taskform.startDate" label="开始时间" placeholder="请选择开始时间" @click="startDateShow = true" readonly clickable></van-field>
  59. <van-popup v-model="startDateShow" position="bottom" v-if="canEdit">
  60. <van-datetime-picker
  61. type="date"
  62. title="选择开始时间"
  63. v-model="currentDate1"
  64. @confirm="startDateChange"
  65. @cancel="startDateShow = false;$forceUpdate();"
  66. :min-date="minDate"
  67. :max-date="maxDate"/>
  68. </van-popup>
  69. <!-- 截止时间 -->
  70. <van-field v-model="taskform.endDate" label="截止时间" placeholder="请选择截止时间" @click="endDateShow = true" readonly clickable></van-field>
  71. <van-popup v-model="endDateShow" position="bottom" v-if="canEdit">
  72. <van-datetime-picker
  73. type="date"
  74. title="选择截止时间"
  75. v-model="currentDate2"
  76. @confirm="endDateChange"
  77. @cancel="endDateShow = false;$forceUpdate();"
  78. :min-date="minDate"
  79. :max-date="maxDate"/>
  80. </van-popup>
  81. <!-- 完成时间 -->
  82. <van-field v-if="taskform.type == 1" v-model="taskform.finishDate" label="完成时间" placeholder="请选择完成时间" @click="finishDateShow = true" readonly clickable></van-field>
  83. <van-popup v-model="finishDateShow" position="bottom" v-if="canEdit">
  84. <van-datetime-picker
  85. type="date"
  86. title="选择完成时间"
  87. v-model="currentDate3"
  88. @confirm="finishDateChange"
  89. @cancel="finishDateShow = false;$forceUpdate();"
  90. :min-date="minDate"
  91. :max-date="maxDate"/>
  92. </van-popup>
  93. <!-- 执行人 -->
  94. <div style="border: 0.5px solid #87c3ff;margin:0.2rem;position:relative" v-for="item,index in taskform.executorList" :key="index">
  95. <van-field v-model="item.executorName" :label="'执行人' + (index + 1)" placeholder="请选择执行人" @click="executorChange(item,index)" readonly clickable>
  96. <template #input>
  97. <span v-if="!item.executorName"></span>
  98. <span v-else-if="user.userNameNeedTranslate != 1">{{item.executorName}}</span>
  99. <span v-else><ww-open-data type='userName' :openid='item.executorName'></ww-open-data></span>
  100. </template>
  101. </van-field>
  102. <van-field label="计划工时">
  103. <template #input>
  104. <van-stepper v-model="item.planHours" :disabled="!canEdit"/><span>{{'\u3000h'}}</span>
  105. </template>
  106. </van-field>
  107. <van-icon v-if="index != 0 && canEdit" class="delete_executor" name="delete-o" @click.stop="deleteExecutor(index)" />
  108. </div>
  109. <van-popup v-model="executor.show" position="bottom" v-if="canEdit">
  110. <van-search v-model="executor.searchText" placeholder="输入员工姓名搜索" @input="onSearch"></van-search>
  111. <div style="minHeight:300px;">
  112. <van-radio-group v-model="executor.item">
  113. <van-radio v-for="uitem in executor.searchList" :key="uitem.id" :name="uitem" style="padding:10px">
  114. <span v-if="user.userNameNeedTranslate != 1">{{uitem.name}}</span>
  115. <span v-else><ww-open-data type='userName' :openid='uitem.name'></ww-open-data></span>
  116. <span class="xinmingghao">{{uitem.jobNumber}}</span>
  117. </van-radio>
  118. </van-radio-group>
  119. <van-button style="width:100%;position: -webkit-sticky;position: sticky;bottom: 0;" @click="searchExecutor()">确定</van-button>
  120. </div>
  121. </van-popup>
  122. <!-- 添加执行人 -->
  123. <div class="add_executor" @click="addExecutor" v-if="canEdit">添加执行人</div>
  124. <!-- 优先级 -->
  125. <van-field v-model="taskform.taskLevel" label="优先级" @click="taskLevel.show = true" readonly clickable>
  126. <template #input><span>{{taskLevel.list[taskform.taskLevel]}}</span></template>
  127. </van-field>
  128. <van-popup v-model="taskLevel.show" position="bottom" v-if="canEdit">
  129. <van-picker
  130. show-toolbar
  131. :columns="taskLevel.list"
  132. @confirm="taskLevelChange"
  133. @cancel="taskLevel.show = false;$forceUpdate();"/>
  134. </van-popup>
  135. <van-cell title="任务描述"/>
  136. <vue-html5-editor :content="taskform.taskDesc" :height="300" @change="htmleditor"></vue-html5-editor>
  137. </van-form>
  138. <div class="form_btn" style="position:fixed; bottom:0px;width:100%;z-index: 99">
  139. <div style="padding-bottom:10px;">
  140. <van-button square block type="info" loading-text="保存中..." @click="submitTask" native-type="submit" :loading="submitTaskBtn" style="width:100%;float:left;" :disabled="!canEdit">
  141. <div v-if="canEdit">保存</div>
  142. <div v-else>暂无权限编辑</div>
  143. </van-button>
  144. </div>
  145. </div>
  146. </div>
  147. </div>
  148. </template>
  149. <script>
  150. export default {
  151. data() {
  152. return {
  153. showOrNot: false,
  154. title: '编辑任务',
  155. user: JSON.parse(localStorage.userInfo),
  156. taskId: JSON.parse(sessionStorage.taskId),
  157. currentDate1: new Date(),
  158. currentDate2: new Date(),
  159. currentDate3: new Date(),
  160. minDate: new Date(2020,0,1),
  161. maxDate: new Date(2025,11,31),
  162. canEdit: true,
  163. onSearchTime: null,
  164. taskform:{ // 表单
  165. taskType: 0,
  166. name: '',
  167. startDate: null,
  168. endDate: null,
  169. finishDate: null,
  170. taskLevel: 0,
  171. executorList: [{executorName: '',executorId: '',planHours: 8}],
  172. },
  173. taskType:{
  174. show: false,
  175. list: ['任务','里程碑','风险']
  176. },
  177. startDateShow: false,
  178. endDateShow: false,
  179. finishDateShow: false,
  180. submitTaskBtn: false,
  181. taskLevel:{
  182. show: false,
  183. list: ['一般','重要','紧急']
  184. },
  185. executor:{
  186. show: false,
  187. item: {id:null,name:''},
  188. index: 0,
  189. list: [],
  190. searchList: [],
  191. searchText: ''
  192. },
  193. select_project_show: false,
  194. select_grouping_show: false,
  195. select_list_show: false,
  196. select_project: '请选择',
  197. select_grouping: '请选择',
  198. select_list: '请选择',
  199. select_project_array: [],
  200. select_project_array_tow: [],
  201. select_grouping_array: [],
  202. select_list_array: [],
  203. select_project_show_searchText: ''
  204. }
  205. },
  206. mounted() {
  207. this.showOrNot = this.taskId.showOrNot
  208. this.getProjectList()
  209. if(!this.taskId.addNew){
  210. this.title = '编辑任务'
  211. this.getTask()
  212. }else{
  213. this.title = '新建任务'
  214. this.taskform = {
  215. projectId: '',
  216. groupId: '',
  217. stagesId: '',
  218. taskType: 0,
  219. name: '',
  220. startDate: null,
  221. endDate: null,
  222. finishDate: null,
  223. taskDesc: '',
  224. taskLevel: 0,
  225. executorList: [{executorName: '',executorId: '',planHours: this.user.timeType.allday}]
  226. }
  227. if(!this.taskId.showOrNot) {
  228. this.taskform.groupId = this.taskId.groupId
  229. this.taskform.stagesId = this.taskId.stagesId
  230. this.taskform.projectId = JSON.parse(sessionStorage.projectId)
  231. }
  232. }
  233. this.getUsersList()
  234. console.log('mounted',this.taskId,null);
  235. },
  236. methods: {
  237. selectProject(value,key) {
  238. this.select_project = this.taskform.projectId.projectName
  239. this.taskform.projectId = this.taskform.projectId.id
  240. console.log(this.taskform)
  241. this.getTaskGrouping()
  242. this.select_project_show_searchText = ''
  243. this.select_project_show = false
  244. this.select_list = ''
  245. this.select_grouping = ''
  246. this.taskform.groupId = ''
  247. this.taskform.stagesId = ''
  248. },
  249. selectGrouping(value){
  250. this.select_grouping = value.name
  251. this.taskform.groupId = value.id
  252. this.getStageList()
  253. this.select_grouping_show = false
  254. this.select_list = ''
  255. this.taskform.stagesId = ''
  256. },
  257. selectList(value) {
  258. console.log(value)
  259. this.select_list = value.stagesName
  260. this.taskform.stagesId = value.id
  261. this.select_list_show = false
  262. },
  263. onSearchProject() {
  264. let text = this.select_project_show_searchText
  265. if(text != '') {
  266. let projectArr = this.select_project_array_tow
  267. var arr = []
  268. for(var i in projectArr) {
  269. if(projectArr[i].projectName.indexOf(text) != '-1') {
  270. arr.push(projectArr[i])
  271. }
  272. }
  273. this.select_project_array = arr
  274. } else {
  275. this.select_project_array = this.select_project_array_tow
  276. }
  277. },
  278. getProjectList() {
  279. this.$axios.post("/project/getProjectList", {})
  280. .then(res => {
  281. if(res.code == "ok") {
  282. this.select_project_array = res.data
  283. this.select_project_array_tow = res.data
  284. } else {
  285. this.$toast.fail('失败');
  286. }
  287. }).catch(err=> {this.$toast.clear();console.log(err)});
  288. },
  289. getTaskGrouping() {
  290. this.$axios.post("/task-group/list", {projectId:this.taskform.projectId})
  291. .then(res => {
  292. if(res.code == "ok") {
  293. this.select_grouping_array = res.data
  294. } else {
  295. this.$toast.fail('失败');
  296. }
  297. }).catch(err=> {this.$toast.clear();console.log(err)});
  298. },
  299. getStageList() {
  300. this.$axios.post("/stages/list", {
  301. projectId: this.taskform.projectId,
  302. groupId: this.taskform.groupId,
  303. order: 'seq',
  304. isDesc: false
  305. })
  306. .then(res => {
  307. if(res.code == "ok") {
  308. this.select_list_array = res.data.list
  309. } else {
  310. this.$toast.fail('失败');
  311. }
  312. }).catch(err=> {this.$toast.clear();console.log(err)});
  313. },
  314. back() {
  315. history.back();
  316. },
  317. formatDate(date) {
  318. let mon = date.getMonth() + 1
  319. return `${date.getFullYear()}-${mon<10?'0'+mon:mon}-${date.getDate()<10?'0'+date.getDate():date.getDate()}`;
  320. },
  321. tasktypeChange(value,key){ // 类型
  322. this.taskform.taskType = key
  323. this.taskType.show = false
  324. },
  325. startDateChange(date){ // 开始时间
  326. this.taskform.startDate = this.formatDate(date)
  327. this.startDateShow = false
  328. },
  329. endDateChange(date){ // 截止时间
  330. this.taskform.endDate = this.formatDate(date)
  331. this.endDateShow = false
  332. },
  333. finishDateChange(date){ // 完成时间
  334. this.taskform.finishDate = this.formatDate(date)
  335. this.finishDateShow = false
  336. },
  337. executorChange(item,index){ // 选择执行人
  338. this.executor.show = true
  339. this.executor.index = index
  340. this.executor.searchList.forEach(u=>{if (u.id == item.executorId) {
  341. this.executor.item = u
  342. }})
  343. },
  344. deleteExecutor(index){
  345. console.log('deleteExecutor');
  346. this.taskform.executorList.splice(index,1)
  347. this.$forceUpdate();
  348. },
  349. addExecutor(){
  350. console.log('addExecutor');
  351. this.taskform.executorList.push({
  352. executorName: '',
  353. executorId: '',
  354. planHours: this.user.timeType.allday
  355. })
  356. this.$forceUpdate();
  357. },
  358. onSearch(val) {
  359. if(this.user.userNameNeedTranslate != 1) {
  360. this.executor.searchList = [];
  361. this.executor.list.forEach(u=>{if (u.name.startsWith(val)) {
  362. this.executor.searchList.push(u);
  363. }})
  364. } else {
  365. if (this.onSearchTime != null) {
  366. clearTimeout(this.onSearchTime)
  367. }
  368. var that = this
  369. this.onSearchTime = setTimeout(() => {
  370. that.getOnSearch(val)
  371. }, 500)
  372. }
  373. },
  374. getOnSearch(val) {
  375. this.$axios.post("/user/getEmployeeList", {
  376. departmentId: -1,
  377. pageIndex: 1,
  378. pageSize: 200,
  379. keyword: val,
  380. status: 1,
  381. roleId: '',
  382. cursor: '',
  383. onlyDirect: 0,
  384. })
  385. .then(res => {
  386. if(res.code == "ok") {
  387. this.executor.searchList = res.data.records
  388. } else {
  389. this.$toast.fail('搜索失败');
  390. }
  391. }).catch(err=> {this.$toast.clear();console.log(err)});
  392. },
  393. searchExecutor(){
  394. this.taskform.executorList[this.executor.index].executorId = this.executor.item.id
  395. this.taskform.executorList[this.executor.index].executorName = this.executor.item.name
  396. this.executor.show = false
  397. console.log('searchExecutor',this.executor.item,this.executor.item.name);
  398. },
  399. taskLevelChange(value,key){ // 优先级
  400. this.taskform.taskLevel = key
  401. this.taskLevel.show = false
  402. },
  403. submitTask(){
  404. console.log('submitTask');
  405. if(!this.taskform.name.replace(/^\s*|\s*$/g,"")){
  406. return
  407. }
  408. // 执行人查重
  409. let arr = this.taskform.executorList
  410. let json={};
  411. for(let i in arr){
  412. if(!json[arr[i].executorId]){
  413. json[arr[i].executorId]=1;
  414. }else{
  415. this.$toast.fail("执行人存在重复");
  416. return
  417. }
  418. }
  419. if(this.taskform.projectId == '' || this.taskform.projectId == null) {
  420. this.$toast.fail("请选择所属项目");
  421. return
  422. }
  423. if(this.taskform.groupId == '' || this.taskform.groupId == null) {
  424. this.$toast.fail("请选择所属任务分组");
  425. return
  426. }
  427. if(this.taskform.stagesId == '' || this.taskform.stagesId == null) {
  428. this.$toast.fail("请选择所属任务列表");
  429. return
  430. }
  431. // 去除未选择执行人的执行人列表
  432. this.taskform.executorList = this.taskform.executorList.filter(item => item.executorId)
  433. this.taskform.executorListStr = JSON.stringify(this.taskform.executorList)
  434. delete this.taskform.executorList
  435. delete this.taskform.subTaskList;
  436. delete this.taskform.refTaskList;
  437. delete this.taskform.progress;
  438. this.submitTaskBtn = true
  439. // return
  440. this.$axios.post("/task/save", this.taskform)
  441. .then(res => {
  442. this.submitTaskBtn = false
  443. if(res.code == "ok") {
  444. this.$toast.success('保存成功');
  445. this.back()
  446. } else {
  447. this.$toast.fail('保存失败');
  448. }
  449. }).catch(err=> {this.$toast.clear();console.log(err);this.submitTaskBtn = false});
  450. },
  451. htmleditor(e) {
  452. this.taskform.taskDesc = e
  453. console.log()
  454. },
  455. getTask(){
  456. this.$axios.post("/task/getTask", {
  457. id: this.taskId.id
  458. }).then(res => {
  459. if(res.code == "ok") {
  460. this.taskform = res.data
  461. this.taskform.createDate = null;
  462. this.taskform.indate = null;
  463. let projectManagement = false
  464. if(!this.taskform.taskDesc){
  465. this.taskform.taskDesc = ''
  466. }
  467. if(this.taskform.startDate){
  468. this.currentDate1 = new Date(this.taskform.startDate)
  469. }
  470. if(this.taskform.endDate){
  471. this.currentDate2 = new Date(this.taskform.endDate)
  472. }
  473. if(this.taskform.finishDate){
  474. this.currentDate3 = new Date(this.taskform.finishDate)
  475. }
  476. // 判断编辑权限
  477. for(let i in this.user.functionList){
  478. if(this.user.functionList[i].name == '查看全部项目'){
  479. projectManagement = true
  480. }
  481. }
  482. if(this.user.id == res.data.createrId || this.user.id == res.data.projectInchargerId || this.user.id == res.data.groupInchargerId || projectManagement || this.title == '新建任务'){
  483. this.canEdit = true
  484. }else{
  485. this.canEdit = false
  486. }
  487. // (
  488. // (
  489. // (addForm.executorListFront == null || addForm.executorListFront.length<10)
  490. // && (
  491. // addForm.id == null|| user.id == addForm.createrId || currentProject.inchargerId == user.id || permissions.projectManagement
  492. // )
  493. // )
  494. // || groupResponsibleId == user.id
  495. // )
  496. // this.canEdit = false
  497. } else {
  498. this.$toast.fail('获取失败');
  499. }
  500. }).catch(err=> {this.$toast.clear();console.log(err)});
  501. },
  502. getUsersList(){
  503. this.$axios.post("/user/getSimpleActiveUserList", {})
  504. .then(res => {
  505. if(res.code == "ok") {
  506. this.executor.list = res.data
  507. this.executor.searchList = res.data
  508. } else {
  509. this.$toast.fail('获取失败');
  510. }
  511. }).catch(err=> {this.$toast.clear();console.log(err)});
  512. }
  513. },
  514. }
  515. </script>
  516. <style lang="less" scoped>
  517. .content{
  518. margin-top: 46px;
  519. overflow: auto;
  520. .add_executor{
  521. font-size:13px;
  522. color:#1989fa;
  523. padding-left:0.42667rem;
  524. padding-bottom:.2rem;
  525. width:100px
  526. }
  527. .delete_executor{
  528. position: absolute;
  529. top: 3px;
  530. right: 3px;
  531. font-size: 22px;
  532. color: #c03131;
  533. }
  534. }
  535. .xinmingghao {
  536. overflow: hidden;
  537. text-overflow: ellipsis;
  538. width: 200px;
  539. display: inline-block;
  540. float: right;
  541. }
  542. </style>
  543. <style>
  544. .editaskBox .van-radio__label {
  545. width: 100%;
  546. display: inline-block;
  547. }
  548. </style>