submit.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <template>
  2. <view class="order-form info-wrap common-form">
  3. <!-- 注意,如果需要兼容微信小程序,最好通过setRules方法设置rules规则 -->
  4. <up-form
  5. labelPosition="left"
  6. :model="state.model"
  7. :rules="state.rules"
  8. ref="formRef"
  9. labelWidth="120"
  10. >
  11. <up-form-item
  12. label="工单名称"
  13. prop="order.name"
  14. borderBottom
  15. :required="true"
  16. >
  17. <up-input
  18. v-model="state.model.order.name"
  19. border="none"
  20. ></up-input>
  21. </up-form-item>
  22. <up-form-item
  23. label="工单类型"
  24. prop="order.type"
  25. borderBottom
  26. :required="true"
  27. @click="state.showOrderType = true; hideKeyboard()"
  28. >
  29. <up-input
  30. :modelValue="valueToConst(WorkOrderTypes, state.model.order.type).label"
  31. disabled
  32. disabledColor="#ffffff"
  33. placeholder="请选择工单类型"
  34. :required="true"
  35. border="none"
  36. ></up-input>
  37. <template #right>
  38. <up-icon
  39. name="arrow-right"
  40. ></up-icon>
  41. </template>
  42. </up-form-item>
  43. <up-form-item
  44. label="工单等级"
  45. prop="order.level"
  46. borderBottom
  47. :required="true"
  48. @click="state.showOrderLevel = true; hideKeyboard()"
  49. >
  50. <up-input
  51. :modelValue="valueToConst(WorkOrderLevel, state.model.order.level).label"
  52. disabled
  53. disabledColor="#ffffff"
  54. placeholder="请选择工单等级"
  55. border="none"
  56. ></up-input>
  57. <template #right>
  58. <up-icon
  59. name="arrow-right"
  60. ></up-icon>
  61. </template>
  62. </up-form-item>
  63. <up-form-item
  64. label="预计开始日期"
  65. prop="order.startDate"
  66. borderBottom
  67. :required="true"
  68. @click="state.showStartClendar = true; hideKeyboard()"
  69. >
  70. <up-input
  71. :modelValue="formatDate(state.model.order.startDate)"
  72. disabled
  73. disabledColor="#ffffff"
  74. placeholder="请选择预计开始日期"
  75. border="none"
  76. ></up-input>
  77. <template #right>
  78. <up-icon
  79. name="arrow-right"
  80. ></up-icon>
  81. </template>
  82. </up-form-item>
  83. <up-form-item
  84. label="预计结束日期"
  85. prop="order.endDate"
  86. borderBottom
  87. :required="true"
  88. @click="state.showEndClendar = true; hideKeyboard()"
  89. >
  90. <up-input
  91. :modelValue="formatDate(state.model.order.endDate)"
  92. disabled
  93. disabledColor="#ffffff"
  94. placeholder="请选择预计结束日期"
  95. border="none"
  96. ></up-input>
  97. <template #right>
  98. <up-icon
  99. name="arrow-right"
  100. ></up-icon>
  101. </template>
  102. </up-form-item>
  103. <up-form-item
  104. label="故障描述"
  105. borderBottom
  106. >
  107. <up-textarea
  108. placeholder="故障描述"
  109. v-model="state.model.order.desc"
  110. ></up-textarea>
  111. </up-form-item>
  112. <up-form-item>
  113. <text class="u-demo-block__title">问题图片</text>
  114. <up-upload
  115. :fileList="state.model.order.files"
  116. @afterRead="afterRead"
  117. @delete="deletePic"
  118. name="imags"
  119. multiple
  120. :maxCount="5"
  121. :previewFullImage="true"
  122. ></up-upload>
  123. </up-form-item>
  124. <up-button @click="submit" style="margin-top: 20rpx;">提交</up-button>
  125. </up-form>
  126. <up-action-sheet
  127. :show="state.showOrderType"
  128. :actions="state.orderTypeList"
  129. title="请选择工单类型"
  130. @close="state.showOrderType = false"
  131. @select="orderTypeSelect"
  132. >
  133. </up-action-sheet>
  134. <up-action-sheet
  135. :show="state.showOrderLevel"
  136. :actions="state.orderLevelList"
  137. title="请选择工单等级"
  138. @close="state.showOrderLevel = false"
  139. @select="orderLevelSelect"
  140. >
  141. </up-action-sheet>
  142. <up-datetime-picker
  143. :show="state.showStartClendar"
  144. v-model="state.model.order.startDate"
  145. mode="datetime"
  146. @close="state.showStartClendar = false"
  147. :closeOnClickOverlay="true"
  148. @confirm="(e)=>confirm(e,'showStartClendar')"
  149. @cancel="state.showStartClendar = false"
  150. ></up-datetime-picker>
  151. <up-datetime-picker
  152. :show="state.showEndClendar"
  153. v-model="state.model.order.endDate"
  154. mode="datetime"
  155. @close="state.showEndClendar = false"
  156. :closeOnClickOverlay="true"
  157. @confirm="(e)=>confirm(e,'showEndClendar')"
  158. @cancel="state.showEndClendar = false"
  159. >
  160. </up-datetime-picker>
  161. </view>
  162. </template>
  163. <script setup lang="ts">
  164. import {reactive, ref} from 'vue'
  165. import {submitOrderWork, uploadOrderFile} from '@/api/workorder.js'
  166. import dayjs from 'dayjs';
  167. import {DateFormat, hideKeyboard, reloadPage, timestampToDate} from "@/util/index.js";
  168. import {WorkOrderLevel, WorkOrderTypes} from "@/common/consts/WorkOrderConst.js";
  169. import {valueToConst} from "@/common/consts/CommonConst.js";
  170. const state = reactive({
  171. showOrderType: false,
  172. showOrderLevel: false,
  173. showStartClendar: false,
  174. showEndClendar: false,
  175. model: {
  176. order: {
  177. files: [],
  178. startDate: dayjs().valueOf(),
  179. endDate: dayjs().valueOf(),
  180. }
  181. },
  182. orderTypeList: [],
  183. orderLevelList: [],
  184. rules: {
  185. 'order.name': {
  186. type: 'string',
  187. required: true,
  188. message: '请填工单名称',
  189. trigger: ['blur', 'change'],
  190. },
  191. 'order.type': {
  192. type: 'number',
  193. required: true,
  194. message: '请选择工单类型',
  195. trigger: ['blur', 'change'],
  196. },
  197. 'order.level': {
  198. type: 'number',
  199. required: true,
  200. message: '请选择工单等级',
  201. trigger: ['blur', 'change'],
  202. },
  203. 'order.startDate': {
  204. type: 'number',
  205. required: true,
  206. message: '请选择预计开始时间',
  207. trigger: ['blur', 'change'],
  208. },
  209. 'order.endDate': {
  210. type: 'number',
  211. required: true,
  212. message: '请选择预计结束时间',
  213. trigger: ['blur', 'change'],
  214. }
  215. },
  216. });
  217. Object.keys(WorkOrderTypes).forEach(key => {
  218. state.orderTypeList.push({name: WorkOrderTypes[key].label, id: WorkOrderTypes[key].value})
  219. });
  220. Object.keys(WorkOrderLevel).forEach(key => {
  221. state.orderLevelList.push({name: WorkOrderLevel[key].label, id: WorkOrderLevel[key].value})
  222. });
  223. // 使用 ref 创建响应式引用
  224. const formRef = ref(null);
  225. const orderTypeSelect = (item) => {
  226. state.model.order.type = item.id;
  227. state.showOrderType = false;
  228. };
  229. const orderLevelSelect = (item) => {
  230. state.model.order.level = item.id;
  231. state.showOrderLevel = false;
  232. };
  233. // 删除图片
  234. const deletePic = (event) => {
  235. state.model.order.files.splice(event.index, 1)
  236. }
  237. const formatDate = (date) => {
  238. return timestampToDate(date)
  239. }
  240. const confirm = (e, type) => {
  241. state[type] = false;
  242. };
  243. const afterRead = async (event) => {
  244. // 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
  245. let lists = [].concat(event.file)
  246. let fileListLen = state.model.order.files.length
  247. lists.map((item) => {
  248. state.model.order.files.push({
  249. ...item,
  250. status: 'uploading',
  251. message: '上传中'
  252. })
  253. })
  254. for (let i = 0; i < lists.length; i++) {
  255. const result = await uploadOrderFile(lists[i].url)
  256. let item = state.model.order.files[fileListLen]
  257. state.model.order.files.splice(fileListLen, 1, Object.assign(item, {
  258. status: 'success',
  259. name: result.fileName,
  260. uid: result.md5,
  261. url: result.url
  262. }))
  263. fileListLen++
  264. }
  265. }
  266. const submit = () => {
  267. formRef.value.validate().then(async valid => {
  268. if (valid) {
  269. const order = state.model.order
  270. submitOrderWork({
  271. "name": order.name,
  272. "type": order.type,
  273. "level": order.level,
  274. "estimatedStartTime": dayjs(order.startDate).format(DateFormat.YYYYMMDDHHMMSS),
  275. "estimatedEndTime": dayjs(order.endDate).format(DateFormat.YYYYMMDDHHMMSS),
  276. "description": order.desc,
  277. "source": 2,
  278. "problemImg": JSON.stringify(order.files),
  279. "problemFile": null
  280. }).then(res => {
  281. uni.$u.toast('提交成功')
  282. reloadPage()
  283. })
  284. } else {
  285. uni.$u.toast('校验失败')
  286. }
  287. }).catch((e) => {
  288. // 处理验证错误
  289. uni.$u.toast('校验失败')
  290. });
  291. }
  292. </script>
  293. <style lang="scss">
  294. .order-form {
  295. background-color: #fff;
  296. border-radius: $uni-text-gap;
  297. padding: $uni-text-gap;
  298. }
  299. </style>