Project.vue 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  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. <el-row type="flex" align="middle" justify="start">
  6. <el-col :span="15">
  7. <div class="title h2" v-if="!isModifyMode">基本信息</div>
  8. <div v-if="!isModifyMode" class="el-form-item">
  9. <label class="el-form-item__label" style="width: 30%;">编号</label>
  10. <div class="el-form-item__content" style="margin-left: 30%;">
  11. <div>{{projectId}}</div>
  12. </div>
  13. </div>
  14. <el-form :model="project" :rules="rules" ref="project" label-width="30%" class="demo-project">
  15. <el-form-item label="项目名称" prop="name">
  16. <el-input size="small" v-if="isModifyMode" v-model="project.name"></el-input>
  17. <span v-if="!isModifyMode" style="margin-right: 5px">{{project.name}}</span>
  18. <el-tag v-if="!isModifyMode" :type="project.statusVO&&project.statusVO.style">
  19. {{project.statusVO?project.statusVO.text:''}}
  20. </el-tag>
  21. </el-form-item>
  22. <el-form-item size="small" label="联系人" prop="contactName">
  23. <el-input v-if="isModifyMode" v-model="project.contactName" placeholder="请输入联系人姓名"></el-input>
  24. <span v-if="!isModifyMode">{{project.contactName}}</span>
  25. </el-form-item>
  26. <el-form-item size="small" label="联系人电话" prop="contactPhone">
  27. <el-input v-if="isModifyMode" v-model="project.contactPhone" placeholder="请输入联系人电话"></el-input>
  28. <span v-if="!isModifyMode">{{project.contactPhone}}</span>
  29. </el-form-item>
  30. <el-form-item size="small" label="预算" prop="budget">
  31. <el-input v-if="isModifyMode" type="number" v-model="project.budget">
  32. ¥
  33. <template slot="append"></template>
  34. </el-input>
  35. <span v-if="!isModifyMode">¥{{project.budget}}</span>
  36. </el-form-item>
  37. <el-form-item label="计价标准" prop="valuationStandard">
  38. <el-input style="width: 400px" autosize v-if="isModifyMode" type="textarea"
  39. v-model="project.valuationStandard"></el-input>
  40. <span v-if="!isModifyMode">{{project.valuationStandard ? project.valuationStandard : '暂无'}}</span>
  41. </el-form-item>
  42. <!-- <el-form-item size="small" label="计价标准" prop="valuationStandard">-->
  43. <!-- <el-input v-if="isModifyMode" type="number" v-model="project.valuationStandard">-->
  44. <!-- <template slot="append"></template>-->
  45. <!-- </el-input>-->
  46. <!-- <span v-if="!isModifyMode">{{project.valuationStandard}}</span>-->
  47. <!-- </el-form-item>-->
  48. <!-- <el-form-item v-if="!isModifyMode" size="small" label="状态" prop="status">-->
  49. <!-- <span v-if="!isModifyMode">{{project.statusVO?project.statusVO.text:''}}</span>-->
  50. <!-- </el-form-item>-->
  51. <el-form-item size="small" label="区域管理员" prop="regionManagerName"
  52. v-if="!isModifyMode && project.regionManagerName">
  53. <span>{{project.regionManagerName}}</span>
  54. </el-form-item>
  55. <el-form-item label="需求描述">
  56. <el-input style="width: 400px" autosize v-if="isModifyMode" type="textarea"
  57. v-model="project.desc"></el-input>
  58. <span v-if="!isModifyMode">{{project.desc ? project.desc : '暂无'}}</span>
  59. </el-form-item>
  60. <!--<el-form-item label="价格" prop="price">-->
  61. <!--<el-input v-if="isModifyMode" type="number" v-model="project.price">-->
  62. <!--<template slot="append">¥</template>-->
  63. <!--</el-input>-->
  64. <!--<span v-if="!isModifyMode">{{project.price}}¥</span>-->
  65. <!--</el-form-item>-->
  66. <el-form-item label="领域类型" prop="field">
  67. <el-radio-group v-if="isModifyMode" v-model="project.field">
  68. <span v-for="(item,index) in fields" :key="index">
  69. <el-radio :label="item.name">{{ item.name }}&nbsp;&nbsp;&nbsp;&nbsp;</el-radio>
  70. </span>
  71. </el-radio-group>
  72. <span
  73. v-if="!isModifyMode"
  74. class="badge"
  75. >
  76. {{project.field}}</span>
  77. </el-form-item>
  78. <el-form-item label="应用类型" prop="platform">
  79. <el-radio-group v-if="isModifyMode" v-model="project.platform">
  80. <span v-for="(item,index) in platforms" :key="index">
  81. <el-radio :label="item.name">{{ item.name }}&nbsp;&nbsp;&nbsp;&nbsp;</el-radio>
  82. </span>
  83. </el-radio-group>
  84. <span
  85. v-if="!isModifyMode"
  86. class="badge"
  87. >
  88. {{project.platform}}</span>
  89. </el-form-item>
  90. <el-form-item label="测试类型" prop="type">
  91. <el-checkbox-group v-if="isModifyMode" v-model="project.type">
  92. <span v-for="(item,index) in serviceType" :key="index">
  93. <el-checkbox :label="item.name" name="type">{{ item.name }}&nbsp;&nbsp;</el-checkbox>
  94. </span>
  95. </el-checkbox-group>
  96. <span v-if="!isModifyMode" class="badge" v-for="item in project.type">{{item}}</span>
  97. </el-form-item>
  98. <!--<el-form-item label="用途" prop="usage">-->
  99. <!--<el-input v-if="isModifyMode" v-model="project.usage"></el-input>-->
  100. <!--<span v-if="!isModifyMode">{{project.usage}}</span>-->
  101. <!--</el-form-item>-->
  102. <el-form-item label="项目可见性" prop="resource">
  103. <div v-if="!isModifyMode">
  104. <div v-if="project.resource=='1'">{{updateLocation(project.location)}}</div>
  105. <div v-if="project.resource=='0'">定向</div>
  106. <div v-if="project.resource=='2'">{{resourceType[project.resource]}}</div>
  107. </div>
  108. <el-tabs :tab-position="tabPosition" v-model="project.resource" style="max-height: 200px;"
  109. v-if="isModifyMode">
  110. <!-- <el-tab-pane :label="resourceType[0]" :name="0">-->
  111. <!-- <el-radio-group v-model="project.institution">-->
  112. <!-- <span v-for="(item,index) in institutionArray" :key="index">-->
  113. <!-- <el-radio :label="item.id" name="type" style="margin: 3px">{{ item.name }}&nbsp;&nbsp;&nbsp;&nbsp;</el-radio>-->
  114. <!-- </span>-->
  115. <!-- </el-radio-group>-->
  116. <!-- </el-tab-pane>-->
  117. <el-tab-pane :label="resourceType[0]" :name="0">
  118. <el-radio-group v-model="project.institution">
  119. <el-radio v-for="(item,index) in institutionArray" :label="item.id" name="type" :key="index">
  120. {{item.name}}
  121. </el-radio>
  122. </el-radio-group>
  123. </el-tab-pane>
  124. <el-tab-pane :label="resourceType[1]" :name="1">
  125. <provincecity
  126. ref="addFormProvince"
  127. @selectChange="locationChange"
  128. :provinceCode="project.location==null?'3200':project.location.provinceCode"
  129. :cityCode="project.location==null?'3201':project.location.cityCode"
  130. ></provincecity>
  131. </el-tab-pane>
  132. <el-tab-pane :label="resourceType[2]" :name="2"></el-tab-pane>
  133. </el-tabs>
  134. </el-form-item>
  135. <el-form-item label="需求文档" prop="doc">
  136. <el-upload
  137. style="width: 400px"
  138. v-if="isModifyMode"
  139. drag
  140. class="upload-demo"
  141. action=""
  142. :on-remove="handleRemove"
  143. :before-remove="beforeRemove"
  144. :limit="1"
  145. :on-exceed="handleExceed"
  146. :before-upload="beforeFileUpload"
  147. :http-request="uploadRequireDoc"
  148. :file-list="project.doc"
  149. >
  150. <i class="el-icon-upload"></i>
  151. <div class="el-upload__text">
  152. 将文件拖到此处,或
  153. <em>点击上传</em>
  154. </div>
  155. </el-upload>
  156. <span>
  157. <a :href="project.requireDocUrl" v-if="project.requireDocUrl!=null && project.requireDocUrl!=''"><el-link
  158. :underline="false" type="primary"><i
  159. class="el-icon-document"></i>下载文档</el-link></a>
  160. <i v-if="project.requireDocUrl==null || project.requireDocUrl==''" class="el-icon-document">暂无文档</i>
  161. </span>
  162. </el-form-item>
  163. <el-form-item label="安装包" prop="file">
  164. <el-upload
  165. style="width: 400px"
  166. v-if="isModifyMode"
  167. drag
  168. class="upload-demo"
  169. action=""
  170. :on-remove="handleRemove"
  171. :before-remove="beforeRemove"
  172. :limit="1"
  173. :on-exceed="handleExceed"
  174. :before-upload="beforeApkUpload"
  175. :http-request="uploadApkFile"
  176. :file-list="project.file"
  177. >
  178. <i class="el-icon-upload"></i>
  179. <div class="el-upload__text">
  180. 将文件拖到此处,或
  181. <em>点击上传</em>
  182. </div>
  183. </el-upload>
  184. <span>
  185. <a v-if="project.fileUrl!=null && project.fileUrl!=''" :href="project.fileUrl"><el-link :underline="false"
  186. type="primary"><i
  187. class="el-icon-document"></i>下载文件</el-link></a>
  188. <i v-if="project.fileUrl==null || project.fileUrl==''" class="el-icon-document">暂无文件</i>
  189. </span>
  190. </el-form-item>
  191. <el-form-item label="委托单位" prop="entrustUnit" v-if="project.entrustUnit">
  192. <el-input style="width: 400px" autosize v-if="isModifyMode" type="textarea"
  193. v-model="project.entrustUnit"></el-input>
  194. <span v-if="!isModifyMode">{{project.entrustUnit}}</span>
  195. </el-form-item>
  196. <el-form-item label="项目截止时间" prop="datetime">
  197. <div class="block" v-if="isModifyMode">
  198. <el-date-picker
  199. size="small"
  200. v-model="project.datetime"
  201. type="datetime"
  202. placeholder="选择截止时间"
  203. align="right"
  204. :picker-options="pickerOptions"
  205. ></el-date-picker>
  206. </div>
  207. <span v-if="!isModifyMode">{{dateFormat(new Date(project.datetime),'yyyy-MM-dd HH:mm:ss')}}</span>
  208. </el-form-item>
  209. <el-form-item v-if="isModifyMode">
  210. <div class="btn btn-small btn-info" @click="submitForm('project')">确认修改</div>
  211. <!--<div class="btn btn-small" @click="resetForm('project')">重置</div>-->
  212. <div class="btn btn-small" @click="cancelMode('project')">取消</div>
  213. </el-form-item>
  214. <el-form-item v-if="!isModifyMode">
  215. <el-button v-if="projectOperationControl.reject" type="danger" size="mini" @click="rejectProject()">
  216. 拒绝项目
  217. </el-button>
  218. <el-button v-if="projectOperationControl.receive" type="primary" size="mini" @click="receiveProject()">
  219. 接收项目
  220. </el-button>
  221. <el-button v-if="projectOperationControl.update" type="primary" size="mini" @click="modifyForm()">
  222. 修改项目
  223. </el-button>
  224. <el-button v-if="projectOperationControl.createTask" type="primary" size="mini" @click="createNewTask()">
  225. 新建任务
  226. </el-button>
  227. <el-button v-if="projectOperationControl.uploadReport" type="primary" size="mini" @click="createReport()">
  228. 上传报告
  229. </el-button>
  230. <el-button v-if="projectOperationControl.finish" type="primary" size="mini"
  231. @click="submitProjectRequest()">
  232. 提交项目
  233. </el-button>
  234. <el-button v-if="projectOperationControl.confirmFinish" type="success" size="mini" @click="endProject()">
  235. 结束项目
  236. </el-button>
  237. </el-form-item>
  238. </el-form>
  239. </el-col>
  240. <el-col :span="5" id="pieImage" style="height: 500px;min-width: 500px">
  241. </el-col>
  242. </el-row>
  243. </div>
  244. <!-- 任务列表-->
  245. <div class="create-body" v-if="!isModifyMode">
  246. <div class="title h2">任务列表</div>
  247. <div class="task-list">
  248. <el-table :showHeader="true" :stripe="true" :data="task" style="width: 100%">
  249. <el-table-column prop="title" label="任务名称" title="任务名称">
  250. <template slot-scope="scope">
  251. <span>{{ scope.row.title }}</span>
  252. </template>
  253. </el-table-column>
  254. <el-table-column align="center" prop="datetime" sortable label="任务截止时间">
  255. <template slot-scope="scope">
  256. <span>{{reformDate(new Date(scope.row.datetime))}}</span>
  257. </template>
  258. </el-table-column>
  259. <el-table-column align="center" prop="resource" label="任务可见性">
  260. <template slot-scope="scope">
  261. <div v-if="scope.row.resource=='1'">{{scope.row.location.provinceCode}}/{{scope.row.location.cityCode}}
  262. </div>
  263. <div v-if="scope.row.resource=='0'">{{scope.row.agencyName}}</div>
  264. <div v-if="scope.row.resource=='2'">{{resourceType[scope.row.resource]}}</div>
  265. </template>
  266. </el-table-column>
  267. <el-table-column align="center" prop="type" label="测试类型">
  268. <template slot-scope="scope">
  269. <div class="badge">{{scope.row.serviceType}}</div>
  270. </template>
  271. </el-table-column>
  272. <el-table-column align="center" label="状态">
  273. <template slot-scope="scope">
  274. <el-tag :type="scope.row.statusVO.style">{{scope.row.statusVO.text}}</el-tag>
  275. </template>
  276. </el-table-column>
  277. <el-table-column align="center" label="操作">
  278. <template slot-scope="scope">
  279. <div
  280. class="btn btn-small btn-info"
  281. @click="goToTaskDetail(projectId, scope.row.id)"
  282. >查看详情
  283. </div>
  284. <!-- <div-->
  285. <!-- class="btn btn-small btn-danger"-->
  286. <!-- @click="handleDelete(scope.$index, scope.row.id)"-->
  287. <!-- >删除-->
  288. <!-- </div>-->
  289. </template>
  290. </el-table-column>
  291. </el-table>
  292. </div>
  293. </div>
  294. <div class="create-body" v-if="!isModifyMode">
  295. <div class="title h2">项目报告</div>
  296. <report-list v-bind:reports="reportList" v-bind:taskId=null v-bind:projectId="projectId"/>
  297. </div>
  298. </div>
  299. </template>
  300. <script>
  301. import ReportList from '@/components/report/ReportList'
  302. import Http from '@/js/http.js'
  303. import Apis from '@/js/api.js'
  304. import ResourceType from '@/constants/enum/resource-type'
  305. import provincecity from '@/components/commons/ProvinceCity'
  306. import {notify} from '@/constants/index'
  307. import echarts from 'echarts'
  308. import {
  309. deleteTask,
  310. ensureEndProject,
  311. getAllFields,
  312. getAllInstitutions,
  313. getAllApplicationTypes,
  314. getAllServiceTypes,
  315. getFormalTimeFromDate,
  316. getProvinceCodeByProvinceName,
  317. getProvinceNameByProvinceCode,
  318. receiveProjectRequest,
  319. rejectProject,
  320. storageGet,
  321. submitProjectRequest
  322. } from '@/js/index'
  323. export default {
  324. name: 'Project',
  325. components: {
  326. provincecity,
  327. ReportList
  328. },
  329. data() {
  330. var validatePass = (rule, value, callback) => {
  331. var reg = /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/
  332. if (this.project.contactPhone) {
  333. if (!reg.test(this.project.contactPhone)) {
  334. callback(new Error('请检查手机号码'))
  335. } else {
  336. callback()
  337. }
  338. }
  339. }
  340. return {
  341. showTaskList: true,
  342. acceptedUserList: [],
  343. projectId: 0,
  344. user: {},
  345. loading: false,
  346. tabPosition: 'top',
  347. institutionArray: [],
  348. isModifyMode: false,
  349. platforms: [],
  350. fields: [],
  351. resourceType: ResourceType,
  352. serviceType: [],
  353. projectOperationControl: {
  354. confirmFinish: false,
  355. createTask: false,
  356. finish: false,
  357. receive: false,
  358. reject: false,
  359. update: false,
  360. uploadReport: false,
  361. },
  362. project: {
  363. userId: 0,
  364. name: '',
  365. type: [],
  366. platform: '',
  367. valuationStandard: '',
  368. entrustUnit: '',
  369. field: '',
  370. desc: '',
  371. resource: '',
  372. location: '',
  373. institution: {},
  374. regionManagerId: 0,
  375. regionManagerName: '',
  376. contactName: '',
  377. contactPhone: '',
  378. doc: [],
  379. requireDocUrl: '',
  380. file: [],
  381. fileUrl: '',
  382. budget: '',
  383. price: '',
  384. datetime: '',
  385. usage: '',
  386. status: '',
  387. },
  388. task: [],
  389. progress: [],
  390. reportList: [],
  391. pickerOptions: {
  392. disabledDate(time) {
  393. return time.getTime() <= Date.now();
  394. },
  395. shortcuts: [
  396. {
  397. text: '今天',
  398. onClick(picker) {
  399. picker.$emit('pick', new Date())
  400. }
  401. },
  402. {
  403. text: '明天',
  404. onClick(picker) {
  405. const date = new Date()
  406. date.setTime(date.getTime() + 3600 * 1000 * 24)
  407. picker.$emit('pick', date)
  408. }
  409. },
  410. {
  411. text: '一周后',
  412. onClick(picker) {
  413. const date = new Date()
  414. date.setTime(date.getTime() + 3600 * 1000 * 24 * 7)
  415. picker.$emit('pick', date)
  416. }
  417. }
  418. ]
  419. },
  420. rules: {
  421. name: [
  422. {required: true, message: '请输入项目名称', trigger: 'blur'},
  423. {min: 5, max: 50, message: '项目名称长度在 5 到 50 个字符', trigger: 'blur'}
  424. ],
  425. contactName: [
  426. {required: true, message: '请输入联系人姓名', trigger: 'blur'}
  427. // { min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }
  428. ],
  429. contactPhone: [
  430. {required: true, message: '请输入手机号', trigger: 'blur'},
  431. {min: 11, max: 11, message: '请输入正确的手机号', trigger: 'blur'},
  432. {
  433. validator: (rule, value, callback) => {
  434. if (!this.checkPhoneNumber(value)) {
  435. callback(new Error('手机号输入有误'))
  436. } else {
  437. callback()
  438. }
  439. }, trigger: 'blur'
  440. },
  441. ],
  442. type: [
  443. {
  444. type: 'array',
  445. required: true,
  446. message: '请至少选择一种测试类型',
  447. trigger: 'change'
  448. }
  449. ],
  450. platform: [
  451. {
  452. required: true,
  453. message: '请选择一个应用类型',
  454. trigger: 'change'
  455. }
  456. ],
  457. field: [
  458. {
  459. required: true,
  460. message: '请选择一个领域类型',
  461. trigger: 'change'
  462. }
  463. ],
  464. desc: [{required: false, message: '请填写描述', trigger: 'blur'}],
  465. //price: [{required: true, message: '请填写价格', trigger: 'blur'}],
  466. budget: [
  467. {required: true, message: '预算不可为空', trigger: 'blur'},
  468. {
  469. validator: (rule, value, callback) => {
  470. if (value < 0) {
  471. callback(new Error('请输入不小于0的数'))
  472. } else {
  473. callback()
  474. }
  475. }, trigger: 'blur'
  476. },
  477. ],
  478. resource: [
  479. {required: true},
  480. {
  481. validator: (rule, value, callback) => {
  482. if (value == 0 && this.project.institution == null) {
  483. callback(new Error('定向发布至少要选择一个区域管理员'))
  484. } else {
  485. callback()
  486. }
  487. }, trigger: 'change'
  488. },
  489. ],
  490. datetime: [{required: true, message: '截止时间不可为空', trigger: 'blur'}],
  491. }
  492. }
  493. },
  494. mounted() {
  495. this.$nextTick(() => {
  496. this.init();
  497. })
  498. },
  499. watch: {
  500. serviceType(val) {
  501. this.serviceType = val
  502. },
  503. institutionArray(val) {
  504. this.institutionArray = val
  505. },
  506. deep: true
  507. },
  508. methods: {
  509. updateLocation(location) {
  510. //console.log(location)
  511. const loactionName = getProvinceNameByProvinceCode(location.provinceCode, location.cityCode)
  512. // var provinceName = ''
  513. // var cityName = ''
  514. // for (var item of provinceCityJSON.provinces) {
  515. // if (item.code === location.provinceCode) {
  516. // provinceName = item.name
  517. // for (var city of item.cities) {
  518. // if (city.code === location.cityCode) {
  519. // cityName = city.name
  520. // break
  521. // }
  522. // }
  523. // }
  524. // }
  525. return loactionName.provinceCode + ' / ' + loactionName.cityCode
  526. },
  527. init() {
  528. this.projectId = this.$route.params.projectId
  529. // this.setInstitutions()
  530. this.setUserInfo()
  531. this.loadData()
  532. //this.reformDate(123)
  533. // this.project.platform.map(item => {
  534. // this.platformType.push(PlatformType[item])
  535. // })
  536. },
  537. //画个饼
  538. setEcharts() {
  539. // 基于准备好的dom,初始化echarts实例
  540. let myChart = echarts.init(document.getElementById('pieImage'))
  541. // 绘制图表
  542. var option = {
  543. tooltip: {
  544. trigger: 'item',
  545. formatter: '{a} <br/>{b}: {c} ({d}%)'
  546. },
  547. legend: {
  548. orient: 'vertical',
  549. x: 'left',
  550. data: ['已完成', '进行中']
  551. },
  552. series: [
  553. {
  554. name: '任务状态',
  555. type: 'pie',
  556. radius: ['50%', '70%'],
  557. avoidLabelOverlap: false,
  558. label: {
  559. normal: {
  560. show: false,
  561. position: 'center'
  562. },
  563. emphasis: {
  564. show: true,
  565. textStyle: {
  566. fontSize: '30',
  567. fontWeight: 'bold'
  568. }
  569. }
  570. },
  571. labelLine: {
  572. normal: {
  573. show: false
  574. }
  575. },
  576. data: this.progress,
  577. color: ['#909399', '#409EFF']
  578. }
  579. ]
  580. }
  581. myChart.setOption(option)
  582. },
  583. //提交修改
  584. submitForm(formName) {
  585. this.$refs['project'].validate(valid => {
  586. if (valid) {
  587. this.showLoading()
  588. const newProject = {
  589. userId: this.user.userVO.id,
  590. name: this.project.name,
  591. type: this.project.type,
  592. platform: this.project.platform,
  593. valuationStandard: this.project.valuationStandard,
  594. entrustUnit: this.project.entrustUnit,
  595. field: this.project.field,
  596. desc: this.project.desc,
  597. resource: this.project.resource,
  598. location: getProvinceNameByProvinceCode(this.project.location.provinceCode, this.project.location.cityCode),
  599. institution: this.project.institution == null ? null : this.project.institution,
  600. contactName: this.project.contactName,
  601. contactPhone: this.project.contactPhone,
  602. doc: this.project.requireDocUrl,
  603. file: this.project.fileUrl,
  604. budget: this.project.budget,
  605. price: this.project.price,
  606. datetime: this.project.datetime,
  607. usage: this.project.usage,
  608. }
  609. // console.log(newProject);
  610. Http.put(Apis.PROJECT.UPDATE_PROJECT.replace('{projectId}', this.projectId), newProject).then((res) => {
  611. // console.log(res)
  612. this.project.resource = res.projectDetails.resource
  613. this.project.location = getProvinceCodeByProvinceName(res.projectDetails.location.provinceCode, res.projectDetails.location.cityCode)
  614. this.project.datetime = new Date(res.projectDetails.datetime)
  615. this.changeValue(res);
  616. this.isModifyMode = false
  617. this.hideLoading()
  618. notify('success', '项目修改成功')
  619. }).catch(error => {
  620. this.hideLoading()
  621. notify('error', error.data)
  622. console.log(error)
  623. })
  624. } else {
  625. notify('error', '表单填写错误!')
  626. return false
  627. }
  628. })
  629. },
  630. changeValue(res) {
  631. this.project = res.projectDetails
  632. this.projectId = res.projectDetails.id
  633. this.project.fileUrl = res.projectDetails.file
  634. this.project.requireDocUrl = res.projectDetails.doc
  635. this.task = res.taskList
  636. this.reportList = res.reportList
  637. this.projectOperationControl = res.projectOperationControl
  638. },
  639. //重置表单
  640. resetForm(formName) {
  641. this.$refs[formName].resetFields()
  642. this.project.name = ''
  643. this.project.type = []
  644. this.project.platform = ''
  645. this.project.valuationStandard = ''
  646. this.project.entrustUnit = ''
  647. this.project.field = ''
  648. this.project.desc = ''
  649. this.project.doc = ''
  650. this.project.file = ''
  651. this.project.contactName = ''
  652. this.project.contactPhone = ''
  653. this.project.resource = '2'
  654. this.project.institution = ''
  655. this.project.datetime = ''
  656. this.project.price = ''
  657. this.project.usage = ''
  658. this.project.budget = ''
  659. },
  660. //进入修改项目页面
  661. modifyForm() {
  662. this.isModifyMode = true
  663. this.setServiceType()
  664. this.setFields()
  665. this.setPlatformType()
  666. // this.project.type = []
  667. // this.project.platform = ''
  668. // this.project.field = ''
  669. // console.log(this.project.doc)
  670. this.setInstitutions()
  671. //获得update 信息
  672. //this.loadData()
  673. },
  674. //接收项目
  675. receiveProject() {
  676. this.$confirm('确认接收项目?', '提示', {
  677. confirmButtonText: '确认接收',
  678. cancelButtonText: '取消',
  679. type: 'success'
  680. }).then(() => {
  681. this.showLoading()
  682. receiveProjectRequest(this.projectId, this.user.userVO.id, this.receiveProjectSuccess, this.receiveProjectFail)
  683. }).catch(() => {
  684. })
  685. },
  686. receiveProjectSuccess(res) {
  687. this.hideLoading()
  688. notify('success', '项目接收成功!')
  689. this.changeValue(res);
  690. },
  691. receiveProjectFail(error) {
  692. this.hideLoading()
  693. notify('error', '接收项目失败:' + error.data)
  694. },
  695. //拒绝项目
  696. rejectProject() {
  697. this.$confirm('确认拒绝项目?', '提示', {
  698. confirmButtonText: '确认拒绝',
  699. cancelButtonText: '取消',
  700. type: 'success'
  701. }).then(() => {
  702. this.showLoading()
  703. rejectProject(this.projectId, this.rejectProjectSuccess, this.rejectProjectFail)
  704. }).catch(() => {
  705. })
  706. },
  707. rejectProjectSuccess(res) {
  708. this.hideLoading()
  709. notify('success', '拒绝项目成功')
  710. this.changeValue(res);
  711. },
  712. rejectProjectFail(error) {
  713. this.hideLoading()
  714. notify('error', '拒绝项目失败:' + error.data)
  715. },
  716. //提交项目
  717. submitProjectRequestSuccess(res) {
  718. this.hideLoading()
  719. notify('success', '项目提交成功!')
  720. this.loadData()
  721. this.changeValue(res);
  722. },
  723. submitProjectRequest() {
  724. this.$confirm('确认提交项目?', '提示', {
  725. confirmButtonText: '确认提交',
  726. cancelButtonText: '取消',
  727. type: 'success'
  728. }).then(() => {
  729. this.showLoading()
  730. submitProjectRequest(this.projectId, this.submitProjectRequestSuccess, this.submitProjectRequestFail)
  731. }).catch(() => {
  732. })
  733. },
  734. submitProjectRequestFail(error) {
  735. this.hideLoading()
  736. notify('error', '提交项目失败:' + error.data)
  737. },
  738. //结束项目
  739. endProject() {
  740. this.$confirm('确认结束项目?', '提示', {
  741. confirmButtonText: '确认结束',
  742. cancelButtonText: '取消',
  743. type: 'success'
  744. }).then(() => {
  745. this.showLoading()
  746. ensureEndProject(this.projectId, this.endProjectSuccess, this.endProjectFail)
  747. }).catch(() => {
  748. })
  749. },
  750. endProjectSuccess(res) {
  751. this.hideLoading()
  752. notify('success', '项目提交成功!')
  753. this.loadData()
  754. this.changeValue(res);
  755. },
  756. endProjectFail(error) {
  757. this.hideLoading()
  758. notify('error', '结束项目失败:' + error.data)
  759. },
  760. cancelMode(formName) {
  761. this.isModifyMode = false
  762. this.loadData()
  763. },
  764. goToTaskDetail(projectId, taskId) {
  765. this.$router.push({
  766. name: 'Task',
  767. params: {projectId: projectId, taskId: taskId}
  768. })
  769. },
  770. createNewTask() {
  771. const that = this
  772. this.$router.push({
  773. name: 'TaskCreate',
  774. params: {projectId: that.projectId}
  775. })
  776. },
  777. createReport() {
  778. this.$router.push({
  779. name: 'ProjectReportCreate',
  780. params: {
  781. scope: 0,
  782. dependencyCode: this.projectId,
  783. projectId: this.projectId,
  784. }
  785. })
  786. },
  787. handleDelete(index, id) {
  788. this.$confirm('确认删除该任务?')
  789. .then(_ => {
  790. //done()
  791. //id->taskid
  792. console.log(id)
  793. console.log(this.projectId)
  794. deleteTask(this.projectId, id, this.deleteTaskSuccess, this.deleteTaskFail)
  795. })
  796. .catch(_ => {
  797. notify('error', '删除失败')
  798. })
  799. //this.task.splice(index, 1)
  800. },
  801. deleteTaskSuccess(res) {
  802. notify('success', '删除成功')
  803. },
  804. deleteTaskFail(error) {
  805. console.log(error)
  806. notify('error', '删除失败:' + error)
  807. },
  808. beforeApkUpload(file) {
  809. return true;
  810. //const fileTypeList = ['dmg', 'exe', 'apk']
  811. //return checkFileType(file, fileTypeList, this.beforeFileUploadError)
  812. },
  813. beforeFileUpload(file) {
  814. return true;
  815. //const fileTypeList = ['pdf', 'xls', 'xlsx', 'doc', 'docx', 'txt']
  816. //return checkFileType(file, fileTypeList, this.beforeFileUploadError)
  817. },
  818. beforeFileUploadError() {
  819. this.$message.error('上传文件只能是 PDF 、 DOC 、DOCX 、XLS、TXT、XLSX 格式!')
  820. },
  821. analyseDemand() {
  822. this.$router.push({name: 'AnalyseDemand'})
  823. },
  824. handleAccept(index, id) {
  825. console.log('接收')
  826. },
  827. handleReject(index, id) {
  828. console.log('拒绝')
  829. },
  830. loadData() {
  831. this.showLoading()
  832. Http.get(Apis.PROJECT.GET_PROJECT.replace('{projectId}', this.projectId)).then((res) => {
  833. this.project.desc = res.projectDetails.desc
  834. this.project.doc = []
  835. this.project.file = []
  836. this.project.resource = res.projectDetails.resource
  837. this.project.location = getProvinceCodeByProvinceName(res.projectDetails.location.provinceCode, res.projectDetails.location.cityCode)
  838. this.project.datetime = new Date(res.projectDetails.datetime)
  839. this.project.fileUrl = res.projectDetails.file
  840. this.project.requireDocUrl = res.projectDetails.doc
  841. this.project.userId = res.projectDetails.userId
  842. this.project.status = res.projectDetails.status
  843. this.project.statusVO = res.projectDetails.statusVO
  844. this.task = res.taskList
  845. this.reportList = res.reportList
  846. this.progress = res.progress
  847. this.changeValue(res);
  848. this.hideLoading()
  849. this.handleShowTaskListOrNot()
  850. for (var i = 0; i < this.progress.length; i++) {
  851. if (this.progress[i].value != 0) {
  852. this.setEcharts()
  853. break
  854. }
  855. }
  856. }).catch((error) => {
  857. this.hideLoading()
  858. // notify('error', error.data)
  859. })
  860. },
  861. handleShowTaskListOrNot() {
  862. // console.log(storageGet('user')['userVO']['id'])
  863. if (storageGet('user')['userVO']['id'] === this.project.userId) {
  864. this.showTaskList = false
  865. }
  866. },
  867. locationChange(provinceId, cityId) {
  868. if (provinceId || cityId) {
  869. this.project.location = {provinceCode: provinceId, cityCode: cityId}
  870. }
  871. },
  872. handleRemove(file, fileList) {
  873. console.log(file, fileList)
  874. },
  875. handleExceed(files, fileList) {
  876. this.$message.warning(
  877. `当前限制选择 1 个文件,本次选择了 ${
  878. files.length
  879. } 个文件,共选择了 ${files.length + fileList.length} 个文件`
  880. )
  881. },
  882. beforeRemove(file, fileList) {
  883. //return this.$confirm(`确定移除 ${file.name}?`)
  884. },
  885. beforeUploadRequireDoc() {
  886. },
  887. beforeUploadApkFile() {
  888. },
  889. uploadRequireDoc(param) {
  890. this.showLoading()
  891. const formData = new FormData()
  892. let config = {
  893. //添加请求头
  894. headers: {'Content-Type': 'multipart/form-data'},
  895. }
  896. formData.append('file', param.file)
  897. Http.upload(Apis.FILE.REQUIREMENT_FILE.replace('{userId}', this.user.userVO.id), formData, config).then((res) => {
  898. this.project.requireDocUrl = res.data
  899. this.hideLoading()
  900. notify('success', '需求文档上传成功')
  901. }).catch((error) => {
  902. this.hideLoading()
  903. notify('error', '需求文档上传失败:' + error.data)
  904. })
  905. },
  906. uploadApkFile(param) {
  907. this.showLoading()
  908. const formData = new FormData()
  909. let config = {
  910. //添加请求头
  911. headers: {'Content-Type': 'multipart/form-data'},
  912. }
  913. formData.append('file', param.file)
  914. Http.upload(Apis.FILE.APK.replace('{userId}', this.user.userVO.id), formData, config).then((res) => {
  915. this.project.fileUrl = res.data
  916. this.hideLoading()
  917. notify('success', '文件上传成功')
  918. }).catch((error) => {
  919. this.hideLoading()
  920. this.project.file = []
  921. notify('error', '文件上传失败')
  922. })
  923. },
  924. setServiceType() {
  925. getAllServiceTypes().then((res) => {
  926. this.serviceType = res
  927. })
  928. },
  929. setPlatformType() {
  930. getAllApplicationTypes().then((res) => {
  931. console.log(res)
  932. this.platforms = res
  933. })
  934. },
  935. setFields() {
  936. getAllFields().then((res) => {
  937. this.fields = res
  938. })
  939. },
  940. setInstitutions() {
  941. getAllInstitutions().then((res) => {
  942. this.institutionArray = res
  943. }).catch((error) => {
  944. notify('error', '获取institution失败' + error.data)
  945. })
  946. },
  947. setUserInfo() {
  948. this.user = storageGet('user')
  949. },
  950. checkPhoneNumber(phoneNumber) {
  951. return /^1[3456789]\d{9}$/.test(phoneNumber)
  952. },
  953. showLoading() {
  954. this.loading = true
  955. },
  956. hideLoading() {
  957. this.loading = false
  958. },
  959. reformDate(date) {
  960. return getFormalTimeFromDate(date)
  961. },
  962. dateFormat(date, format) {
  963. date = new Date(date)
  964. let o = {
  965. 'M+': date.getMonth() + 1, //month
  966. 'd+': date.getDate(), //day
  967. 'H+': date.getHours(), //hour+8小时
  968. 'm+': date.getMinutes(), //minute
  969. 's+': date.getSeconds(), //second
  970. 'q+': Math.floor((date.getMonth() + 3) / 3), //quarter
  971. 'S': date.getMilliseconds() //millisecond
  972. }
  973. if (/(y+)/.test(format)) {
  974. format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
  975. }
  976. for (let k in o)
  977. if (new RegExp('(' + k + ')').test(format))
  978. format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
  979. return format;
  980. }
  981. }
  982. }
  983. </script>
  984. <style lang="scss" scoped>
  985. .task-list {
  986. margin: 0 30px;
  987. }
  988. .el-col {
  989. padding: 0 !important;
  990. }
  991. .el-row {
  992. margin-bottom: 10px;
  993. }
  994. .el-input {
  995. width: 400px;
  996. }
  997. </style>