index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. <template>
  2. <view class="container">
  3. <page-title>周报录入</page-title>
  4. <view class="cards-list">
  5. <view class="card only-card">
  6. <!-- 项目名称 -->
  7. <view class="card-item first-card-item">
  8. <view class="card-item-name">项目名称</view>
  9. <view class="card-item-input">{{pageForm.subName || "--"}}</view>
  10. </view>
  11. <!-- 主体单位 -->
  12. <view class="card-item">
  13. <view class="card-item-name">主体单位</view>
  14. <view class="card-item-input">{{pageForm.UnitName || "--"}}</view>
  15. </view>
  16. <!-- 录入周期 -->
  17. <view class="card-item">
  18. <view class="card-item-name">录入周期</view>
  19. <view class="card-item-input">{{editTime || "--"}}</view>
  20. </view>
  21. <!-- 当前阶段 -->
  22. <!-- <view class="card-item">
  23. <view class="card-item-name">当前阶段</view>
  24. <view class="card-item-name flex" @click="subPlanOpen()">
  25. <view v-if="pageForm.subPlanId" class="card-item-input">{{pageForm.subPlanId}}</view>
  26. <view v-else class="remind-text">请选择阶段</view>
  27. <u-icon name="arrow-right" color="#343437" size="16" customStyle="margin:auto 0 auto 10rpx"></u-icon>
  28. </view>
  29. </view> -->
  30. <!-- 当前阶段内容 -->
  31. <!-- <view class="card-item">
  32. <view class="card-item-name">当前阶段内容</view>
  33. </view>
  34. <view class="card-item">
  35. <u--textarea class="card-item-textarea" v-model="pageForm.content" disabled></u--textarea>
  36. </view> -->
  37. <!-- 项目进展情况 -->
  38. <view class="card-item">
  39. <view class="card-item-name">项目进展情况<span class="must-input">*</span></view>
  40. </view>
  41. <view class="card-item">
  42. <u--textarea class="card-item-textarea" v-model="pageForm.content" :disabled="banSubmit"></u--textarea>
  43. </view>
  44. <!-- 项目延期原因 -->
  45. <view class="card-item">
  46. <view class="card-item-name">项目延期原因</view>
  47. </view>
  48. <view class="card-item">
  49. <u--textarea class="card-item-textarea" v-model="pageForm.reason" :disabled="banSubmit"></u--textarea>
  50. </view>
  51. <!-- 进度 -->
  52. <view class="card-item">
  53. <view class="card-item-name">进度<span class="must-input">*</span></view>
  54. <view class="card-item-name flex">
  55. <input type="number" v-model="pageForm.numBl" class="card-item-input" placeholder="填写进度"
  56. placeholder-style="color: #D8D8D8" maxlength="20" :disabled="banSubmit" />
  57. <view class="card-item-unit">%</view>
  58. </view>
  59. </view>
  60. <!-- 附件(照片) -->
  61. <view class="card-item flex-align-start">
  62. <view class="card-item-name" style="min-width: 156rpx;">图片附件</view>
  63. <u-upload :fileList="uploadListPhoto" @afterRead="afterReadPhoto" @delete="delFilePhoto"
  64. uploadIcon="plus"></u-upload>
  65. </view>
  66. <!-- 附件(视频) -->
  67. <view class="card-item flex-align-start">
  68. <view class="card-item-name" style="min-width: 156rpx;">视频附件</view>
  69. <u-upload :fileList="uploadListVideo" @afterRead="afterReadVideo" @delete="delFileVideo"
  70. @onVideoClick="videoClick" name="file" uploadIcon="plus" accept="video"></u-upload>
  71. </view>
  72. <!-- 附件(文件) -->
  73. <view class="card-item flex-align-start">
  74. <view class="card-item-name" style="min-width: 156rpx;">其他附件</view>
  75. <view class="upload-file-area">
  76. <view class="upload-file-name" v-for="(item,index) in uploadListFile" :key="index"
  77. @click="showFile('pdf',item.url)">
  78. {{item.fileName}}
  79. </view>
  80. </view>
  81. </view>
  82. </view>
  83. <view class="confirm-btn" :class="banSubmit?'ban-submit':''" @click="confirmParams()">确定</view>
  84. </view>
  85. <!-- 当前阶段 -->
  86. <u-picker :show="subPlanShow" :columns="subPlanList" @confirm="subPlanClose" @cancel="subPlanClose"
  87. @close="subPlanClose" closeOnClickOverlay></u-picker>
  88. </view>
  89. </template>
  90. <script setup>
  91. import config from '@/config.js'
  92. import {
  93. ref
  94. } from 'vue'
  95. import {
  96. onLoad
  97. } from "@dcloudio/uni-app"
  98. import {
  99. uploadFilePromise
  100. } from "@/utils/request_new.js"
  101. import {
  102. getWeeklyById,
  103. saveWeekly
  104. } from "@/api/work/weeklyAndMonthly.js"
  105. let editTime = ref(null)
  106. let pageForm = ref({
  107. year: null,
  108. beginDate: null,
  109. endDate: null,
  110. subId: null,
  111. subName: null,
  112. UnitName: null,
  113. subPlanId: null,
  114. content: null,
  115. reason: null,
  116. numBl: null,
  117. listFile: [],
  118. })
  119. let fileTypeCode = {
  120. 0: "dir",
  121. 1: "txt",
  122. 2: "doc",
  123. 3: "docx",
  124. 4: "xls",
  125. 5: "xlsx",
  126. 6: "ppt",
  127. 7: "pptx",
  128. 8: "pdf",
  129. 9: "swf",
  130. 101: "jpg",
  131. 102: "image",
  132. 103: "jpeg",
  133. 104: "bmp",
  134. 105: "gif",
  135. 201: "avi",
  136. 202: "wmv",
  137. 202: "flv",
  138. 203: "video"
  139. }
  140. // 当前阶段
  141. let subPlanShow = ref(false)
  142. let subPlanList = ref([])
  143. let subPlanContentList = ref([])
  144. function subPlanOpen() {
  145. subPlanShow.value = true
  146. }
  147. function subPlanClose(e) {
  148. if (e) {
  149. pageForm.value.subPlanId = e.value[0]
  150. pageForm.value.content = subPlanContentList.value.find(item => item.time === e.value[0]).content
  151. }
  152. subPlanShow.value = false
  153. }
  154. function parseDate(date, year) {
  155. pageForm.value.year = year;
  156. const index = date.indexOf("至")
  157. pageForm.value.beginDate = date.substring(0, index)
  158. pageForm.value.endDate = date.substring(index + 1)
  159. }
  160. // 获取数据
  161. function getWeeklyDetail(sendParams) {
  162. let params = {
  163. subId: sendParams.subId,
  164. startDate: sendParams.startDate,
  165. year: sendParams.year
  166. }
  167. getWeeklyById(params).then(res => {
  168. pageForm.value.subName = res.data.subName;
  169. pageForm.value.UnitName = res.data.UnitName;
  170. pageForm.value.subId = res.data.subId;
  171. pageForm.value.numBl = res.data.weekInfo.numBl;
  172. pageForm.value.content = res.data.weekInfo.content;
  173. pageForm.value.reason = res.data.weekInfo.reason;
  174. // combinePlanList(res.data.subPlanList)
  175. // showHavingData(sendParams)
  176. conbineFileList(res.data.listFile)
  177. })
  178. }
  179. function combinePlanList(list) {
  180. let subPlanListItem = []
  181. let subPlanContentListTemp = []
  182. for (let i in list) {
  183. let showName = `${list[i].beginDate}至${list[i].endDate}`;
  184. let content = list[i].content;
  185. let id = list[i].id;
  186. subPlanListItem.push(showName)
  187. subPlanContentListTemp.push({
  188. id,
  189. content,
  190. time: showName,
  191. })
  192. }
  193. subPlanList.value.push(subPlanListItem)
  194. subPlanContentList.value = subPlanContentListTemp
  195. }
  196. // 展示已有数据
  197. function showHavingData(data) {
  198. // pageForm.value.numBl = data.num_bl
  199. if (data.sub_plan_id) {
  200. let statuItem = subPlanContentList.value.find(item => item.id === data.sub_plan_id)
  201. if (statuItem) {
  202. pageForm.value.content = statuItem.content;
  203. pageForm.value.subPlanId = statuItem.time
  204. }
  205. }
  206. }
  207. // 组合附件数据
  208. function conbineFileList(list) {
  209. // 添加上传成功标识
  210. const statusList = list.map(item => {
  211. let orginal = {
  212. ...item
  213. }
  214. return Object.assign(
  215. orginal, {
  216. status: 'success'
  217. })
  218. })
  219. // 照片附件
  220. let listPhoto = statusList.filter(item => ['101', '102', '103', '104', '105'].includes(item.fileType))
  221. uploadListPhoto.value = listPhoto
  222. // 视频附件
  223. let listVideo = statusList.filter(item => ['202', '203'].includes(item.fileType));
  224. uploadListVideo.value = listVideo;
  225. // 其他附件
  226. let exceptPhotoList = statusList.filter(item => !listPhoto.includes(item));
  227. uploadListFile.value = exceptPhotoList.filter(item => !listVideo.includes(item));
  228. // 上传数据
  229. const dataList = list.map(item => {
  230. let orginal = {
  231. ...item
  232. }
  233. return {
  234. id: orginal.id,
  235. fileName: orginal.fileName,
  236. fileType: orginal.fileType,
  237. fileAddre: orginal.fileAddre
  238. }
  239. })
  240. pageForm.value.listFile = dataList
  241. // 备份初始数据
  242. listFileOrginal = dataList
  243. }
  244. // ====================附件上传
  245. let listFileOrginal = [] //原始数据--备份比较用
  246. let uploadListPhoto = ref([]) //上传列表--图片
  247. let uploadListVideo = ref([]) //上传列表--视频
  248. let uploadListFile = ref([]) //上传列表--文件
  249. // 上传文件操作
  250. async function afterReadPhoto(event) {
  251. if (banSubmit.value) return
  252. let lists = [].concat(event.file); //文件内容
  253. let fileListLen = uploadListPhoto.value.length; //数量
  254. lists.map((item) => {
  255. uploadListPhoto.value.push({
  256. ...item,
  257. status: 'uploading',
  258. message: '上传中'
  259. })
  260. })
  261. for (let i = 0; i < lists.length; i++) {
  262. const resultObj = await uploadFilePromise(lists[i].url);
  263. // console.log(resultObj);
  264. let fileItem = {
  265. fileName: resultObj.data.resultList[0].name,
  266. fileType: resultObj.data.resultList[0].ftype,
  267. fileAddre: resultObj.data.resultList[0].id
  268. }
  269. pageForm.value.listFile.push(fileItem)
  270. // 上传地址
  271. const serverAddress = uni.getStorageSync("serverAddress");
  272. const baseUrlIp = serverAddress ? serverAddress : config.baseUrl;
  273. const preViewUrl = baseUrlIp + "/projects//static/file/";
  274. // =================取消上传中状态
  275. // 文件
  276. let item = uploadListPhoto.value[fileListLen]
  277. // 文件类型
  278. let type = fileTypeCode[resultObj.data.resultList[0].ftype]
  279. uploadListPhoto.value.splice(fileListLen, 1, Object.assign(item, {
  280. status: 'success',
  281. message: '',
  282. url: preViewUrl + resultObj.data.resultList[0].id + "/showfile",
  283. id: resultObj.data.resultList[0].id,
  284. preView: preViewUrl + resultObj.data.resultList[0].id + "/showfile",
  285. // type
  286. }))
  287. fileListLen++
  288. }
  289. }
  290. // 删除文件
  291. function delFilePhoto(event) {
  292. if (banSubmit.value) return
  293. // 从渲染列表里移除
  294. uploadListPhoto.value.splice(event.index, 1);
  295. // 从文件里删除或标记
  296. let delFileIndex = pageForm.value.listFile.findIndex(item => item.fileAddre === event.file.fileAddre || item
  297. .fileAddre ===
  298. event.file.id);
  299. let delFile = pageForm.value.listFile[delFileIndex];
  300. // 是否是已经上传的文件
  301. if (delFile && delFile.id) {
  302. // 已保存
  303. delFile.logicDeleteFlag = 1
  304. } else {
  305. pageForm.value.listFile.splice(delFileIndex, 1)
  306. }
  307. }
  308. function waterMarkShow(event) {
  309. return uni.navigateTo({
  310. url: `/pages/weekly/media/index?url=${event.url}&time=${event.createTime}`
  311. })
  312. }
  313. // 上传文件操作--视频
  314. async function afterReadVideo(event) {
  315. if (banSubmit.value) return
  316. let lists = [].concat(event.file); //文件内容
  317. let fileListLen = uploadListVideo.value.length; //数量
  318. lists.map((item) => {
  319. uploadListVideo.value.push({
  320. ...item,
  321. status: 'uploading',
  322. message: '上传中'
  323. })
  324. })
  325. for (let i = 0; i < lists.length; i++) {
  326. const resultObj = await uploadFilePromise(lists[i].url);
  327. let fileItem = {
  328. fileName: resultObj.data.resultList[0].name,
  329. fileType: resultObj.data.resultList[0].ftype,
  330. fileAddre: resultObj.data.resultList[0].id
  331. }
  332. pageForm.value.listFile.push(fileItem)
  333. // 上传地址
  334. const serverAddress = uni.getStorageSync("serverAddress");
  335. const baseUrlIp = serverAddress ? serverAddress : config.baseUrl;
  336. const preViewUrl = baseUrlIp + "/projects//static/file/";
  337. // =================取消上传中状态
  338. // 文件
  339. let item = uploadListVideo.value[fileListLen]
  340. // 文件类型
  341. let type = fileTypeCode[resultObj.data.resultList[0].ftype]
  342. uploadListVideo.value.splice(fileListLen, 1, Object.assign(item, {
  343. status: 'success',
  344. message: '',
  345. url: preViewUrl + resultObj.data.resultList[0].id + "/showfile",
  346. id: resultObj.data.resultList[0].id,
  347. preView: preViewUrl + resultObj.data.resultList[0].id + "/showfile",
  348. // type
  349. }))
  350. fileListLen++
  351. }
  352. }
  353. // 删除文件--视频
  354. function delFileVideo(event) {
  355. if (banSubmit.value) return
  356. uploadListVideo.value.splice(event.index, 1);
  357. // 从文件里删除或标记
  358. let delFileIndex = pageForm.value.listFile.findIndex(item => item.fileAddre === event.file.fileAddre || item
  359. .fileAddre ===
  360. event.file.id);
  361. let delFile = pageForm.value.listFile[delFileIndex];
  362. // 是否是已经上传的文件
  363. if (delFile && delFile.id) {
  364. // 已保存
  365. delFile.logicDeleteFlag = 1
  366. } else {
  367. pageForm.value.listFile.splice(delFileIndex, 1)
  368. }
  369. }
  370. // 播放文件--视频
  371. function videoClick(event) {
  372. showFile(event.fileType, event.url)
  373. }
  374. // 文件预览
  375. function showFile(type, filePath) {
  376. uni.navigateTo({
  377. url: `/pages/projectInfo/media/index?type=${type}&filePath=${filePath}`
  378. })
  379. }
  380. //====================提交数据
  381. let banSubmit = ref(false);
  382. let isSubmit = ref(false);
  383. // 提交操作
  384. function confirmParams() {
  385. // 禁止提交
  386. if (banSubmit.value || isSubmit.value) return;
  387. // 检查必填项
  388. if (((pageForm.value.content ?? '') === '') || ((pageForm.value.numBl ?? '') === '')) {
  389. return uni.showModal({
  390. title: '请检查',
  391. content: '进度与项目进展情况为必填项。',
  392. showCancel: false
  393. })
  394. }
  395. // 确认提交
  396. uni.showModal({
  397. title: "保存确认",
  398. content: "确定要保存该周报录入吗?",
  399. success: function(res) {
  400. if (res.confirm) {
  401. let params = Object.assign({}, pageForm.value)
  402. delete(params.UnitName)
  403. delete(params.subName)
  404. let subPlanIdItem = subPlanContentList.value.find(item => item.time === params.subPlanId)
  405. params.subPlanId = subPlanIdItem ? subPlanIdItem.id : null
  406. isSubmit.value = true;
  407. saveWeekly(params).then(res => {
  408. if (res.code === 200) {
  409. isSubmit.value = false;
  410. banSubmit.value = true;
  411. uni.showToast({
  412. title: "保存成功",
  413. icon: "success",
  414. duration: 2000
  415. })
  416. }
  417. }).catch(() => {
  418. isSubmit.value = false;
  419. uni.showToast({
  420. title: "保存失败",
  421. icon: "error",
  422. duration: 2000
  423. })
  424. })
  425. } else if (res.cancel) {
  426. uni.showToast({
  427. title: "取消保存",
  428. icon: "none",
  429. duration: 2000,
  430. })
  431. }
  432. },
  433. })
  434. }
  435. onLoad((options) => {
  436. editTime.value = options.kj_month
  437. parseDate(options.kj_month, options.year)
  438. getWeeklyDetail(options)
  439. })
  440. </script>
  441. <style lang="scss" scoped>
  442. .must-input {
  443. color: #f00;
  444. }
  445. </style>