index.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <template>
  2. <view class="process_container">
  3. <uni-card margin="10px" spacing="0">
  4. <uni-forms label-position="left" :label-width="125" :border="true">
  5. <uni-forms-item v-for="(item, index) in formElements" :label="item.elementName" :key="index">
  6. <uni-easyinput v-if="'多少小时' == item.elementName" :disabled="true" placeholder=""
  7. :value="diffHours"></uni-easyinput>
  8. <!-- 输入框 -->
  9. <uni-easyinput v-else-if="'0' == item.type" :disabled="'0' == item.canEdit" :placeholder="'0' == item.canEdit?'':'请输入内容'" :value="item.defaultValue"></uni-easyinput>
  10. <!-- 富文本输入框 -->
  11. <uni-easyinput v-else-if="'1' == item.type" :disabled="'0' == item.canEdit" :placeholder="'0' == item.canEdit?'':'请输入内容'" :value="item.defaultValue" type="textarea"></uni-easyinput>
  12. <!-- 下拉框 -->
  13. <picker class="picker_container" v-else-if="'2' == item.type" @change="bindPickerChange($event, item)" :value="item.defaultValue" :range="formatDict(item.typeDetail.enum)">
  14. <view class="uni-input input_text">
  15. <!-- 设置默认值为第一个选项 -->
  16. {{ item.defaultValue ? item.defaultValue:item.defaultValue = item.typeDetail.enum[0].enumVname }}
  17. </view>
  18. </picker>
  19. <!-- 开始时间选择器 -->
  20. <uni-datetime-picker :end="endTime" @change="setTimeRange(item)"
  21. v-else-if="timeFlag && '9' == item.type && '开始时间' == item.elementName" v-model="item.defaultValue"
  22. :clear-icon="false" type="datetime" />
  23. <!-- 结束时间选择器 -->
  24. <uni-datetime-picker :start="startTime" @change="setTimeRange(item)" :disabled="disableEndTime"
  25. :placeholder="disableEndTime ? '请先确认开始时间' : '确认结束时间'"
  26. v-else-if="timeFlag && '9' == item.type && '结束时间' == item.elementName" v-model="item.defaultValue"
  27. :clear-icon="false" type="datetime" />
  28. <!-- 其他时间选择器 -->
  29. <!-- 年月日 时分秒 -->
  30. <uni-datetime-picker v-else-if="'9' == item.type" v-model="item.defaultValue" type="datetime" />
  31. <!-- 年月日 -->
  32. <uni-datetime-picker v-else-if="'3' == item.type" v-model="item.defaultValue" type="date" />
  33. </uni-forms-item>
  34. </uni-forms>
  35. </uni-card>
  36. <uni-card title="上传附件" :extra="`${fileList.length}/15`" margin="10px" spacing="0">
  37. <uni-file-picker
  38. ref="filePicker"
  39. :value="fileList"
  40. :auto-upload="true"
  41. mode="list" limit="10"
  42. file-mediatype="all"
  43. @select="handleFileSelect"
  44. @progress="handleFileProgress"
  45. @success="handleFileSuccess"
  46. @fail="handleFileFail"
  47. @delete="handleFileDelete"
  48. />
  49. <button :loading="!button_state" type="default" class="submit_button" @click="submitProcess">提交</button>
  50. </uni-card>
  51. </view>
  52. </template>
  53. <script setup lang="ts">
  54. import { onMounted, reactive, ref } from 'vue'
  55. import { onLoad } from '@dcloudio/uni-app'
  56. import { useUserStore } from '@/store/user.js'
  57. import $modal from '@/plugins/modal.js'
  58. import $tab from '@/plugins/tab.js'
  59. import { getProcessInfo, getProcessForm, submitProcessForm, uploadFiles } from '@/api/work.js'
  60. let processInfo = reactive({
  61. modelName: '流程申请',
  62. control: '',
  63. formId: '',
  64. modelId: '',
  65. tmodelId: '',
  66. isMoreIns: '',
  67. pathJudgeType: '',
  68. form: []
  69. })
  70. const userStore = useUserStore()
  71. const title = ref('')
  72. onLoad((options) => {
  73. const { modelName, modelId, control } = options
  74. processInfo.modelName = modelName
  75. processInfo.modelId = modelId
  76. processInfo.control = control
  77. title.value = userStore.user.name + '的' + processInfo.modelName
  78. // 设置导航栏标题
  79. uni.setNavigationBarTitle({
  80. title: title.value
  81. });
  82. })
  83. onMounted(() => {
  84. initProcessInfo().then(() => {
  85. initProcessForm()
  86. })
  87. })
  88. function initProcessInfo() {
  89. return new Promise<void>((resolve, reject) => {
  90. getProcessInfo(processInfo)
  91. .then(({ returnParams }) => {
  92. const { formId, tmodelId, isMoreIns, pathJudgeType } = returnParams.flow[0]
  93. processInfo.formId = formId
  94. processInfo.tmodelId = tmodelId
  95. processInfo.isMoreIns = isMoreIns
  96. processInfo.pathJudgeType = pathJudgeType
  97. resolve()
  98. })
  99. })
  100. }
  101. // 下拉框
  102. function bindPickerChange(e, item) {
  103. const index = e.detail.value;
  104. item.defaultValue = item.typeDetail.enum[index].enumVname
  105. }
  106. function formatDict(dict) {
  107. return dict.map(({enumVname}) => enumVname)
  108. }
  109. const formElements = ref([])
  110. const startEleIndex = ref(0) // 开始时间
  111. const endEleIndex = ref(0) // 结束时间
  112. function initProcessForm() {
  113. getProcessForm(userStore.user, processInfo).then(({ returnParams }) => {
  114. formElements.value = returnParams.formElements
  115. startEleIndex.value = formElements.value.findIndex((item) => '开始时间' == item.elementName)
  116. endEleIndex.value = formElements.value.findIndex((item) => '结束时间' == item.elementName)
  117. // console.log('startEle', startEleIndex.value);
  118. // console.log('endEle', endEleIndex.value);
  119. if (startEleIndex.value != -1 && endEleIndex.value != -1) { // 判断是否需要计算时间差
  120. // console.log('if (startEleIndex && endEleIndex)');
  121. timeFlag.value = true
  122. disableEndTime.value = true // 计算时间差时默认禁用结束时间选择器
  123. formElements.value[startEleIndex.value].defaultValue = new Date()
  124. }
  125. })
  126. }
  127. const startTime = ref(0) // 开始时间
  128. const endTime = ref(0) // 结束时间
  129. const diffHours = ref(' ') // 时间差
  130. const timeFlag = ref(false) // 是否计算时间差
  131. const disableEndTime = ref(false) // 禁用 结束时间选择器
  132. function setTimeRange(e) {
  133. if (timeFlag.value && '开始时间' == e.elementName) {
  134. startTime.value = e.defaultValue // 设置 开始时间
  135. disableEndTime.value = false // 解除 结束时间选择器 禁用
  136. }
  137. if (timeFlag.value && '结束时间' == e.elementName) {
  138. endTime.value = e.defaultValue // 设置 结束时间
  139. }
  140. if (timeFlag.value && startTime.value && endTime.value) {
  141. const start = new Date(startTime.value).getTime() // 获取 开始时间 时间戳
  142. const end = new Date(endTime.value).getTime() // 获取 结束时间 时间戳
  143. const diffSec = Math.abs(end - start) // 获取 时间戳 差值
  144. diffHours.value = (diffSec / 1000 / 60 / 60).toFixed(2) // 计算 时间差值 并格式化 为只有2位小数
  145. }
  146. }
  147. const uploadFileConfig = ref({
  148. maxCount: 10,
  149. uploadType: "file",
  150. hostUrl: "",
  151. autoUpload: false
  152. })
  153. const fileList = ref([]) // 文件列表
  154. const fileSeqs = ref([]) // 文件上传返回 seq 列表
  155. const filePicker = ref(null)
  156. function handleFileSelect(file) { // 新增文件
  157. console.log('handleFileSelect', file)
  158. console.log('handleFileProgress', file)
  159. const data = {
  160. name: file.tempFiles[0].name,
  161. files: file.tempFiles[0].file.path,
  162. }
  163. uploadFiles(data)
  164. .then(res => {
  165. fileSeqs.value.push(res.returnParams)
  166. let newFile = file.tempFiles[0]
  167. newFile.seq = res.returnParams
  168. fileList.value.push(newFile)
  169. })
  170. .catch(err => {
  171. if (err == -20201) {
  172. console.log('文件上传失败 返回值不是JSON字符串');
  173. }
  174. })
  175. }
  176. function handleFileProgress(file, progress) {
  177. console.log('handleFileProgress', file, progress);
  178. }
  179. function handleFileSuccess(file, res) {
  180. console.log('handleFileSuccess', file, res);
  181. }
  182. function handleFileFail(file, err) {
  183. console.log('handleFileFail', file, err);
  184. }
  185. function handleFileDelete(file, index) { // 移除文件
  186. console.log('handleDelete', file)
  187. fileList.value.splice(fileList.value.indexOf(file.tempFiles), 1)
  188. fileSeqs.value.splice(index, 1)
  189. }
  190. const button_state = ref(true)
  191. function submitProcess() { // 提交表单
  192. // 禁用提交按钮
  193. button_state.value = false
  194. // 保存表单数据
  195. processInfo.form = formElements.value.map(({tableField, defaultValue}) => {
  196. return { name: tableField, value: defaultValue }
  197. })
  198. console.log('submitProcessForm', processInfo.form);
  199. console.log('fileList', fileList.value);
  200. console.log('fileSeqs', fileSeqs.value);
  201. console.log('filePicker', filePicker.value);
  202. button_state.value = true
  203. submitProcessForm(userStore.user, processInfo, fileSeqs.value).then(res => {
  204. console.log('submitProcessForm', res);
  205. if (res.returnMsg.includes('提交失败')) {
  206. // 启用提交按钮
  207. button_state.value = true
  208. $modal.msgError(res.returnMsg)
  209. } else {
  210. $modal.msgSuccess(res.returnMsg)
  211. // 返回上一页
  212. $tab.navigateBack();
  213. }
  214. })
  215. }
  216. </script>
  217. <style lang="scss">
  218. .process_container {
  219. .picker_container {
  220. border: 1px solid #e5e5e5;
  221. background-color: #fff;
  222. border-radius: 4px;
  223. // box-sizing: border-box;
  224. .input_text{
  225. color: #333;
  226. font-size: 14px;
  227. line-height: 35px;
  228. height: 35px;
  229. padding: 0 0 0 10px;
  230. }
  231. }
  232. .is-disabled {
  233. color: #666 !important;
  234. }
  235. .submit_button {
  236. background-color: #007aff !important;
  237. color: #fff !important;
  238. }
  239. }
  240. </style>