editask.vue 17 KB

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