rehearsalTaskSign.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <template>
  2. <div>
  3. <NavBar :go="{ type: 'push', path: goBack }" />
  4. <div class="mainItem">
  5. <div class="label">标题</div>
  6. <div>{{ trainingData.title }}</div>
  7. </div>
  8. <div class="mainItem">
  9. <div class="label">单位名称</div>
  10. <div>{{ trainingData.orgName }}</div>
  11. </div>
  12. <div class="mainItem">
  13. <div class="label">演练开始时间</div>
  14. <div>{{ trainingData.drillStartDateTime }}</div>
  15. </div>
  16. <div class="mainItem">
  17. <div class="label">演练结束时间</div>
  18. <div>{{ trainingData.drillEndDateTime }}</div>
  19. </div>
  20. <div class="mainItem">
  21. <div class="label">演练地点</div>
  22. <div>{{ trainingData.drillSite }}</div>
  23. </div>
  24. <div class="mainItem mainItemData">
  25. <p class="label labelPeople">演练计划资料</p>
  26. <div>
  27. <div v-for="item in studyList" :key="item.name">
  28. <van-tag type="primary" class="tagCls" plain @click="tagHandler(item)">{{ item.name }}</van-tag>
  29. </div>
  30. </div>
  31. </div>
  32. <div class="mainItem">
  33. <div class="label">指挥人</div>
  34. <div>{{ trainingData.hostName }}</div>
  35. </div>
  36. <div class="mainItem">
  37. <div class="label">演练项目</div>
  38. <div>{{ trainingData.typeText }}</div>
  39. </div>
  40. <div class="mainItem">
  41. <div class="label">预设案由</div>
  42. <div>{{ trainingData.presetCase }}</div>
  43. </div>
  44. <div class="mainItem">
  45. <div class="label">演练情况</div>
  46. <div>{{ trainingData.drillSituation }}</div>
  47. </div>
  48. <div class="mainItem">
  49. <div class="label">参与人员</div>
  50. <div>{{ taskUserList }}</div>
  51. </div>
  52. <div class="mainItem">
  53. <div class="label">缺席人员</div>
  54. <div>{{ qsUserList }}</div>
  55. </div>
  56. <div class="mainItem">
  57. <div class="label">上传图片</div>
  58. <imgCom :width="'100'" v-for="item in imgList" :list="imgList" :key="item" :height="'100'" :src="item"></imgCom>
  59. </div>
  60. <div class="mainItem" v-if="peopleShow">
  61. <div class="label labelPeople">参与人员签名图片</div>
  62. <template v-for="item in signUserList">
  63. <imgCom :width="'100'" v-if="item.signImage" :list="signUserListMap" :key="item.userId" :height="'100'" :src="item.signImage"></imgCom>
  64. </template>
  65. </div>
  66. <div class="mainItem" v-if="evaluate">
  67. <div class="label">评分</div>
  68. <div><van-rate :disabled="disabledShow" v-model="value" :count="10" /></div>
  69. </div>
  70. <van-field
  71. v-if="evaluate"
  72. required
  73. :rules="[{ required: true, message: '评语不能为空' }]"
  74. v-model="content"
  75. name="content"
  76. label="评语"
  77. type="textarea"
  78. row="3"
  79. maxlength="200"
  80. show-word-limit
  81. placeholder="请填写评语"
  82. />
  83. <div class="mainItem" v-if="disabledShow">
  84. <div class="label">评分</div>
  85. <div>{{ value }}分</div>
  86. </div>
  87. <div class="mainItem" v-if="disabledShow">
  88. <div class="label">评语</div>
  89. <div>{{ content }}</div>
  90. </div>
  91. <div class="mainItem" v-if="islearning">
  92. <div class="label">评优状态</div>
  93. <div>{{ trainingData.recStatusText }}</div>
  94. </div>
  95. <div class="mainItem" v-if="$route.params.id.split('_')[1] === 'comment'">
  96. <!-- <div class="label"></div> -->
  97. <div>
  98. <van-checkbox-group v-model="result" direction="horizontal" @change="clickChekcBox($event)">
  99. <van-checkbox
  100. v-for="item in resultList"
  101. :key="item.value"
  102. :disabled="item.disabled"
  103. shape="square"
  104. :checked="item.checked"
  105. :name="item.value"
  106. >{{ item.name }}</van-checkbox
  107. >
  108. </van-checkbox-group>
  109. </div>
  110. </div>
  111. <van-row>
  112. <van-col span="24" class="btns">
  113. <!-- 签名 -->
  114. <van-button
  115. type="info"
  116. class="btn"
  117. v-if="this.$route.params.id.split('_')[1] === 'edit'"
  118. @click="signatureHandler"
  119. >签名</van-button
  120. >
  121. <!-- 评价 || 评优推优选 -->
  122. <van-button
  123. type="info"
  124. class="btn"
  125. v-if="this.$route.params.id.split('_')[1] === 'evaluate' || this.$route.params.id.split('_')[1] === 'comment'"
  126. @click="submitHandler"
  127. >提交</van-button
  128. >
  129. </van-col>
  130. </van-row>
  131. <van-action-sheet v-model="show" title="签署名字" class="sheet">
  132. <writingPad ref="esign" @resultImg="resultImg"></writingPad>
  133. </van-action-sheet>
  134. </div>
  135. </template>
  136. <script>
  137. import NavBar from '@/components/NavBar'
  138. import writingPad from '@/components/writingPad/index.vue'
  139. import { getrehearsalInfo, singrehearsalTask, drillSignInfo } from '@/api/drillTask.js'
  140. import { submitRecTask } from '@/api/optimalLearning.js'
  141. import { upload } from '@/api/public'
  142. import imgCom from '@/components/imgCom/index.vue'
  143. import { base64ToBlob } from '@/utils/base64TurnImg.js'
  144. import config from '@/config/index'
  145. import { Toast, Dialog } from 'vant'
  146. import VuePdf from '@/components/pdfCom/index.vue'
  147. export default {
  148. name: 'SocAppAddTraining',
  149. components: {
  150. NavBar,
  151. Dialog,
  152. Toast,
  153. VuePdf,
  154. imgCom,
  155. writingPad
  156. },
  157. data() {
  158. return {
  159. result: [],
  160. orgType: '', //机构类型
  161. content: '', //评语
  162. value: 0, //评分
  163. this_window: window,
  164. show: false,
  165. resultList: [],
  166. taskUserList: [], //参与人员
  167. qsUserList: [], //缺席人员
  168. imgList: [], //图片数组
  169. signUserList: [], //参与人员签名数组
  170. signUserListMap: [], //参与人员签名数组Map
  171. studyList: [], //学习资料数组
  172. trainingData: {} //详情数据
  173. }
  174. },
  175. computed: {
  176. goBack() {
  177. if (
  178. this.$route.params.id.split('_')[1] === 'evaluate' ||
  179. this.$route.params.id.split('_')[1] === 'edit' ||
  180. this.$route.params.id.split('_')[1] === 'info'
  181. ) {
  182. return '/rehearsalTask'
  183. } else if (this.$route.params.id.split('_')[1] === 'comment') {
  184. return '/rehearsaloptimal'
  185. } else if (this.$route.params.id.split('_')[1] === 'learning') {
  186. return '/rehearsallearning'
  187. } else if (this.$route.params.id.split('_')[1] === 'info1') {
  188. return '/rehearsaloptimal'
  189. }
  190. },
  191. evaluate() {
  192. if (this.$route.params.id.split('_')[1] === 'evaluate') {
  193. return true
  194. } else {
  195. return false
  196. }
  197. },
  198. disabledShow() {
  199. if (
  200. this.$route.params.id.split('_')[1] === 'info' ||
  201. this.$route.params.id.split('_')[1] === 'info1' ||
  202. this.$route.params.id.split('_')[1] === 'comment' ||
  203. this.$route.params.id.split('_')[1] === 'learning'
  204. ) {
  205. return true
  206. } else {
  207. return false
  208. }
  209. },
  210. islearning() {
  211. if (this.$route.params.id.split('_')[1] === 'learning') {
  212. return true
  213. } else {
  214. return false
  215. }
  216. },
  217. peopleShow() {
  218. if (
  219. this.$route.params.id.split('_')[1] === 'info' ||
  220. this.$route.params.id.split('_')[1] === 'info1' ||
  221. this.$route.params.id.split('_')[1] === 'comment' ||
  222. this.$route.params.id.split('_')[1] === 'learning'
  223. ) {
  224. return true
  225. } else {
  226. return false
  227. }
  228. }
  229. },
  230. created() {
  231. //获取详情信息
  232. getrehearsalInfo(this.$route.params.id.split('_')[0]).then(res => {
  233. let { code, data, msg } = res
  234. if (code == 200) {
  235. this.content = data.comment
  236. this.value = +data.commentScore
  237. this.trainingData = data
  238. if (this.trainingData.taskUserList && this.trainingData.taskUserList.length > 0) {
  239. this.trainingData.taskUserList.forEach(item => {
  240. if (item.type == 1) {
  241. this.taskUserList.push(item.userName)
  242. } else {
  243. this.qsUserList.push(item.userName)
  244. }
  245. })
  246. }
  247. this.taskUserList = this.taskUserList.join(',')
  248. this.qsUserList = this.qsUserList.join(',')
  249. this.signUserList = data.taskUserList || []
  250. this.signUserListMap = data.taskUserList.map(item=>item.signImage) || []
  251. let list = data.fileList || []
  252. if (list.length > 0) {
  253. list.forEach(item => {
  254. let i = JSON.parse(item)
  255. if (i.url.split('.')[1] == 'pdf') {
  256. i.type = 1
  257. } else {
  258. i.type = 0
  259. }
  260. this.studyList.push(i)
  261. })
  262. }
  263. this.imgList = this.trainingData.imageList.split(',') || []
  264. //获取当前登录人机构类型
  265. this.orgType = window.sessionStorage.getItem('SET_USER_ORGTYPE')
  266. console.log(this.orgType, 'this.orgType')
  267. if (this.orgType == 1) {
  268. //省联社
  269. this.resultList = [
  270. {
  271. name: '设置为省级优秀案例',
  272. value: 5,
  273. disabled: false
  274. }
  275. ]
  276. if (data.recStatus == 5) {
  277. this.result = [5]
  278. }
  279. } else if (this.orgType == 2) {
  280. //办事处
  281. this.resultList = [
  282. {
  283. name: '设置为地区优秀案例',
  284. value: 3,
  285. disabled: false
  286. },
  287. {
  288. name: '推荐为省级优秀案例',
  289. value: 4,
  290. disabled: true
  291. }
  292. ]
  293. if (data.recStatus == 4) {
  294. this.result = [3, 4]
  295. } else if (data.recStatus == 3) {
  296. this.result = [3]
  297. }
  298. } else if (this.orgType == 3) {
  299. //行社
  300. this.resultList = [
  301. {
  302. name: '设置为行社优秀案例',
  303. value: 1,
  304. disabled: false
  305. },
  306. {
  307. name: '推荐为地区优秀案例',
  308. value: 2,
  309. disabled: true
  310. }
  311. ]
  312. if (data.recStatus == 2) {
  313. this.result = [1, 2]
  314. } else if (data.recStatus == 1) {
  315. this.result = [1]
  316. }
  317. }
  318. }
  319. })
  320. },
  321. mounted() {},
  322. methods: {
  323. disabledCheck(item) {
  324. if (item == 'false') return false
  325. if (item == 'true') return true
  326. //当前是最后一个复选框禁用
  327. if (this.resultList.length > 1 && item.value == this.resultList[this.resultList.length - 1].value) {
  328. return true
  329. } else {
  330. return false
  331. }
  332. },
  333. clickChekcBox(v) {
  334. console.log(v)
  335. console.log(this.resultList[0])
  336. if (v[0] == this.resultList[0].value) {
  337. if (this.resultList[1]) {
  338. this.resultList[1].disabled = this.disabledCheck('false')
  339. }
  340. // if(v.length>1){
  341. // this.result=[]
  342. // }
  343. // this.resultList[1].checked = this.disabledCheck('false')
  344. } else if (v[0] > this.resultList[0].value) {
  345. this.result = []
  346. } else {
  347. this.resultList[1].disabled = this.disabledCheck('true')
  348. // this.result=[]
  349. }
  350. },
  351. signatureHandler() {
  352. this.show = true
  353. },
  354. //评价提交
  355. submitHandler() {
  356. //判断当前是评价 还是评价推优
  357. if (this.$route.params.id.split('_')[1] === 'evaluate') {
  358. //评价
  359. if (!this.content) {
  360. //评语不能为空
  361. Toast('评语不能为空')
  362. return
  363. } else if (this.value == 0) {
  364. //评分不能为0分
  365. Toast('评分不能为0分')
  366. return
  367. }
  368. Dialog.confirm({
  369. title: '',
  370. message: `是否提交评价?`
  371. })
  372. .then(() => {
  373. drillSignInfo({
  374. taskId: this.trainingData.id,
  375. // type: this.trainingData.type,
  376. score: this.value,
  377. comment: this.content
  378. }).then(res => {
  379. let { code, msg } = res
  380. if (code == 200) {
  381. Toast('评价成功')
  382. setTimeout(() => {
  383. this.$router.push('/rehearsalTask')
  384. }, 1000)
  385. } else {
  386. Toast(msg)
  387. }
  388. })
  389. })
  390. .catch(() => {
  391. // on cancel
  392. })
  393. } else {
  394. //评价推优
  395. submitRecTask({
  396. drillTaskId: this.trainingData.id,
  397. recStatus: Math.max(...this.result)
  398. }).then(res => {
  399. if (this.result && this.result.length > 0) {
  400. Toast('评优成功')
  401. } else {
  402. Toast('取消成功')
  403. }
  404. setTimeout(() => {
  405. this.$router.push('/rehearsaloptimal')
  406. }, 1000)
  407. })
  408. }
  409. },
  410. clearHandler() {
  411. this.$refs.esign.handleReset()
  412. },
  413. //上传签名图到服务器
  414. resultImg(img) {
  415. let obj = base64ToBlob(img)
  416. let formData = new FormData()
  417. obj.name = '签名.jpg'
  418. formData.append('file', base64ToBlob(img))
  419. upload(formData, 'image')
  420. .then(res => {
  421. console.log(process.env.NODE_ENV)
  422. /*上传成功*/
  423. let imgUrl = process.env.NODE_ENV === 'development' ? res.data.url : res.data.url
  424. this.submitSign(imgUrl)
  425. // this.$emit("imgUrl", res.data.url);
  426. })
  427. .catch(err => {
  428. /*上传失败*/
  429. })
  430. },
  431. tagHandler(i) {
  432. let str = i.name.split('.')[1]
  433. if (str == 'png' || str == 'jpg' || str == 'jpeg' || str == 'pdf') {
  434. //当前是图片||PDF
  435. this.openFilePreview(i)
  436. } else {
  437. const filePath = `${process.env.NODE_ENV === 'development' ? '/dev' : window.origin}${i.url}`
  438. const tempLink = document.createElement('a')
  439. tempLink.style.display = 'none'
  440. tempLink.href = filePath
  441. tempLink.setAttribute('download', i.name)
  442. tempLink.setAttribute('target', '_blank')
  443. document.body.appendChild(tempLink)
  444. tempLink.click()
  445. document.body.removeChild(tempLink)
  446. }
  447. },
  448. //提交到后端数据
  449. submitSign(url) {
  450. singrehearsalTask({
  451. id: this.trainingData.id,
  452. signImage: url
  453. }).then(res => {
  454. this.$router.push('/rehearsalTask')
  455. })
  456. }
  457. }
  458. }
  459. </script>
  460. <style lang="scss" scoped>
  461. .mainItem {
  462. display: flex;
  463. font-size: 28px;
  464. align-items: center;
  465. padding: 34px;
  466. justify-content: space-between;
  467. background-color: #fff;
  468. flex-wrap: wrap;
  469. div {
  470. flex: 1;
  471. text-align: left;
  472. }
  473. p {
  474. }
  475. .label {
  476. width: 230px;
  477. flex: none;
  478. }
  479. .labelPeople {
  480. margin-bottom: 20px;
  481. }
  482. }
  483. .mainItemData {
  484. justify-content: end;
  485. }
  486. .tagCls {
  487. margin-bottom: 20px;
  488. margin-left: 10px;
  489. }
  490. .btns {
  491. background-color: #fff;
  492. width: 100%;
  493. }
  494. .btn {
  495. width: 100%;
  496. }
  497. .sheet {
  498. height: 45%;
  499. }
  500. </style>