BaseForm.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. <template>
  2. <el-form ref="baseForm" :inline="isInline" :model="baseForm" :label-position="labelPosition" :label-width="labelWidth" class="xl-form" :class="isInline && 'inputw190'">
  3. <template v-for="(item, index) in curData">
  4. <template v-if="insertSlotArr.indexOf(index) > -1">
  5. <slot :name="`OI${index}`" />
  6. </template>
  7. <el-form-item
  8. v-if="item.type === 'select'"
  9. :key="index"
  10. :class="item.class"
  11. :prop="item.key"
  12. :label="isInline && noLabel ? '' : item.label"
  13. :label-width="item.singleLabelWidth || labelWidth"
  14. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  15. >
  16. <el-select
  17. v-model.trim="baseForm[item.key]"
  18. clearable
  19. :placeholder="`请选择${item.label2 || item.label}`"
  20. :disabled="item.disabled || false"
  21. :multiple="item.multiple || false"
  22. :filterable="item.filterable"
  23. @change="changeHandle"
  24. @remove-tag="focusHandle(item.key)"
  25. @focus="focusHandle(item.key)"
  26. >
  27. <el-option
  28. v-for="(op, o) in item.options"
  29. :key="o"
  30. :label="op.key"
  31. :disabled="op.disabled"
  32. :value="op.val"
  33. >{{ op.key }}</el-option>
  34. </el-select>
  35. </el-form-item>
  36. <el-form-item
  37. v-else-if="item.type === 'colorPicker'"
  38. :key="index"
  39. :class="item.class"
  40. :prop="item.key"
  41. :label="isInline && noLabel ? '' : item.label"
  42. :label-width="item.singleLabelWidth || labelWidth"
  43. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  44. >
  45. <el-color-picker
  46. @change="changeHandle"
  47. @focus="focusHandle(item.key)"
  48. v-model.trim="baseForm[item.key]">
  49. </el-color-picker>
  50. </el-form-item>
  51. <el-form-item
  52. v-else-if="item.type === 'selectRemote'"
  53. :key="index"
  54. :class="item.class"
  55. :prop="item.key"
  56. :label="isInline && noLabel ? '' : item.label"
  57. :label-width="item.singleLabelWidth || labelWidth"
  58. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  59. >
  60. <el-select
  61. v-model.trim="baseForm[item.key]"
  62. filterable
  63. remote
  64. clearable
  65. :disabled="item.disabled || false"
  66. :multiple="item.multiple || false"
  67. :remote-method="remoteMethod"
  68. :loading="formLoading"
  69. :placeholder="`搜索${item.label}`"
  70. @change="changeHandle"
  71. @remove-tag="focusHandle(item.key)"
  72. @focus="focusHandle(item.key)"
  73. >
  74. <el-option
  75. v-for="(op, o) in item.remoteOptions"
  76. :key="o"
  77. :label="op.keyRO"
  78. :disabled="op.disabled"
  79. :value="op.valRO"
  80. >{{ op.keyRO }}</el-option>
  81. </el-select>
  82. </el-form-item>
  83. <el-form-item
  84. v-else-if="item.type === 'datePicker'"
  85. :key="index"
  86. :class="item.class"
  87. :prop="item.key"
  88. :label="isInline && noLabel ? '' : item.label"
  89. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  90. >
  91. <el-date-picker
  92. v-model.trim="baseForm[item.key]"
  93. :style="item.type2 === 'date' && 'width: 100%;'"
  94. unlink-panels
  95. :type="`${item.type2 ? item.type2 : 'daterange'}`"
  96. :align="'right'"
  97. :value-format="`${item.valueFormat ? item.valueFormat : 'yyyy-MM-dd'}`"
  98. range-separator="至"
  99. :disabled="item.disabled || false"
  100. :placeholder="`请选择${item.label}`"
  101. :start-placeholder="item.label2"
  102. :end-placeholder="item.label3"
  103. :picker-options="`${item.type2 ? {} : item.datePickerOptions}`"
  104. @focus="focusHandle(item.key)"
  105. />
  106. </el-form-item>
  107. <el-form-item
  108. v-else-if="item.type === 'timePicker'"
  109. :key="index"
  110. :class="item.class"
  111. :prop="item.key"
  112. :label="isInline && noLabel ? '' : item.label"
  113. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  114. >
  115. <el-time-picker
  116. v-model="baseForm[item.key]"
  117. :is-range="item.type2!=='time'"
  118. range-separator="至"
  119. :value-format="item.format || 'HH:mm'"
  120. :format="item.format || 'HH:mm'"
  121. :disabled="item.disabled || false"
  122. :start-placeholder="item.label2 || '开始时间'"
  123. :end-placeholder="item.label3 || '结束时间'"
  124. :placeholder="`请选择${item.label}`"
  125. />
  126. </el-form-item>
  127. <el-form-item
  128. v-else-if="item.type === 'inputFont'"
  129. :key="index"
  130. :class="item.class"
  131. :prop="item.key"
  132. :label="isInline && noLabel ? '' : item.label"
  133. :rules="item.rules === 1 ? [{ required: true, message: '请输入'+ item.label, trigger: 'blur' }] : item.rules"
  134. >
  135. <el-input
  136. v-model.trim="baseForm[item.key]"
  137. clearable
  138. :disabled="item.disabled || false"
  139. :maxlength="item.maxlength || false"
  140. :placeholder="`请输入${item.label2 || item.label}`"
  141. @change="changeHandle"
  142. @focus="focusHandle(item.key)"
  143. >
  144. <template v-if="item.prependFont" slot="prepend">{{ item.prependFont }}</template>
  145. <template v-if="item.appendFont" slot="append">{{ item.appendFont }}</template>
  146. </el-input>
  147. </el-form-item>
  148. <el-form-item
  149. v-else-if="item.type === 'cascader'"
  150. :key="index"
  151. :class="item.class"
  152. :prop="item.key"
  153. :label="isInline && noLabel ? '' : item.label"
  154. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  155. >
  156. <el-cascader
  157. v-model.trim="baseForm[item.key]"
  158. clearable
  159. :options="item.options"
  160. :props="item.props || {}"
  161. :disabled="item.disabled || false"
  162. :placeholder="`请选择${item.label}`"
  163. @focus="focusHandle(item.key)"
  164. @change="changeHandle"
  165. />
  166. </el-form-item>
  167. <el-form-item
  168. v-else-if="item.type === 'upload'"
  169. :key="index"
  170. :class="item.class"
  171. :prop="item.key"
  172. :label="isInline && noLabel ? '' : item.label"
  173. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  174. >
  175. <el-upload
  176. class="img-upload"
  177. :disabled="item.disabled || false"
  178. :action="`${requireUrl}/adm/upload/cloud`"
  179. :data="{logic_type: 'estate', token}"
  180. name="upload"
  181. :show-file-list="false"
  182. :on-success="uploadSuccess"
  183. :on-error="uploadError"
  184. :before-upload="uploadBefore"
  185. >
  186. <img v-if="baseForm[item.key]" :src="baseForm[item.key].indexOf('_adm0') > -1 ? baseForm[item.key] : baseForm[item.key] + '_adm0'" class="img" @click="focusHandle(item.key)">
  187. <i v-else class="el-icon-plus icon" @click="focusHandle(item.key)" />
  188. </el-upload>
  189. </el-form-item>
  190. <el-form-item
  191. v-else-if="item.type === 'cuImg'"
  192. :key="index"
  193. :class="item.class"
  194. :prop="item.key"
  195. :label="isInline && noLabel ? '' : item.label"
  196. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  197. >
  198. <el-upload
  199. class="img-upload"
  200. :action="`${requireUrl}/adm/upload/cloudpub`"
  201. :data="{logic_type: 'estate', token}"
  202. name="upload"
  203. ref="cui"
  204. :auto-upload="false"
  205. :show-file-list="false"
  206. :on-change='cuImgOpen'
  207. :on-success="uploadSuccess"
  208. >
  209. <template v-if="item.options && item.options.SY === 1">
  210. <img v-if="baseForm[item.key]" :src="baseForm[item.key].indexOf('_adm0') > -1 ? baseForm[item.key] : baseForm[item.key] + '_adm0'" class="img" @click="focusHandle(item.key)">
  211. <i v-else class="el-icon-plus icon" @click="focusHandle(item.key)" />
  212. </template>
  213. <template v-else>
  214. <img v-if="baseForm[item.key]" :src="baseForm[item.key]" class="img" @click="focusHandle(item.key)">
  215. <i v-else class="el-icon-plus icon" @click="focusHandle(item.key)" />
  216. </template>
  217. </el-upload>
  218. </el-form-item>
  219. <el-form-item
  220. v-else-if="item.type === 'uploads'"
  221. :key="index"
  222. :class="item.class"
  223. :prop="item.key"
  224. :label="isInline && noLabel ? '' : item.label"
  225. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  226. >
  227. <el-upload
  228. class="img-upload"
  229. :disabled="item.disabled || false"
  230. :action="`${requireUrl}/adm/upload/cloudpub`"
  231. :data="{logic_type: 'estate', token}"
  232. name="upload"
  233. :show-file-list="false"
  234. :on-success="uploadSuccess"
  235. :on-error="uploadError"
  236. :before-upload="uploadBefore"
  237. >
  238. <img v-if="baseForm[item.key]" :src="baseForm[item.key]" class="img" @click="focusHandle(item.key)">
  239. <i v-else class="el-icon-plus icon" @click="focusHandle(item.key)" />
  240. </el-upload>
  241. </el-form-item>
  242. <el-form-item
  243. v-else-if="item.type === 'uploadsGif'"
  244. :key="index"
  245. :class="item.class"
  246. :prop="item.key"
  247. :label="isInline && noLabel ? '' : item.label"
  248. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  249. >
  250. <el-upload
  251. class="img-upload"
  252. :disabled="item.disabled || false"
  253. :action="`${requireUrl}/adm/upload/cloudpub`"
  254. :data="{logic_type: 'estate', token}"
  255. name="upload"
  256. :show-file-list="false"
  257. :on-success="uploadSuccess"
  258. :on-error="uploadError"
  259. :before-upload="uploadGifBefore"
  260. >
  261. <img v-if="baseForm[item.key]" :src="baseForm[item.key]" class="img" @click="focusHandle(item.key)">
  262. <i v-else class="el-icon-plus icon" @click="focusHandle(item.key)" />
  263. </el-upload>
  264. </el-form-item>
  265. <el-form-item
  266. v-else-if="item.type === 'uploadIcon'"
  267. :key="index"
  268. :class="item.class"
  269. :prop="item.key"
  270. :label="isInline && noLabel ? '' : item.label"
  271. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  272. >
  273. <el-upload
  274. class="img-upload"
  275. :disabled="item.disabled || false"
  276. :action="`${requireUrl}/adm/theme/icon/upload`"
  277. :data="{logic_type: 'estate', token}"
  278. name="upload"
  279. :show-file-list="false"
  280. :on-success="uploadSuccess"
  281. :on-error="uploadError"
  282. :before-upload="uploadBefore"
  283. >
  284. <img v-if="baseForm[item.key]" :src="baseForm[item.key]" class="img" @click="focusHandle(item.key)">
  285. <i v-else class="el-icon-plus icon" @click="focusHandle(item.key)" />
  286. </el-upload>
  287. </el-form-item>
  288. <el-form-item
  289. v-else-if="item.type === 'upload2'"
  290. :key="index"
  291. :class="item.class"
  292. :prop="item.key"
  293. :label="isInline && noLabel ? '' : item.label"
  294. :rules="item.rules === 1 ? [{ required: true, message: '请选择'+ item.label, trigger: 'blur' }] : item.rules"
  295. >
  296. <el-upload
  297. :disabled="item.disabled || false"
  298. :action="`${requireUrl}/adm/upload/cloud`"
  299. :data="{filename: 'sysimg', token}"
  300. name="upload"
  301. :on-success="uploadSuccess2"
  302. :on-error="uploadError"
  303. :multiple="item.limit || false"
  304. :limit="item.limit || 1"
  305. :on-exceed="uploadHandleExceed"
  306. :on-remove="uploadHandleRemove"
  307. :file-list="baseForm[item.key] || []"
  308. :before-upload="uploadBefore2"
  309. @click.native="focusHandle(item.key)"
  310. >
  311. <el-button size="small" type="success" @click="focusHandle(item.key)">{{ baseForm[item.key].length > 0 ? '重新上传' : '立即上传' }}</el-button>
  312. </el-upload>
  313. </el-form-item>
  314. <el-form-item
  315. v-else-if="item.type === 'inputSelect'"
  316. :key="index"
  317. :class="item.class"
  318. :prop="item.key"
  319. :label="isInline && noLabel ? '' : item.label"
  320. :rules="item.rules === 1 ? [{ required: true, message: '请输入'+ item.label, trigger: 'blur' }] : item.rules"
  321. >
  322. <el-input
  323. v-model.trim="baseForm[item.key]"
  324. clearable
  325. :disabled="item.disabled || false"
  326. :placeholder="`请输入${item.label2 || item.label}`"
  327. @focus="focusHandle(item.key)"
  328. >
  329. <template slot="append">
  330. <el-select
  331. v-model.trim="baseForm[item.selectObj.key]"
  332. :disabled="item.disabled || false"
  333. :placeholder="`${item.selectObj.label}`"
  334. >
  335. <el-option
  336. v-for="(op, o) in item.selectObj.options"
  337. :key="o"
  338. :label="op.key"
  339. :value="op.val"
  340. >{{ op.key }}</el-option>
  341. </el-select>
  342. </template>
  343. </el-input>
  344. </el-form-item>
  345. <el-form-item
  346. v-else-if="item.type === 'checkbox'"
  347. :key="index"
  348. :class="item.class"
  349. :prop="item.key"
  350. :label="isInline && noLabel ? '' : item.label"
  351. :rules="item.rules === 1 ? [{ required: true, message: '请勾选'+ item.label, trigger: 'blur' }] : item.rules"
  352. >
  353. <el-checkbox-group v-model.trim="baseForm[item.key]" :disabled="item.disabled || false">
  354. <el-checkbox
  355. v-for="(op, o) in item.options"
  356. :key="o"
  357. :label="op.val"
  358. >{{ op.key }}</el-checkbox>
  359. </el-checkbox-group>
  360. </el-form-item>
  361. <el-form-item
  362. v-else-if="item.type === 'radio'"
  363. :key="index"
  364. :class="item.class"
  365. :prop="item.key"
  366. :label="isInline && noLabel ? '' : item.label"
  367. :label-width="item.singleLabelWidth || labelWidth"
  368. :rules="item.rules === 1 ? [{ required: true, message: '请勾选'+ item.label, trigger: 'blur' }] : item.rules"
  369. >
  370. <el-radio-group v-model.trim="baseForm[item.key]" :disabled="item.disabled || false">
  371. <el-radio
  372. v-for="(op, o) in item.options"
  373. :key="o"
  374. :label="op.val"
  375. :disabled="op.disabled"
  376. >{{ op.key }}</el-radio>
  377. </el-radio-group>
  378. </el-form-item>
  379. <el-form-item
  380. v-else-if="item.type === 'switch'"
  381. :key="index"
  382. :class="item.class"
  383. :label="isInline && noLabel ? '' : item.label"
  384. >
  385. <el-switch
  386. v-model="baseForm[item.key]"
  387. :active-value="item.labelTrue || '1'"
  388. :inactive-value="item.labelFalse || '2'"
  389. :active-color="item.activeColor || '#13ce66'"
  390. :inactive-color="item.inactiveColor || '#ccc'"
  391. :active-text="item.activeText"
  392. :inactive-text="item.inactiveText"
  393. :disabled="item.disabled || false"
  394. @change="changeHandle"
  395. @focus.native="focusHandle(item.key)"
  396. @click.native="focusHandle(item.key)"
  397. />
  398. </el-form-item>
  399. <el-form-item
  400. v-else
  401. :key="index"
  402. :class="item.class"
  403. :prop="item.key"
  404. :label="isInline && noLabel ? '' : item.label"
  405. :rules="item.rules === 1 ? [{ required: true, message: '请输入'+ item.label, trigger: 'blur' }] : item.rules"
  406. >
  407. <el-input
  408. v-model.trim="baseForm[item.key]"
  409. clearable
  410. :type="item.type || 'text'"
  411. :disabled="item.disabled || false"
  412. :placeholder="`请输入${item.label2 || item.label}`"
  413. :maxlength="item.maxlength || false"
  414. @change="changeHandle"
  415. @focus="focusHandle(item.key)"
  416. />
  417. </el-form-item>
  418. </template>
  419. <slot name="otherItem" />
  420. <el-form-item>
  421. <slot name="footer" />
  422. </el-form-item>
  423. <cropper-img
  424. :isShow="isCIShow"
  425. :curObj="uploadObj"
  426. @close="cuImgClose"
  427. />
  428. </el-form>
  429. </template>
  430. <script>
  431. import { strTrim } from '@/utils'
  432. import CropperImg from './CropperImg'
  433. export default {
  434. name: 'BaseForm',
  435. components: { CropperImg },
  436. props: {
  437. data: Array,
  438. labelWidth: {
  439. default: '80px',
  440. type: String
  441. },
  442. isInline: {
  443. default: true,
  444. type: Boolean
  445. },
  446. noLabel: {
  447. default: true,
  448. type: Boolean
  449. },
  450. labelPosition: {
  451. default: 'right',
  452. type: String
  453. },
  454. insertSlotArr: {
  455. default: () => [],
  456. type: Array
  457. }
  458. },
  459. data() {
  460. const curData = this.data
  461. let requireUrl = process.env.VUE_APP_BASE_API
  462. const userApi = window.sessionStorage.getItem('testUrl')
  463. const token = window.sessionStorage.getItem('fp_token')
  464. if (process.env.VUE_APP_BASE_API === 'http://api.t.antretail.cn' && userApi) {
  465. requireUrl = userApi
  466. }
  467. return {
  468. token,
  469. requireUrl,
  470. curData,
  471. formLoading: false,
  472. baseForm: {},
  473. curFormKey: '',
  474. curFormIndex: '',
  475. selectRemoteTotal: null,
  476. selectRemoteNum: null,
  477. uploadHeaders: {
  478. 'Content-Type': 'multipart/form-data'
  479. },
  480. remoteOptionsPrev: {},
  481. isCIShow: false,
  482. uploadObj: {},
  483. }
  484. },
  485. watch: {
  486. data: {
  487. handler: function(val) {
  488. if (val.length === 0) return
  489. this.curData = [...val]
  490. this.selectRemoteTotal = 0
  491. this.selectRemoteNum = 0
  492. const baseForm = {}
  493. val.forEach((item, index) => {
  494. let emptyVal = ''
  495. // if (item.type === 'cascader' || item.type === 'upload2') emptyVal = []
  496. if (item.type === 'switch') emptyVal = item.labelFalse || '2'
  497. if (item.type === 'selectRemote') this.selectRemoteTotal++
  498. baseForm[item.key] = item.defaultValue || emptyVal
  499. if (item.type === 'datePicker') {
  500. this.curData[index].datePickerOptions = {
  501. shortcuts: [{
  502. text: '昨天',
  503. onClick(picker) {
  504. // const end = new Date()
  505. const start = new Date()
  506. start.setTime(start.getTime() - 3600 * 1000 * 24)
  507. picker.$emit('pick', [start, start])
  508. }
  509. }, {
  510. text: '最近一周',
  511. onClick(picker) {
  512. const end = new Date()
  513. const start = new Date()
  514. start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
  515. picker.$emit('pick', [start, end])
  516. }
  517. }, {
  518. text: '最近一个月',
  519. onClick(picker) {
  520. const end = new Date()
  521. const start = new Date()
  522. start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
  523. picker.$emit('pick', [start, end])
  524. }
  525. }, {
  526. text: '最近三个月',
  527. onClick(picker) {
  528. const end = new Date()
  529. const start = new Date()
  530. start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
  531. picker.$emit('pick', [start, end])
  532. }
  533. }]
  534. }
  535. if (item.disabledDate === '-1') {
  536. this.curData[index].datePickerOptions.disabledDate = function(time) {
  537. return time.getTime() > Date.now() - 3600 * 1000 * 24
  538. }
  539. }
  540. }
  541. })
  542. this.baseForm = Object.assign({}, baseForm)
  543. const that = this
  544. that.$nextTick(() => {
  545. that.$refs['baseForm'].resetFields()
  546. val.forEach((op, i) => {
  547. // 待优化,目前每次open都有请求
  548. if (that.curData[i].type === 'selectRemote') {
  549. that.remoteMethod(null, i)
  550. }
  551. })
  552. })
  553. },
  554. immediate: true
  555. }
  556. },
  557. methods: {
  558. uploadHandleExceed(files, fileList) {
  559. this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
  560. },
  561. uploadSuccess(res, file) {
  562. // console.log(res)
  563. const data = res.data || {}
  564. const uploadItem = this.curData[this.curFormIndex]
  565. // this.baseForm[uploadItem.key] = `${data.domain}${data.url}?url=${data.url}&id=${data.file_id}`
  566. this.baseForm[uploadItem.key] = `${data.url}`
  567. // this.baseForm[uploadItem.key] = uploadItem.uploadData.domain + res.key
  568. // this.imageUrl = URL.createObjectURL(file.raw)
  569. this.changeHandle(file)
  570. },
  571. uploadError(file) {
  572. this.changeHandle(file)
  573. },
  574. uploadGifBefore(file) {
  575. const isJPGPNG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif'
  576. const isLtM = file.size / 1024 / 1024 < 30
  577. if (!isJPGPNG) {
  578. this.$message.error('上传图片只能是 JPG PNG GIF 格式!')
  579. }
  580. if (!isLtM) {
  581. this.$message.error('上传图片大小不能超过 30M!')
  582. }
  583. return isJPGPNG && isLtM
  584. },
  585. uploadBefore(file) {
  586. const isJPGPNG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif'
  587. const isLtM = file.size / 1024 / 1024 < 10
  588. if (!isJPGPNG) {
  589. this.$message.error('上传图片只能是 JPG PNG GIF 格式!')
  590. }
  591. if (!isLtM) {
  592. this.$message.error('上传图片大小不能超过 10M!')
  593. }
  594. return isJPGPNG && isLtM
  595. },
  596. uploadBefore2(file) {
  597. // console.log(file.type)
  598. },
  599. uploadSuccess2(res, file) {
  600. const data = res.data || {}
  601. const uploadItem = this.curData[this.curFormIndex]
  602. this.baseForm[uploadItem.key] = [{
  603. name: file.name,
  604. url: data.url
  605. }]
  606. this.changeHandle(file)
  607. },
  608. uploadHandleRemove(file, fileList) {
  609. window.setTimeout(() => {
  610. this.$set(this.baseForm, this.curFormKey, [])
  611. }, 100)
  612. },
  613. changeHandle(val) {
  614. this.$nextTick(() => {
  615. if (parseFloat(this.curFormIndex).toString() === 'NaN') return
  616. const curFormItem = this.curData[this.curFormIndex]
  617. if (curFormItem) {
  618. if (curFormItem.changeHandle) {
  619. if (curFormItem.type === 'selectRemote' && curFormItem.remoteOptions) {
  620. let curOption = curFormItem.multiple ? [] : {}
  621. curFormItem.remoteOptions.forEach(item => {
  622. if (curFormItem.multiple) {
  623. const subArr = String(val).split(',') || []
  624. subArr.forEach(sub => {
  625. if (String(item.valRO) === sub) {
  626. curOption.push(item)
  627. }
  628. })
  629. } else {
  630. if (item.valRO === val) {
  631. curOption = item
  632. }
  633. }
  634. })
  635. // let curOption = {}
  636. // curFormItem.remoteOptions.forEach(item => {
  637. // if (item.valRO === val) {
  638. // curOption = item
  639. // }
  640. // })
  641. curFormItem.changeHandle(val, curFormItem, curOption)
  642. } else if (curFormItem.type === 'select' && curFormItem.options) {
  643. let curOption = curFormItem.multiple ? [] : {}
  644. curFormItem.options.forEach(item => {
  645. if (curFormItem.multiple) {
  646. const subArr = val || []
  647. subArr.forEach(sub => {
  648. if (item.val === sub) {
  649. curOption.push(item)
  650. }
  651. })
  652. } else {
  653. if (item.val === val) {
  654. curOption = item
  655. }
  656. }
  657. })
  658. curFormItem.changeHandle(val, curFormItem, curOption)
  659. } else {
  660. curFormItem.changeHandle(val, curFormItem, this.curFormIndex)
  661. }
  662. }
  663. if (curFormItem.type === 'selectRemote') {
  664. this.remoteChange(val)
  665. }
  666. if (curFormItem.type === 'checkbox' || curFormItem.type === 'switch') {
  667. // console.log(this.curFormKey)
  668. this.$set(this.baseForm, this.curFormKey, val)
  669. }
  670. }
  671. })
  672. },
  673. focusHandle(key) {
  674. this.curFormKey = key
  675. for (let i = 0; i < this.curData.length; i++) {
  676. if (this.curData[i].key === this.curFormKey) {
  677. this.curFormIndex = i
  678. const curFormItem = this.curData[i]
  679. if (curFormItem.focusHandle) {
  680. curFormItem.focusHandle(key, curFormItem, this.curFormIndex)
  681. }
  682. return
  683. }
  684. }
  685. },
  686. cuImgOpen(file, fileList) {
  687. const isLt10M = file.size / 1024 / 1024 < 1000
  688. if (!isLt10M) {
  689. this.$msgw('上传文件大小不能超过 1000MB!')
  690. return false
  691. }
  692. this.$nextTick(() => {
  693. let cObj = this.curData[this.curFormIndex]
  694. this.uploadObj = {
  695. url: URL.createObjectURL(file.raw),
  696. file,
  697. options: cObj.options,
  698. }
  699. this.isCIShow = true
  700. })
  701. },
  702. cuImgClose (url) {
  703. this.isCIShow = false
  704. if (url) {
  705. this.baseForm[this.curFormKey] = url
  706. }
  707. },
  708. remoteChange(val) {
  709. if (val) {
  710. const remoteParams = this.curData[this.curFormIndex].remoteParams
  711. if (remoteParams && remoteParams.changeKey) {
  712. this.$set(this.baseForm, remoteParams.changeKey, val)
  713. }
  714. }
  715. },
  716. remoteMethod(val, curI) {
  717. // const loading = this.$loading({
  718. // lock: true,
  719. // spinner: 'none',
  720. // background: 'rgba(0, 0, 0, 0.7)'
  721. // })ss
  722. let curIndex = this.curFormIndex
  723. if (Number(curI) > -1) curIndex = curI
  724. this.formLoading = true
  725. if (!this.curData[curIndex]) return
  726. const remoteParams = this.curData[curIndex].remoteParams
  727. const apiArr = remoteParams.api.split('?')
  728. const apiUrl = apiArr[0]
  729. const params = this.noEmpty(val) ? { [remoteParams.skey]: strTrim(val) } : {}
  730. const apiUrlArr = apiUrl.split('.')
  731. if (apiArr[1]) {
  732. const queryArr = apiArr[1].split('&')
  733. queryArr.forEach(item => {
  734. const itemArr = item.split('=')
  735. if (this.noEmpty(itemArr[1])) params[itemArr[0]] = itemArr[1]
  736. })
  737. }
  738. if (!this.$api[apiUrlArr[0]] || !this.$api[apiUrlArr[0]][apiUrlArr[1]]) {
  739. console.warn('tip:接口不存在')
  740. return
  741. }
  742. if (val !== null && !params[remoteParams.skey]) {
  743. this.curData[curIndex].remoteOptions = this.remoteOptionsPrev[curIndex]
  744. this.$set(this.curData[curIndex], 'remoteOptions', this.remoteOptionsPrev[curIndex])
  745. this.formLoading = false
  746. const baseForm = { ...this.baseForm }
  747. this.$refs['baseForm'].resetFields()
  748. window.setTimeout(() => {
  749. this.baseForm = { ...baseForm }
  750. this.isRemoteOne = false
  751. }, 200)
  752. // loading.close()
  753. return
  754. }
  755. this.$api[apiUrlArr[0]][apiUrlArr[1]](params).then(data => {
  756. const arr = data.list || []
  757. const remoteOptions = []
  758. arr.forEach(item => {
  759. const curItem = { keyRO: item[remoteParams.opKey], valRO: item[remoteParams.opVal] }
  760. remoteOptions.push({ ...item, ...curItem })
  761. })
  762. const defaultRemoteOptions = this.curData[curIndex].remoteOptions || []
  763. if (val === null && defaultRemoteOptions && defaultRemoteOptions.length > 0) {
  764. const edIndexArr = []
  765. defaultRemoteOptions.forEach((old, o) => {
  766. remoteOptions.forEach(r => {
  767. if (String(old.valRO) === String(r.valRO)) {
  768. edIndexArr.push(o)
  769. }
  770. })
  771. if (edIndexArr.indexOf(o) === -1 && this.noEmpty(old.valRO)) {
  772. remoteOptions.unshift(old)
  773. }
  774. })
  775. }
  776. this.curData[curIndex].remoteOptions = remoteOptions
  777. const remoteOptionsPrev = this.remoteOptionsPrev[curIndex] || []
  778. const remoteOptionsPrev2 = [...remoteOptionsPrev]
  779. remoteOptionsPrev.forEach((one, o) => {
  780. remoteOptions.forEach(two => {
  781. if (one.valRO === two.valRO) {
  782. remoteOptionsPrev2.splice(o, 1)
  783. }
  784. })
  785. })
  786. this.remoteOptionsPrev[curIndex] = [...remoteOptionsPrev2, ...remoteOptions]
  787. this.formLoading = false
  788. this.selectRemoteNum++
  789. if (this.selectRemoteTotal === this.selectRemoteNum) {
  790. this.$emit('loaded')
  791. // loading.close()
  792. }
  793. this.curData = [...this.curData]
  794. })
  795. },
  796. btnHandle(key) { // 按钮回调
  797. this.curFormKey = key
  798. for (let i = 0; i < this.curData.length; i++) {
  799. if (this.curData[i].key === this.curFormKey) {
  800. this.$nextTick(() => {
  801. if (parseFloat(i).toString() === 'NaN') return
  802. const curFormItem = this.curData[i]
  803. if (curFormItem) {
  804. if (curFormItem.btnHandle) {
  805. curFormItem.btnHandle(key, this.curData[i].remoteOptions)
  806. }
  807. }
  808. })
  809. return
  810. }
  811. }
  812. }
  813. }
  814. }
  815. </script>
  816. <style lang="scss" scoped>
  817. .img-upload {
  818. ::v-deep .el-upload {
  819. border: 1px dashed #d9d9d9;
  820. border-radius: 6px;
  821. cursor: pointer;
  822. position: relative;
  823. overflow: hidden;
  824. &:hover {
  825. border-color: #409EFF;
  826. }
  827. }
  828. .icon {
  829. font-size: 28px;
  830. color: #8c939d;
  831. width: 178px;
  832. height: 178px;
  833. line-height: 178px;
  834. text-align: center;
  835. }
  836. .img {
  837. width: 178px;
  838. height: 178px;
  839. display: block;
  840. }
  841. }
  842. ::v-deep .el-form-item__content{
  843. display: flex;
  844. align-items: center;
  845. height: 100%;
  846. }
  847. </style>