Task.vue 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. <template>
  2. <div class="create-container" v-loading="loading">
  3. <div class="title h1" v-if="!isModifyMode">任务</div>
  4. <div class="create-body">
  5. <div class="title h2" v-if="!isModifyMode">基本信息</div>
  6. <el-form :model="task" :rules="rules" ref="task" label-width="120px" class="demo-task"
  7. style="margin:0 100px;">
  8. <el-form-item label="任务名称" prop="title" style="width: 700px;">
  9. <el-input size="small" v-if="isModifyMode" v-model="task.title"></el-input>
  10. <span v-if="!isModifyMode">{{task.title}}</span>
  11. <el-tag v-if="!isModifyMode" :type="task.statusVO&&task.statusVO.style">{{task.statusVO ?
  12. task.statusVO.text:''}}
  13. </el-tag>
  14. </el-form-item>
  15. <el-form-item label="任务描述" prop="desc" style="width: 700px;">
  16. <el-input autosize v-if="isModifyMode" type="textarea" v-model="task.description"></el-input>
  17. <span v-if="!isModifyMode">{{task.description ? task.description : '暂无'}}</span>
  18. </el-form-item>
  19. <el-form-item label="任务报价" prop="quotePrice" style="width: 700px;">
  20. <el-input size="small" type="number" v-if="isModifyMode" v-model="task.quotePrice">
  21. <template slot="append">¥</template>
  22. </el-input>
  23. <span v-if="!isModifyMode">¥{{task.quotePrice}}</span>
  24. </el-form-item>
  25. <!--<el-form-item type="number" label="任务定价" prop="fixedPrice">-->
  26. <!--<el-input v-if="isModifyMode" v-model="task.fixedPrice">-->
  27. <!--<template slot="append">¥</template>-->
  28. <!--</el-input>-->
  29. <!--<span v-if="!isModifyMode">{{task.fixedPrice}}</span>-->
  30. <!--</el-form-item>-->
  31. <el-form-item label="测试类型" prop="serviceType">
  32. <el-radio-group v-if="isModifyMode" v-model="task.serviceType" @change="handleTestTypeChange">
  33. <span v-for="(item,index) in serviceType" :key="index">
  34. <el-radio :label="item.code" name="serviceType">{{item.name}}</el-radio>
  35. </span>
  36. </el-radio-group>
  37. <span class="badge" v-if="!isModifyMode">{{serviceName}}</span>
  38. </el-form-item>
  39. <el-form-item label="服务序列号" prop="endPoint" style="width: 700px;"
  40. v-if="showBD&&task.endPoint&&currType.type===1"
  41. >
  42. <el-input v-if="isModifyMode" v-model="task.endPoint.serverCode" label="examId"></el-input>
  43. <span v-if="!isModifyMode&&showBD">{{task.endPoint.serverCode}}</span>
  44. </el-form-item>
  45. <el-form-item label="任务可见性" prop="resource" style="width: 700px;">
  46. <div v-if="!isModifyMode">
  47. <!--<div v-if="task.resource=='1'">{{updateLocation(task.location)}}</div>-->
  48. <div v-if="task.resource==0">定向</div>
  49. <div v-if="task.resource==2">{{resourceType[task.resource]}}</div>
  50. </div>
  51. <el-tabs
  52. :tab-position="tabPosition"
  53. v-model="task.resource"
  54. style="max-height: 200px;"
  55. v-if="isModifyMode"
  56. >
  57. <el-tab-pane :label="resourceType[0]" name="0">
  58. <el-radio-group v-model="task.institution" @change="handleTestTypeChange">
  59. <el-radio
  60. :label="item"
  61. name="type"
  62. v-for="item,index in institutionArray"
  63. :key="index"
  64. >{{item.evaluationAgencyName}}
  65. </el-radio>
  66. </el-radio-group>
  67. </el-tab-pane>
  68. <!--<el-tab-pane :label="resourceType[1]" name="1">-->
  69. <!--<provincecity-->
  70. <!--ref="addFormProvince"-->
  71. <!--@selectChange="locationChange"-->
  72. <!--:provinceCode="task.location == null ||task.location.provinceCode==null?'3200':task.location.provinceCode"-->
  73. <!--:cityCode="task.location == null ||task.location.cityCode==null?'3201':task.location.cityCode"-->
  74. <!--&gt;</provincecity>-->
  75. <!--</el-tab-pane>-->
  76. <el-tab-pane :label="resourceType[2]" name="2"></el-tab-pane>
  77. </el-tabs>
  78. </el-form-item>
  79. <el-form-item label="领取人数" prop="contactPhone" v-if="isModifyMode&&task.resource !== '0' && currType.type===0">
  80. <el-input-number v-model="task.participantCount" :min="1" :max="1000" label="领取人数"></el-input-number>
  81. </el-form-item>
  82. <el-form-item label="领取人数" prop="contactPhone" v-if="isModifyMode&&task.resource !== '0' && currType.type===1">
  83. <el-input-number v-model="task.participantCount" :min="2" :max="1000" label="领取人数"></el-input-number>
  84. </el-form-item>
  85. <el-form-item label="领取人数" prop="quotePrice" v-if="!isModifyMode">
  86. {{task.acceptedCount }}/{{ task.participantCount}}
  87. </el-form-item>
  88. <el-form-item label="需求文档" prop="doc">
  89. <el-upload
  90. style="width: 400px"
  91. v-if="isModifyMode"
  92. drag
  93. class="upload-demo"
  94. action=""
  95. :on-remove="handleRemove"
  96. :before-remove="beforeRemove"
  97. :limit="1"
  98. :on-exceed="handleExceed"
  99. :http-request="uploadRequireDoc"
  100. :file-list="task.doc"
  101. >
  102. <i class="el-icon-upload"></i>
  103. <div class="el-upload__text">
  104. 将文件拖到此处,或
  105. <em>点击上传</em>
  106. </div>
  107. </el-upload>
  108. <span>
  109. <span v-if="task.requireDocUrl == null || task.requireDocUrl == ''">
  110. <i class="el-icon-document"></i>暂无文件
  111. </span>
  112. <span v-if="task.requireDocUrl != null && task.requireDocUrl != ''">
  113. <a :href="task.requireDocUrl"><el-link :underline="false" type="primary"><i
  114. class="el-icon-document"></i>下载文档</el-link></a>
  115. </span>
  116. </span>
  117. </el-form-item>
  118. <el-form-item label="任务截止时间" prop="datetime">
  119. <div class="block" v-if="isModifyMode">
  120. <el-date-picker
  121. size="small"
  122. v-model="task.datetime"
  123. type="datetime"
  124. placeholder="选择截止时间"
  125. align="right"
  126. :picker-options="pickerOptions"
  127. ></el-date-picker>
  128. </div>
  129. <span v-if="!isModifyMode">{{dateFormat(new Date(task.datetime),'yyyy-MM-dd HH:mm:ss')}}</span>
  130. </el-form-item>
  131. <el-form-item v-if="isModifyMode">
  132. <div class="btn btn-small btn-info" @click="updateTask()">确认修改</div>
  133. <!--<div class="btn btn-small" @click="resetForm()">重置</div>-->
  134. <div class="btn btn-small" @click="cancelMode()">取消</div>
  135. </el-form-item>
  136. <el-form-item v-if="editShortLink && task.endPoint.serverCode && taskOperationControl.confirmFinish" label="任务面板链接" props="shortLink">
  137. <el-input v-model="shortLink" placeholder="请输入短链接生成任务报告" style="width: 800px">
  138. <template slot="append">
  139. <el-button @click="getTaskDataBoard()">确定</el-button>
  140. </template>
  141. </el-input>
  142. </el-form-item>
  143. <el-form-item v-if="shortLink && !editShortLink" label="任务面板链接" props="shortLink">
  144. {{shortLink}}
  145. <i class="el-icon-edit" @click="editShortLink = true" v-if="taskOperationControl.confirmFinish"/>
  146. </el-form-item>
  147. <el-form-item v-if="!isModifyMode">
  148. <el-button size="mini" @click="toProject()">项目详情</el-button>
  149. <el-popover
  150. placement="top-start"
  151. title="确认结束?"
  152. width="200"
  153. trigger="hover"
  154. content="测评机构已提交结束申请,请确认是否结束该任务">
  155. <el-button v-if="taskOperationControl.confirmFinish" type="success" size="mini" slot="reference"
  156. @click="endTask()">确认结束
  157. </el-button>
  158. </el-popover>
  159. <el-popover
  160. placement="top-start"
  161. title="确认提交?"
  162. width="200"
  163. trigger="hover"
  164. content="提交任务后不可更改,等待区域管理员验收">
  165. <el-button v-if="taskOperationControl.finish" type="primary" size="mini" slot="reference"
  166. @click="submitTaskRequest()">提交任务
  167. </el-button>
  168. </el-popover>
  169. <el-popover
  170. placement="top-start"
  171. title="确认拒绝?"
  172. width="200"
  173. trigger="hover"
  174. content="拒绝后不可再接收此任务,且该任务对您不可见">
  175. <el-button v-if="taskOperationControl.reject" type="danger" size="mini" slot="reference"
  176. @click="rejectTask()">拒绝任务
  177. </el-button>
  178. </el-popover>
  179. <el-popover
  180. placement="top-start"
  181. title="确认接收?"
  182. width="200"
  183. trigger="hover"
  184. content="接收任务后请认真完成!">
  185. <el-button v-if="taskOperationControl.receive" type="primary" size="mini" slot="reference"
  186. @click="receiveTask()">接收任务
  187. </el-button>
  188. </el-popover>
  189. <el-button v-if="taskOperationControl.writeReport" type="primary" size="mini" @click="gotoWriteReport()">填写报告
  190. </el-button>
  191. <el-button v-if="taskOperationControl.update" type="primary" size="mini" @click="modifyForm()">修改任务
  192. </el-button>
  193. <el-button v-if="taskOperationControl.uploadReport" type="primary" size="mini" @click="toCreateReport()">
  194. 上传报告
  195. </el-button>
  196. <el-button v-if="taskOperationControl.taskDemonstrate" type="success" size="mini" @click="gotoDataboard()">
  197. 任务面板
  198. </el-button>
  199. <!--<div class="btn btn-small btn-info"-->
  200. <!--v-if="taskOperationControl.confirmFinish"-->
  201. <!--@click="endTask()">确认结束-->
  202. <!--</div>-->
  203. <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.finish" @click="submitTaskRequest()">提交任务-->
  204. <!--</div>-->
  205. <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.receive" @click="receiveTask()">接收任务</div>-->
  206. <!--<div class="btn btn-small btn-danger" v-if="!taskOperationControl.reject" @click="rejectTask()">拒绝任务</div>-->
  207. <!--<div class="btn btn-small btn-info" v-if="taskOperationControl.update" @click="modifyForm()">修改任务</div>-->
  208. <!--<div class="btn btn-small btn-info" v-if="!taskOperationControl.uploadReport" @click="toCreateReport()">上传报告-->
  209. <!--</div>-->
  210. </el-form-item>
  211. </el-form>
  212. </div>
  213. <div class="create-body" v-if="!isModifyMode">
  214. <div class="title h2">用户报告列表</div>
  215. <el-collapse accordion style="margin: 0 30px">
  216. <el-collapse-item v-for="(item,index) in acceptedUserList" :key="item.id">
  217. <template slot="title">
  218. <el-row style="width: 100%;font-size: 16px">
  219. <el-col :span="6">{{item.userVO.userName}}</el-col>
  220. <el-col :span="6">{{item.userVO.email}}</el-col>
  221. <el-col :span="6">
  222. <el-tag type="success" v-if="item.crowdReportVOS">已提交报告</el-tag>
  223. <el-tag type="info" v-if="!item.crowdReportVOS">未提交报告</el-tag>
  224. </el-col>
  225. <el-col :span="6">
  226. <el-tag type="success" v-if="item.isCommitted">已提交任务</el-tag>
  227. <el-tag type="info" v-if="!item.isCommitted">未提交任务</el-tag>
  228. </el-col>
  229. </el-row>
  230. </template>
  231. <report-list v-bind:reports="item.crowdReportVOS" v-bind:taskId="taskId" v-bind:projectId="projectId"/>
  232. </el-collapse-item>
  233. </el-collapse>
  234. <!-- <report-list v-if="isAgency" v-bind:reports="reportList" v-bind:taskId="taskId" v-bind:projectId="projectId"/>-->
  235. <!-- <report-list v-bind:reports="reportList" v-bind:taskId="taskId" v-bind:projectId="projectId"/>-->
  236. </div>
  237. </div>
  238. </template>
  239. <script>
  240. import ResourceType from '@/constants/enum/resource-type.js'
  241. import provincecity from '@/components/commons/ProvinceCity'
  242. import ReportList from '@/components/report/ReportList'
  243. import Http from '@/js/http.js'
  244. import Apis from '@/js/api.js'
  245. import {notify} from '@/constants/index'
  246. import {
  247. ensureEndTask,
  248. getAllAgencies,
  249. getAllServiceTypes,
  250. getFormalTimeFromDate,
  251. getProvinceCodeByProvinceName,
  252. getProvinceNameByProvinceCode,
  253. getTask,
  254. receiveTaskRequest,
  255. rejectTask,
  256. storageGet,
  257. submitTaskRequest,
  258. updateTask
  259. } from '@/js/index'
  260. export default {
  261. name: 'Task',
  262. components: {
  263. provincecity,
  264. ReportList
  265. },
  266. data() {
  267. return {
  268. currType: {},
  269. user: {},
  270. serviceName:'',
  271. showBD: true,
  272. rolesPermissions: {},
  273. loading: false,
  274. isModifyMode: false,
  275. institutionArray: [],
  276. tabPosition: 'top',
  277. resourceType: ResourceType,
  278. serviceType: [],
  279. taskId: '',
  280. projectId: '',
  281. taskOperationControl: {
  282. confirmFinish: false,
  283. finish: false,
  284. receive: false,
  285. update: false,
  286. uploadReport: false
  287. },
  288. crowdReportUrl: '',
  289. task: {
  290. agencyId: '',
  291. status: '',
  292. name: '',
  293. desc: '',
  294. serviceType: '',
  295. resource: '',
  296. location: {},
  297. institution: {},
  298. datetime: '',
  299. quotePrice: '',
  300. fixedPrice: '',
  301. doc: [],
  302. requireDocUrl: '',
  303. participantCount: 1,
  304. title: '',
  305. description: '',
  306. endPoint: {
  307. serverCode: '',
  308. token: ''
  309. }
  310. },
  311. reportList: [],
  312. pickerOptions: {
  313. shortcuts: [
  314. {
  315. text: '今天',
  316. onClick(picker) {
  317. picker.$emit('pick', new Date())
  318. }
  319. },
  320. {
  321. text: '昨天',
  322. onClick(picker) {
  323. const date = new Date()
  324. date.setTime(date.getTime() - 3600 * 1000 * 24)
  325. picker.$emit('pick', date)
  326. }
  327. },
  328. {
  329. text: '一周前',
  330. onClick(picker) {
  331. const date = new Date()
  332. date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
  333. picker.$emit('pick', date)
  334. }
  335. }
  336. ]
  337. },
  338. rules: {
  339. title: [
  340. {required: true, message: '请输入任务名称', trigger: 'blur'},
  341. {min: 5, max: 50, message: '任务名称长度在 5 到 50 个字符', trigger: 'blur'}
  342. ],
  343. serviceType: [
  344. {required: true, message: '测试类型不可为空', trigger: 'change'},
  345. ],
  346. desc: [{required: false, message: '请填写描述', trigger: 'blur'}],
  347. //price: [{required: true, message: '请填写价格', trigger: 'blur'}],
  348. quotePrice: [
  349. {required: true, message: '预算不可为空', trigger: 'blur'},
  350. {
  351. validator: (rule, value, callback) => {
  352. if (value < 0) {
  353. callback(new Error('请输入不小于0的数'))
  354. } else {
  355. callback()
  356. }
  357. }, trigger: 'blur'
  358. },
  359. ],
  360. resource: [
  361. {required: true},
  362. {
  363. validator: (rule, value, callback) => {
  364. if (value == 0 && this.task.institution.id == null) {
  365. callback(new Error('定向发布至少要选择一个测评机构'))
  366. } else {
  367. callback()
  368. }
  369. }, trigger: 'change'
  370. },
  371. ],
  372. endPoint: [
  373. {
  374. validator: (rule, value, callback) => {
  375. if (this.currType.type === 1 && this.task.endPoint.serverCode === '') {
  376. callback(new Error('请填写对应得服务序列号'))
  377. } else {
  378. callback()
  379. }
  380. }, trigger: ['change','blur']
  381. },
  382. ],
  383. datetime: [{required: true, message: '截止时间不可为空', trigger: 'blur'}],
  384. },
  385. acceptedUserList: [],
  386. shortLink:'',
  387. editShortLink:false,
  388. }
  389. },
  390. watch: {
  391. institutionArray(val) {
  392. this.institutionArray = val
  393. },
  394. serviceType(val) {
  395. this.serviceType = val
  396. },
  397. // 'task.institution' () {
  398. // if (this.task.institution) {
  399. // //this.$refs.addFormProvince.resetProviceCity()
  400. // this.task.location = {provinceCode: '', cityCode: ''}
  401. // }
  402. // },
  403. // 'task.location' () {
  404. // if (this.task.location.provinceCode || this.task.location.cityCode) {
  405. // this.task.institution = ''
  406. // }
  407. // },
  408. // 'task.resource' () {
  409. // if (this.task.resource == '广场') {
  410. // this.$refs.addFormProvince.resetProviceCity()
  411. // this.task.institution = ''
  412. // this.task.location = {provinceCode: '', cityCode: ''}
  413. // }
  414. // },
  415. deep: true
  416. },
  417. mounted() {
  418. this.$nextTick(() => {
  419. this.init()
  420. })
  421. },
  422. methods: {
  423. //跳转到任务对应的数据面板
  424. gotoDataboard(){
  425. window.open(this.task.endPoint.token)
  426. },
  427. //根据短链接获取生成databoard
  428. getTaskDataBoard(){
  429. this.showLoading()
  430. Http.put(`/api/project/${this.projectId}/task/${this.taskId}/addToken`,{"token":this.shortLink}).then((res)=>{
  431. this.taskOperationControl = res.taskOperationControl;
  432. this.task.endPoint = res.crowdTaskVO.endPointVO;
  433. this.shortLink = res.crowdTaskVO.endPointVO.token;
  434. if(this.shortLink != ''){
  435. this.editShortLink = false;
  436. }
  437. this.hideLoading()
  438. })
  439. },
  440. getServiceByCode(code){
  441. let serviceName = this.serviceType.filter((item) => {
  442. return item.code === code;
  443. });
  444. return serviceName&&serviceName[0]&&serviceName[0]['name']
  445. },
  446. handleTestTypeChange(val) {
  447. let type = this.serviceType.filter((item) => {
  448. return item.code === val;
  449. });
  450. this.currType = type[0] ? type[0] : {};
  451. if (this.currType.type === 0) {
  452. this.$refs.task.clearValidate('endPoint');
  453. }
  454. },
  455. init() {
  456. this.taskId = this.$route.params.taskId
  457. this.projectId = this.$route.params.projectId
  458. this.setUserInfo()
  459. this.setServiceType()
  460. //this.loadData(this.projectId, this.taskId)
  461. this.getTaskDetail()
  462. this.setInstitutions()
  463. },
  464. //北斗测试报告填写跳转
  465. gotoWriteReport() {
  466. window.open(this.crowdReportUrl, '_blank');
  467. },
  468. //跳转至项目详情页面
  469. toProject() {
  470. this.$router.push({
  471. name: 'Project',
  472. params: {projectId: this.projectId}
  473. })
  474. },
  475. //切换至可编辑页面
  476. modifyForm() {
  477. // this.task.serviceType = ''
  478. this.isModifyMode = true
  479. },
  480. //切换至不可编辑页面
  481. cancelMode() {
  482. this.isModifyMode = false
  483. },
  484. //重置表单
  485. resetForm() {
  486. this.task.name = ''
  487. this.task.desc = ''
  488. this.task.quotePrice = ''
  489. this.task.fixedPrice = ''
  490. this.task.type = ''
  491. this.task.resource = '2' //如果是广场不用管Location和institution ,定向看institution,区域看location
  492. this.task.location = {provinceCode: '', cityCode: ''}
  493. this.task.institution = ''
  494. this.task.datetime = ''
  495. this.task.participantCount = 1
  496. // this.task.endPointVO.caseId = ''
  497. // this.task.endPointVO.examId = ''
  498. },
  499. //显示页面加载画面
  500. showLoading() {
  501. this.loading = true
  502. },
  503. //隐藏页面加载画面
  504. hideLoading() {
  505. this.loading = false
  506. },
  507. //加载用户信息
  508. setUserInfo() {
  509. this.user = storageGet('user')
  510. this.rolesPermissions = storageGet('rolesPermissions')
  511. if (storageGet('rolesPermissions').isRegionManager || storageGet('rolesPermissions').isSystemAdministrator) {
  512. this.showBD = true;
  513. } else {
  514. this.showBD = false;
  515. }
  516. },
  517. //加载任务的测试类型
  518. setServiceType() {
  519. getAllServiceTypes().then((res) => {
  520. this.serviceType = res
  521. }).catch((error) => {
  522. notify('error', '加载测试类型失败')
  523. })
  524. },
  525. //加载所有的测评机构
  526. setInstitutions() {
  527. getAllAgencies().then((res) => {
  528. this.institutionArray = res
  529. }).catch((error) => {
  530. notify('error', '获取机构列表失败')
  531. })
  532. },
  533. //获取任务详情
  534. getTaskDetail() {
  535. this.showLoading()
  536. getTask(this.projectId, this.taskId, this.getTaskDetailSuccess, this.getTaskDetailFail)
  537. },
  538. //获取任务详情成功时回调函数
  539. getTaskDetailSuccess(res) {
  540. this.hideLoading()
  541. // console.log(res)
  542. this.taskId = res.crowdTaskVO.id
  543. this.projectId = res.crowdTaskVO.projectId
  544. this.task.title = res.crowdTaskVO.title
  545. this.task.description = res.crowdTaskVO.description
  546. this.task.serviceType = res.crowdTaskVO.serviceType
  547. this.task.resource = res.crowdTaskVO.resource.toString()
  548. this.task.location = getProvinceCodeByProvinceName(res.crowdTaskVO.location.provinceCode, res.crowdTaskVO.location.cityCode)
  549. this.task.institution = res.crowdTaskVO.institution
  550. this.task.datetime = new Date(res.crowdTaskVO.datetime)
  551. this.task.quotePrice = res.crowdTaskVO.quotePrice
  552. this.task.acceptedCount = res.crowdTaskVO.acceptedCount
  553. this.task.participantCount = res.crowdTaskVO.participantCount
  554. this.task.fixedPrice = res.crowdTaskVO.fixedPrice
  555. this.task.doc = []
  556. this.task.requireDocUrl = res.crowdTaskVO.requirementFile
  557. this.task.agencyId = res.crowdTaskVO.agencyId
  558. this.task.status = res.crowdTaskVO.status
  559. this.task.statusVO = res.crowdTaskVO.statusVO
  560. this.task.endPoint = res.crowdTaskVO.endPointVO ? res.crowdTaskVO.endPointVO : {
  561. serverCode: '',
  562. }
  563. this.taskOperationControl = res.taskOperationControl;
  564. this.acceptedUserList = res.acceptedUserList;
  565. this.crowdReportUrl = res.crowdTaskVO.writeReportUrl;
  566. this.handleFormatReport(this.acceptedUserList);
  567. this.handleTestTypeChange(res.crowdTaskVO.serviceType);
  568. this.serviceName = this.getServiceByCode(res.crowdTaskVO.serviceType);
  569. if(res.crowdTaskVO.endPointVO){
  570. if(res.crowdTaskVO.endPointVO.token){
  571. this.shortLink = res.crowdTaskVO.endPointVO.token;
  572. this.editShortLink = false
  573. }else{
  574. this.editShortLink = true
  575. }
  576. }
  577. // console.log(res.crowdTaskVO.endPointVO.token)
  578. // console.log(this.editShortLink)
  579. // console.log(this.isModifyMode)
  580. },
  581. //获取任务详情失败时回调函数
  582. getTaskDetailFail(error) {
  583. this.hideLoading()
  584. // notify('error', '获取任务详情失败:' + error.data)
  585. },
  586. //处理显示报告
  587. handleFormatReport(acceptedUserList) {
  588. acceptedUserList.map((user) => {
  589. user.crowdReportVOS && user.crowdReportVOS.map((report) => {
  590. report.userName = user.userVO.userName;
  591. this.reportList.push(report);
  592. })
  593. })
  594. },
  595. dateFormat(date, format) {
  596. date = new Date(date)
  597. let o = {
  598. 'M+': date.getMonth() + 1, //month
  599. 'd+': date.getDate(), //day
  600. 'H+': date.getHours(), //hour+8小时
  601. 'm+': date.getMinutes(), //minute
  602. 's+': date.getSeconds(), //second
  603. 'q+': Math.floor((date.getMonth() + 3) / 3), //quarter
  604. 'S': date.getMilliseconds() //millisecond
  605. }
  606. if (/(y+)/.test(format)) {
  607. format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
  608. }
  609. for (let k in o)
  610. if (new RegExp('(' + k + ')').test(format))
  611. format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
  612. return format;
  613. },
  614. //更新任务信息
  615. updateTask() {
  616. this.$refs['task'].validate(valid => {
  617. if (valid) {
  618. this.showLoading()
  619. const newTask = {
  620. name: this.task.title,
  621. desc: this.task.description,
  622. type: this.task.serviceType,
  623. resource: this.task.resource,
  624. location: this.task.location == null ? {} : getProvinceNameByProvinceCode(this.task.location.provinceCode, this.task.location.cityCode),
  625. institution: this.task.institution ? this.task.institution.id : null,
  626. datetime: this.task.datetime,
  627. quotePrice: this.task.quotePrice,
  628. fixedPrice: this.task.fixedPrice,
  629. requirementFile: this.task.requireDocUrl,
  630. participantCount: this.task.participantCount,
  631. endPoint: this.task.endPoint
  632. }
  633. //console.log(newTask)
  634. updateTask(this.projectId, this.taskId, newTask, this.updateTaskSuccess, this.updateTaskFail)
  635. } else {
  636. notify('error', '表单填写有误!')
  637. return false
  638. }
  639. })
  640. },
  641. //更新任务信息成功时回调函数
  642. updateTaskSuccess(res) {
  643. this.cancelMode()
  644. this.taskId = res.crowdTaskVO.id
  645. this.projectId = res.crowdTaskVO.projectId
  646. this.task.title = res.crowdTaskVO.title
  647. this.task.description = res.crowdTaskVO.description
  648. this.task.serviceType = res.crowdTaskVO.serviceType
  649. this.task.resource = res.crowdTaskVO.resource
  650. this.task.location = res.crowdTaskVO.location == null ? {
  651. provinceCode: 3200,
  652. cityCode: 3201
  653. } : getProvinceCodeByProvinceName(res.crowdTaskVO.location.provinceCode, res.crowdTaskVO.location.cityCode)
  654. this.task.institution = res.crowdTaskVO.institution
  655. this.task.datetime = new Date(res.crowdTaskVO.datetime)
  656. this.task.quotePrice = res.crowdTaskVO.quotePrice
  657. this.task.fixedPrice = res.crowdTaskVO.fixedPrice
  658. // this.task.endPointVO = res.crowdTaskVO.endPointVO
  659. this.task.doc = []
  660. this.task.requireDocUrl = res.crowdTaskVO.requirementFile,
  661. this.task.participantCount = res.crowdTaskVO.participantCount
  662. this.task.endPoint = res.crowdTaskVO.endPointVO ? res.crowdTaskVO.endPointVO : {
  663. serverCode: '',
  664. }
  665. this.reportList = res.crowdReportVOList
  666. this.crowdReportUrl = res.crowdTaskVO.writeReportUrl;
  667. this.acceptedUserList = res.acceptedUserList
  668. this.handleTestTypeChange(res.crowdTaskVO.serviceType);
  669. this.serviceName = this.getServiceByCode(res.crowdTaskVO.serviceType);
  670. this.hideLoading()
  671. notify('success', '修改成功')
  672. },
  673. //更新任务信息失败时回调函数
  674. updateTaskFail(error) {
  675. notify('error', '修改失败:' + error.data)
  676. this.hideLoading()
  677. },
  678. //上传任务需求文档
  679. uploadRequireDoc(param) {
  680. const formData = new FormData()
  681. let config = {
  682. //添加请求头
  683. headers: {'Content-Type': 'multipart/form-data'},
  684. }
  685. formData.append('file', param.file)
  686. Http.upload(Apis.FILE.REQUIREMENT_FILE.replace('{userId}', this.user.userVO.id), formData, config).then((res) => {
  687. notify('success', '上传成功')
  688. this.uploadRequireDocSuccess(res)
  689. }).catch((error) => {
  690. notify('error', '上传失败:' + error.data)
  691. this.uploadRequireDocFail(error)
  692. })
  693. },
  694. //上传任务需求文档成功时回调函数
  695. uploadRequireDocSuccess(res) {
  696. this.hideLoading()
  697. console.log('上传成功')
  698. this.task.requireDocUrl = res.data
  699. console.log(res.data)
  700. },
  701. //上传任务需求文档失败时回调函数
  702. uploadRequireDocFail(error) {
  703. this.hideLoading()
  704. notify('error', '任务需求文档上传失败:' + error.data)
  705. },
  706. //文档上传前响应函数
  707. //移除文档前的响应函数
  708. beforeRemove(file, fileList) {
  709. //return this.$confirm(`确定移除 ${file.name}?`)
  710. },
  711. //移除文档时的响应函数
  712. handleRemove(file, fileList) {
  713. console.log(file, fileList)
  714. },
  715. //需求文档添加进来时的响应函数
  716. handleExceed(files, fileList) {
  717. this.$message.warning(
  718. `当前限制选择 1 个文件,本次选择了 ${
  719. files.length
  720. } 个文件,共选择了 ${files.length + fileList.length} 个文件`
  721. )
  722. },
  723. //接收任务
  724. receiveTask() {
  725. this.$confirm('确认接收任务?', '提示', {
  726. confirmButtonText: '确认接收',
  727. cancelButtonText: '取消',
  728. type: 'success'
  729. }).then(() => {
  730. this.showLoading()
  731. receiveTaskRequest(this.projectId, this.taskId, this.user.userVO.id, this.receiveTaskSuccess, this.receiveTaskFail)
  732. }).catch(() => {
  733. })
  734. },
  735. //接收任务成功时的回调函数
  736. receiveTaskSuccess(res) {
  737. this.hideLoading()
  738. this.getTaskDetail();
  739. notify('success', '接收任务成功')
  740. // console.log(res)
  741. this.taskOperationControl = res.taskOperationControl
  742. this.task.status = res.crowdTaskVO.status
  743. this.task.institution = res.crowdTaskVO.institution
  744. },
  745. //接收任务失败时的回调函数
  746. receiveTaskFail(error) {
  747. this.hideLoading()
  748. notify('error', '接收任务失败:' + error.data)
  749. },
  750. //拒绝任务
  751. rejectTask() {
  752. this.$confirm('确认拒绝任务?拒绝后将不能再接收该任务', '提示', {
  753. confirmButtonText: '确认拒绝',
  754. cancelButtonText: '取消',
  755. type: 'success'
  756. }).then(() => {
  757. this.showLoading()
  758. rejectTask(this.projectId, this.taskId, this.rejectTaskSuccess, this.rejectTaskFail)
  759. }).catch(() => {
  760. })
  761. },
  762. //拒绝任务成功时的回调函数
  763. rejectTaskSuccess(res) {
  764. this.hideLoading()
  765. this.$router.push({
  766. name: 'Mine'
  767. })
  768. notify('success', '拒绝任务成功,已为您自动跳转到个人中心')
  769. },
  770. //拒绝任务失败时的回调函数
  771. rejectTaskFail(error) {
  772. this.hideLoading()
  773. notify('error', '拒绝任务失败:' + error.data)
  774. },
  775. //提交结束任务申请
  776. submitTaskRequest() {
  777. this.$confirm('确认提交任务?提交后将不能再修改', '提示', {
  778. confirmButtonText: '确认提交',
  779. cancelButtonText: '取消',
  780. type: 'success'
  781. }).then(() => {
  782. this.showLoading()
  783. submitTaskRequest(this.projectId, this.taskId, this.submitTaskRequestSuccess, this.submitTaskRequestFail)
  784. }).catch(() => {
  785. })
  786. },
  787. //提交结束任务申请成功时的回调函数
  788. submitTaskRequestSuccess(res) {
  789. this.hideLoading()
  790. console.log(res)
  791. this.taskOperationControl = res.taskOperationControl
  792. this.task.status = res.crowdTaskVO.status
  793. this.task.institution = res.crowdTaskVO.institution
  794. notify('success', '提交任务成功,等待区域管理员审核')
  795. this.getTaskDetail();
  796. },
  797. //提交结束任务申请失败时的回调函数
  798. submitTaskRequestFail(error) {
  799. this.hideLoading()
  800. notify('error', '提交任务失败:' + error.data)
  801. },
  802. //结束任务
  803. endTask() {
  804. this.$confirm('确认结束任务?', '提示', {
  805. confirmButtonText: '确认结束',
  806. cancelButtonText: '取消',
  807. type: 'success'
  808. }).then(() => {
  809. this.getTaskDetail()
  810. this.showLoading()
  811. ensureEndTask(this.projectId, this.taskId, this.endTaskSuccess, this.endTaskFail)
  812. }).catch(() => {
  813. })
  814. },
  815. //结束任务成功时的回调函数
  816. endTaskSuccess(res) {
  817. this.hideLoading()
  818. this.taskOperationControl = res.taskOperationControl
  819. this.task.status = res.crowdTaskVO.status
  820. this.task.institution = res.crowdTaskVO.institution
  821. notify('success', '结束任务成功!')
  822. this.getTaskDetail();
  823. },
  824. //结束任务失败时的回调函数
  825. endTaskFail(error) {
  826. this.hideLoading()
  827. notify('error', '结束任务失败:' + error.data)
  828. },
  829. //跳转到创建项目报告页面
  830. toCreateReport() {
  831. this.$router.push({
  832. name: 'TaskReportCreate',
  833. params: {
  834. scope: 1,
  835. dependencyCode: this.taskId,
  836. projectId: this.projectId,
  837. taskId: this.taskId,
  838. }
  839. })
  840. },
  841. reformDate(date) {
  842. return getFormalTimeFromDate(date)
  843. }
  844. },
  845. }
  846. //回收站
  847. //
  848. // updateLocation (location) {
  849. // console.log(location)
  850. // const loactionName = getProvinceNameByProvinceCode(location.provinceCode, location.cityCode)
  851. // // var provinceName = ''
  852. // // var cityName = ''
  853. // // for (var item of provinceCityJSON.provinces) {
  854. // // if (item.code === location.provinceCode) {
  855. // // provinceName = item.name
  856. // // for (var city of item.cities) {
  857. // // if (city.code === location.cityCode) {
  858. // // cityName = city.name
  859. // // break
  860. // // }
  861. // // }
  862. // // }
  863. // // }
  864. // return loactionName.provinceCode + ' / ' + loactionName.cityCode
  865. // },
  866. //
  867. // locationChange (provinceId, cityId) {
  868. // if (provinceId || cityId) {
  869. // this.task.location = {provinceCode: provinceId, cityCode: cityId}
  870. // }
  871. // },
  872. // submitForm (formName) {
  873. // this.$refs[formName].validate(valid => {
  874. // if (valid) {
  875. // this.isModifyMode = false
  876. //
  877. // } else {
  878. // console.log('error submit!!')
  879. // return false
  880. // }
  881. // })
  882. // },
  883. </script>
  884. <style lang="less" scoped>
  885. .el-radio {
  886. margin: 10px 20px 10px 0;
  887. }
  888. .el-form-item /deep/ .el-tabs__content {
  889. /*max-height: 120px !important;*/
  890. overflow: auto;
  891. }
  892. .el-collapse-item__content {
  893. padding-bottom: 0 !important;
  894. }
  895. </style>