index.vue 14 KB

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