cdReimbursementForm.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <template>
  2. <div class="form-main">
  3. <a-card :body-style="{padding: '24px 32px'}" :bordered="false">
  4. <a-form @submit="handleSubmit" :form="form">
  5. <a-form-item
  6. label="报销金额"
  7. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  8. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
  9. >
  10. <a-input
  11. placeholder="请输入数字"
  12. :disabled="disabled"
  13. v-decorator="[
  14. 'money',
  15. {rules: [{ required: true, message: '请输入数字' }]}
  16. ]"
  17. name="money"
  18. />
  19. </a-form-item>
  20. <a-form-item
  21. label="报销类别"
  22. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  23. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
  24. >
  25. <a-select
  26. placeholder="请选择"
  27. :disabled="disabled"
  28. show-search
  29. v-decorator="[
  30. 'type',
  31. {rules: [{ required: true, message: '请选择类型' }]}
  32. ]"
  33. >
  34. <a-select-option v-for="d in typeData" :key="d.value">{{ d.text }}</a-select-option>
  35. </a-select>
  36. </a-form-item>
  37. <a-form-item
  38. label="费用明细"
  39. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  40. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
  41. >
  42. <a-textarea
  43. placeholder="请输入费用明细描述"
  44. :disabled="disabled"
  45. v-decorator="['expense_details',{rules: [{ required: true, message: '请输入费用明细描述' }]}]"
  46. :auto-size="{ minRows: 3, maxRows: 5 }"
  47. ></a-textarea>
  48. </a-form-item>
  49. <a-form-item
  50. label="发票"
  51. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  52. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
  53. >
  54. <a-select
  55. placeholder="请选择"
  56. :disabled="disabled"
  57. show-search
  58. v-decorator="[
  59. 'invoice',
  60. {rules: [{ required: true, message: '请选择' }]}
  61. ]"
  62. >
  63. <a-select-option v-for="d in invoiceTypeList" :key="d.value">{{ d.text }}</a-select-option>
  64. </a-select>
  65. </a-form-item>
  66. <a-form-item
  67. label="图片"
  68. :labelCol="{lg: {span: 7}, sm: {span: 7}}"
  69. :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
  70. >
  71. <div class="clearfix">
  72. <a-upload
  73. action="/jeecg-boot/sys/common/uploadFile"
  74. list-type="picture-card"
  75. :multiple="true"
  76. :file-list="fileList"
  77. :disabled="disabled"
  78. @preview="handlePreview"
  79. @change="handleChange"
  80. >
  81. <div v-if="fileList.length < 8">
  82. <a-icon type="plus" />
  83. <div class="ant-upload-text">上传</div>
  84. </div>
  85. </a-upload>
  86. <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
  87. <img alt="example" style="width: 100%" :src="previewImage" />
  88. </a-modal>
  89. </div>
  90. </a-form-item>
  91. <a-form-item v-if="!disabled" :wrapperCol="{ span: 24 }" style="text-align: center">
  92. <a-button
  93. htmlType="submit"
  94. type="primary"
  95. :disabled="disabled||btndisabled"
  96. @click="handleSubmit"
  97. >保存</a-button>
  98. <a-button style="margin-left: 8px" :disabled="disabled" @click="close">取消</a-button>
  99. </a-form-item>
  100. </a-form>
  101. </a-card>
  102. </div>
  103. </template>
  104. <script>
  105. import pick from 'lodash.pick'
  106. export default {
  107. name: 'demoForm',
  108. props: {
  109. /*全局禁用,可表示查看*/
  110. disabled: {
  111. type: Boolean,
  112. default: false,
  113. required: false
  114. },
  115. /*流程数据*/
  116. processData: {
  117. type: Object,
  118. default: () => {
  119. return {}
  120. },
  121. required: false
  122. },
  123. /*是否新增*/
  124. isNew: { type: Boolean, default: false, required: false }
  125. },
  126. data() {
  127. return {
  128. url: {
  129. getForm: '/actBusiness/getForm',
  130. addApply: '/actBusiness/add',
  131. editForm: '/actBusiness/editForm',
  132. leaveType: '/sys/dict/getDictItems'
  133. },
  134. description: '流程表单demo,按例开发表单。需在 activitiMixin.js 中加入写好的表单',
  135. // form
  136. form: this.$form.createForm(this),
  137. /*表单回显数据*/
  138. data: {},
  139. btndisabled: false,
  140. // disabled:false,
  141. typeData: [],
  142. previewVisible: false,
  143. previewImage: '',
  144. fileList: [],//文件上传集合
  145. invoiceTypeList:[]
  146. }
  147. },
  148. created() {
  149. console.log('流程数据', this.processData)
  150. //获取报销类型下拉数据
  151. this.getAction(this.url.leaveType + '/reimbursement_type').then(res => {
  152. if (res.success) {
  153. this.typeData = res.result
  154. } else {
  155. this.$message.error(res.message)
  156. }
  157. })
  158. //获取发票类型下拉数据
  159. this.getAction(this.url.leaveType + '/invoice_type').then(res => {
  160. if (res.success) {
  161. this.invoiceTypeList = res.result
  162. } else {
  163. this.$message.error(res.message)
  164. }
  165. })
  166. if (!this.isNew) {
  167. // this.disabled=true;
  168. this.init()
  169. } else {
  170. // this.btndisabled = false;
  171. // this.disabled=false;
  172. }
  173. },
  174. methods: {
  175. /*回显数据*/
  176. init() {
  177. this.btndisabled = true
  178. var r = this.processData
  179. // if(!r.tableId){
  180. // return;
  181. // }
  182. this.getAction(this.url.getForm, {
  183. tableId: r.tableId,
  184. tableName: r.tableName
  185. }).then(res => {
  186. if (res.success) {
  187. let formData = res.result
  188. formData.tableName = r.tableName
  189. this.data = formData
  190. console.log('表单回显数据', this.data)
  191. this.$nextTick(() => {
  192. // this.form.setFieldsValue(pick(this.data,'type'))
  193. console.log('表单回显数据', this.data.start_time)
  194. this.fileList = [{ fileUrl: 'file/20210602/微信图片_20200831182839_1622623148179.jpg' }]
  195. this.getFileList()
  196. console.log(this.fileList)
  197. this.form.setFieldsValue({
  198. money: this.data.money,
  199. type: this.data.type,
  200. expense_details: this.data.expense_details,
  201. invoice: this.data.invoice
  202. })
  203. // this.form.setFieldsValue(moment(this.data.end_time,'end_time'))
  204. })
  205. this.btndisabled = false
  206. } else {
  207. this.$message.error(res.message)
  208. }
  209. })
  210. },
  211. // handler
  212. handleSubmit(e) {
  213. e.preventDefault()
  214. this.form.validateFields((err, values) => {
  215. if (!err) {
  216. let formData = Object.assign(this.data || {}, values)
  217. formData.procDefId = this.processData.id
  218. formData.procDeTitle = this.processData.name
  219. if (!formData.tableName) formData.tableName = this.processData.businessTable
  220. formData.filedNames = _.keys(values).join(',')
  221. var url = this.url.addApply
  222. if (!this.isNew) {
  223. url = this.url.editForm
  224. }
  225. //获取文件集合
  226. formData.tableNameB = 'cd_leave_file' //子表表名
  227. formData.childList = '' //子表数据
  228. let childList = []
  229. if (this.fileList != null && this.fileList.length > 0) {
  230. this.fileList.forEach(element => {
  231. childList.push({ file_url: element.response.message })
  232. })
  233. formData.filedNamesB = _.keys(childList[0]).join(',') //子表字段名
  234. }
  235. formData.childList = JSON.stringify(childList) //子表数据转义
  236. this.btndisabled = true
  237. this.postFormAction(url, formData)
  238. .then(res => {
  239. if (res.success) {
  240. this.$message.success('保存成功!')
  241. this.$emit('afterSubmit', formData)
  242. } else {
  243. this.$message.error(res.message)
  244. }
  245. })
  246. .finally(() => {
  247. this.btndisabled = false
  248. })
  249. }
  250. })
  251. },
  252. close() {
  253. this.$emit('close')
  254. },
  255. //文件控件处理
  256. handleCancel() {
  257. this.previewVisible = false
  258. },
  259. async handlePreview(file) {
  260. if (!file.url && !file.preview) {
  261. file.preview = await getBase64(file.originFileObj)
  262. }
  263. this.previewImage = file.url || file.preview
  264. this.previewVisible = true
  265. },
  266. //选择文件确定事件
  267. handleChange({ fileList }) {
  268. console.log(fileList)
  269. this.fileList = fileList
  270. },
  271. //详情修改查看
  272. getFileList() {
  273. //文件集合不为空则显示文件下载
  274. if (this.fileList && this.fileList != null && this.fileList.length > 0) {
  275. this.fileList.forEach((element, index) => {
  276. const fileName = setAppendix(element)
  277. ;(element.uid = '-1'),
  278. (element.uid = index + 1),
  279. (element.name = fileName),
  280. (element.status = 'done'),
  281. (element.url = '/jeecg-boot/sys/common/downloadFile/' + element.fileUrl)
  282. element.response = { message: element.fileUrl }
  283. })
  284. }
  285. }
  286. }
  287. }
  288. function getBase64(file) {
  289. return new Promise((resolve, reject) => {
  290. const reader = new FileReader()
  291. reader.readAsDataURL(file)
  292. reader.onload = () => resolve(reader.result)
  293. reader.onerror = error => reject(error)
  294. })
  295. }
  296. //显示路径
  297. function setAppendix(file) {
  298. const url = file.fileUrl
  299. if (url != null && url !== '') {
  300. const idx = url.lastIndexOf('/')
  301. const fileUrl = url.slice(idx + 1)
  302. const index = fileUrl.lastIndexOf('_')
  303. const i = fileUrl.lastIndexOf('.')
  304. const fileName = fileUrl.substring(0, index)
  305. const fileSuffix = fileUrl.slice(i + 1)
  306. const f = fileName + '.' + fileSuffix
  307. return f
  308. }
  309. return ''
  310. }
  311. </script>
  312. <style lang="less" scoped>
  313. .form-main {
  314. }
  315. </style>