form.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. <template>
  2. <hc-sys :isNavBar="false">
  3. <uni-notice-bar text="请上传MP4、MOV格式的视频文件,文件大小不超过500M,只能上传1个视频文件" v-if="formData.type === 1"/>
  4. <uni-notice-bar text="请上传JPG、JPEG、PNG格式的图片文件,大小不超过30M,最多10张图片文件" v-if="formData.type === 2"/>
  5. <view class="relative bg-white mt-1 hc-p">
  6. <!-- 图片文件上传 -->
  7. <view class="hc-flex flex-wrap pb-3 mb-5" un-border-b="1 solid gray-2" v-if="formData.type === 2">
  8. <template v-for="(item, index) in fileList" :key="index">
  9. <view class="hc-flex h-120 w-120 b-rounded mr-2 mt-2" @click="previewImg(index)">
  10. <hc-img :src="item" width="60" height="60" class="b-rounded"/>
  11. <view class="hc-tr bg-red-5 text-white text-center w-38 h-38 b-rounded-lb-1 b-rounded-tr-1" @click.stop="delFileClick(index)">
  12. <text class="relative cuIcon-close top--2 text-24"/>
  13. </view>
  14. </view>
  15. </template>
  16. <template v-if="fileList.length < 10">
  17. <view class="hc-flex-center h-120 w-120 b-rounded mt-2" un-border="2 dashed gray-2" @click="addFileClick">
  18. <text class="i-iconoir-plus text-70 text-gray-4"/>
  19. </view>
  20. </template>
  21. </view>
  22. <!-- 视频文件上传 -->
  23. <view class="hc-flex pb-3 mb-5" un-border-b="1 solid gray-2" v-if="formData.type === 1">
  24. <template v-for="(item, index) in fileList" :key="index">
  25. <view class="hc-flex h-120 w-full b-rounded">
  26. <video class="w-full h-full b-rounded" :src="item"/>
  27. <view class="hc-tr bg-red-5 text-white text-center w-38 h-38 b-rounded-lb-1 b-rounded-tr-1 z-24" @click.stop="delFileClick(index)">
  28. <text class="relative cuIcon-close top--2 text-24"/>
  29. </view>
  30. </view>
  31. </template>
  32. <template v-if="fileList.length < 1">
  33. <view class="hc-flex-center h-120 w-full b-rounded" un-border="2 dashed gray-2" @click="addVideoFileClick">
  34. <text class="i-iconoir-plus text-70 text-gray-4"/>
  35. </view>
  36. </template>
  37. </view>
  38. <!-- 表单 -->
  39. <uni-forms ref="formRef" :rules="formRules" :modelValue="formData" :label-width="82">
  40. <uni-forms-item label="题名" required name="title">
  41. <uni-easyinput v-model="formData.title" placeholder="请输入题名" />
  42. </uni-forms-item>
  43. <uni-forms-item label="文字说明" required name="textContent">
  44. <uni-easyinput type="textarea" v-model="formData.textContent" placeholder="请输入文字说明" />
  45. </uni-forms-item>
  46. <uni-forms-item label="拍摄时间" required name="shootingTimeStr">
  47. <uni-datetime-picker type="date" v-model="formData.shootingTimeStr" :end="dateEnd"/>
  48. </uni-forms-item>
  49. <uni-forms-item label="上传日期" required name="uploadTime">
  50. <uni-datetime-picker type="date" v-model="formData.uploadTime" :end="dateEnd"/>
  51. </uni-forms-item>
  52. <uni-forms-item label="拍摄者" required name="shootingUser">
  53. <uni-easyinput v-model="formData.shootingUser" placeholder="请输入拍摄者" />
  54. </uni-forms-item>
  55. <template v-if="formData.type === 2">
  56. <uni-forms-item label="照片号">
  57. <uni-easyinput v-model="formData.photoCode" placeholder="请输入照片号" />
  58. </uni-forms-item>
  59. <uni-forms-item label="底片号">
  60. <uni-easyinput v-model="formData.filmCode" placeholder="请输入底片号" />
  61. </uni-forms-item>
  62. <uni-forms-item label="参见号">
  63. <uni-easyinput v-model="formData.seeAlsoCode" placeholder="请输入参见号" />
  64. </uni-forms-item>
  65. </template>
  66. </uni-forms>
  67. </view>
  68. <!-- 底部操作栏 -->
  69. <HcTabbarBlock :height="70"/>
  70. <hc-tabbars class="flex items-center">
  71. <template v-if="!dataId">
  72. <view class="flex-1 mr-2">
  73. <button hover-class="none" class="cu-btn block bg-orange text-white" @click="continueAdd">继续新增</button>
  74. </view>
  75. <view class="flex-1 ml-2">
  76. <button hover-class="none" class="cu-btn block bg-purple-8 text-white" @click="saveAdd">提交保存</button>
  77. </view>
  78. </template>
  79. <template v-else>
  80. <button hover-class="none" class="cu-btn flex-1 bg-purple-8 text-white" @click="saveClick">提交保存</button>
  81. </template>
  82. </hc-tabbars>
  83. </hc-sys>
  84. </template>
  85. <script setup>
  86. import {ref} from "vue";
  87. import {onLoad, onReady} from '@dcloudio/uni-app'
  88. import mainApi from '~api/image/index';
  89. import {uploadApi} from '~api/upload';
  90. import {getObjValue, isString} from "js-fast-way";
  91. import {errorToast, formValidate, successToast} from "@/utils/tools";
  92. import {chooseImage, chooseVideo} from "@/utils/utils";
  93. import {useAppStore} from "@/store";
  94. import dayjs from "dayjs";
  95. //初始变量
  96. const store = useAppStore()
  97. const userInfo = ref(store.userInfo);
  98. const projectId = ref(store.projectId);
  99. const contractId = ref(store.contractId);
  100. //基础变量
  101. const dataId = ref('');
  102. const fileList = ref([])
  103. const pdfList = ref([])
  104. const dateEnd = ref(dayjs().format("YYYY-MM-DD"));
  105. //页面启动
  106. onLoad(({id, node}) => {
  107. dataId.value = id ?? '';
  108. if (id) {
  109. uni.setNavigationBarTitle({title: '编辑声像文件'})
  110. getInfoApi()
  111. } else {
  112. const nodes = node ? JSON.parse(decodeURIComponent(node)) : {};
  113. const {real_name} = userInfo.value
  114. formData.value = {
  115. projectId: projectId.value,
  116. contractId: contractId.value,
  117. classifyId: nodes.id,
  118. type: nodes.fileType,
  119. wbsId: nodes.treeId,
  120. uploadTime: dateEnd.value,
  121. shootingTimeStr: dateEnd.value,
  122. shootingUser: real_name
  123. }
  124. if (nodes.type === 1) {
  125. getFileTitleNamedata(nodes.treeId)
  126. }
  127. uni.setNavigationBarTitle({title: '新增声像文件'})
  128. }
  129. })
  130. onReady(() => {
  131. // 设置自定义表单校验规则,必须在节点渲染完毕后执行
  132. formRef.value?.setRules(formRules)
  133. })
  134. //获取题名
  135. const getFileTitleNamedata = async (wbsId) => {
  136. const { data } = await mainApi.getFileTitleName({
  137. pKeyId: wbsId
  138. })
  139. formData.value.title = isString(data) ? data: ''
  140. }
  141. //获取详情
  142. const getInfoApi = async () => {
  143. formData.value = {}
  144. if (!dataId.value) {
  145. errorToast('参数异常,请退出重试')
  146. return false;
  147. }
  148. uni.showLoading({title: '获取数据中...', mask: true});
  149. const { data } = await mainApi.queryById({
  150. id: dataId.value
  151. })
  152. const res = getObjValue(data)
  153. formData.value = res
  154. const {imageUrl, pdfUrl} = res
  155. fileList.value = imageUrl.toString().split(',')
  156. pdfList.value = pdfUrl.toString().split(',')
  157. uni.hideLoading();
  158. }
  159. //添加文件
  160. const addFileClick = async () => {
  161. const tempFiles = await chooseImage(10 - fileList.value.length)
  162. if (tempFiles.length > 0) {
  163. uni.showLoading({title: '上传文件中...', mask: true});
  164. }
  165. for (let i = 0; i < tempFiles.length; i++) {
  166. await uploadFile(tempFiles[i].path);
  167. }
  168. uni.hideLoading();
  169. }
  170. //选择视频文件
  171. const addVideoFileClick = async () => {
  172. const {tempFilePath} = await chooseVideo()
  173. if (tempFilePath) {
  174. uni.showLoading({title: '上传文件中...', mask: true});
  175. await uploadFile(tempFilePath);
  176. uni.hideLoading();
  177. }
  178. }
  179. //上传文件
  180. const uploadFile = async (file) => {
  181. const {error, msg, data} = await uploadApi(file)
  182. if (!error) {
  183. const { link, pdfUrl } = getObjValue(data)
  184. fileList.value.push(link)
  185. if (pdfUrl) {
  186. pdfList.value.push(pdfUrl)
  187. }
  188. } else {
  189. errorToast(msg)
  190. }
  191. }
  192. //删除文件
  193. const delFileClick = (index) => {
  194. fileList.value.splice(index, 1)
  195. if (pdfList.value.length > 0) {
  196. pdfList.value.splice(index, 1)
  197. }
  198. }
  199. //预览图片
  200. const previewImg = (index) => {
  201. uni.previewImage({
  202. current: index,
  203. urls: fileList.value,
  204. });
  205. }
  206. //表单验证
  207. const formRef = ref(null)
  208. const formData = ref({})
  209. const formRules = {
  210. title: {
  211. rules: [{
  212. required: true,
  213. errorMessage: '请输入题名'
  214. }]
  215. },
  216. textContent: {
  217. rules: [{
  218. required: true,
  219. errorMessage: '请输入文字说明'
  220. }]
  221. },
  222. shootingTimeStr: {
  223. rules: [{
  224. required: true,
  225. errorMessage: '请选择拍摄时间'
  226. }]
  227. },
  228. uploadTime: {
  229. rules: [{
  230. required: true,
  231. errorMessage: '请选择上传日期'
  232. }]
  233. },
  234. shootingUser: {
  235. rules: [{
  236. required: true,
  237. errorMessage: '请输入拍摄者'
  238. }]
  239. },
  240. }
  241. const isFormValidate = async () => {
  242. if (fileList.value.length <= 0) {
  243. errorToast('请先上传文件')
  244. return false
  245. }
  246. const isForm = await formValidate(formRef.value)
  247. if (!isForm) {
  248. errorToast('请先完善表单')
  249. return false
  250. }
  251. return true
  252. }
  253. //提交保存
  254. const saveClick = async () => {
  255. const isForm = await isFormValidate()
  256. if (!isForm) return false;
  257. //更新数据
  258. if (dataId.value) {
  259. await updateImageData()
  260. } else {
  261. await addImageData()
  262. }
  263. }
  264. //更新数据
  265. const updateImageData = async () => {
  266. uni.showLoading({title: '保存数据中...', mask: true});
  267. const {error, code, msg} = await mainApi.updateImageclassifyFile({
  268. ...formData.value,
  269. imageUrl: fileList.value.join(','),
  270. pdfUrl: pdfList.value.join(','),
  271. })
  272. uni.hideLoading();
  273. if (!error && code === 200) {
  274. successToast('保存成功')
  275. setTimeout(() => {
  276. uni.navigateBack()
  277. }, 1500)
  278. } else {
  279. errorToast('保存失败: ' + msg)
  280. }
  281. }
  282. //新增数据
  283. const addImageData = async () => {
  284. uni.showLoading({title: '新增数据中...', mask: true});
  285. const {error, code, msg} = await mainApi.addImageclassifyFile({
  286. ...formData.value,
  287. imageUrl: fileList.value.join(','),
  288. pdfUrl: pdfList.value.join(','),
  289. })
  290. uni.hideLoading();
  291. if (!error && code === 200) {
  292. successToast('新增成功')
  293. return true
  294. } else {
  295. errorToast('新增失败: ' + msg)
  296. return false
  297. }
  298. }
  299. //继续新增
  300. const continueAdd = async () => {
  301. const isForm = await isFormValidate()
  302. if (!isForm) return false;
  303. const res = await addImageData()
  304. if(!res) return false;
  305. //清空表单
  306. const {real_name} = userInfo.value
  307. const { wbsId } = formData.value;
  308. formData.value.uploadTime = dateEnd.value
  309. formData.value.shootingTimeStr = dateEnd.value
  310. formData.value.shootingUser = real_name
  311. formData.value.title = ''
  312. formData.value.textContent = ''
  313. formData.value.photoCode = ''
  314. formData.value.filmCode = ''
  315. formData.value.seeAlsoCode = ''
  316. fileList.value = []
  317. pdfList.value = []
  318. getFileTitleNamedata(wbsId).then()
  319. }
  320. //新增保存
  321. const saveAdd = async () => {
  322. const isForm = await isFormValidate()
  323. if (!isForm) return false;
  324. const res = await addImageData()
  325. if(!res) return false;
  326. //返回上一页
  327. setTimeout(() => {
  328. uni.navigateBack()
  329. }, 1500)
  330. }
  331. </script>