layoutItem.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. <template>
  2. <div
  3. :class="{
  4. 'layout-width': ['grid', 'table', 'card', 'divider', 'html'].includes(
  5. record.type
  6. )
  7. }"
  8. >
  9. <!-- 动态表格设计模块 start -->
  10. <template v-if="record.type === 'batch'">
  11. <div
  12. class="batch-box"
  13. :class="{ active: record.key === selectItem.key }"
  14. @click.stop="handleSelectItem(record)"
  15. >
  16. <a-form-item
  17. :label="!record.options.showLabel ? '' : record.label"
  18. :label-col="
  19. config.layout === 'horizontal' && record.options.showLabel
  20. ? config.labelLayout === 'flex'
  21. ? { style: `width:${config.labelWidth}px` }
  22. : config.labelCol
  23. : {}
  24. "
  25. :wrapper-col="
  26. config.layout === 'horizontal' && record.options.showLabel
  27. ? config.labelLayout === 'flex'
  28. ? { style: 'width:auto;flex:1' }
  29. : config.wrapperCol
  30. : {}
  31. "
  32. :style="
  33. config.layout === 'horizontal' &&
  34. config.labelLayout === 'flex' &&
  35. record.options.showLabel
  36. ? { display: 'flex' }
  37. : {}
  38. "
  39. >
  40. <draggable
  41. tag="div"
  42. class="draggable-box"
  43. v-bind="{
  44. group: insertAllowed ? 'form-draggable' : '',
  45. ghostClass: 'moving',
  46. animation: 180,
  47. handle: '.drag-move'
  48. }"
  49. v-model="record.list"
  50. @start="$emit('dragStart', $event, record.list)"
  51. @add="$emit('handleColAdd', $event, record.list)"
  52. >
  53. <transition-group tag="div" name="list" class="list-main">
  54. <formNode
  55. v-for="item in record.list"
  56. :key="item.key"
  57. class="drag-move"
  58. :selectItem.sync="selectItem"
  59. :record="item"
  60. :hideModel="hideModel"
  61. :config="config"
  62. @handleSelectItem="handleSelectItem"
  63. @handleColAdd="handleColAdd"
  64. @handleCopy="$emit('handleCopy')"
  65. @handleShowRightMenu="handleShowRightMenu"
  66. @handleDelete="$emit('handleDelete')"
  67. />
  68. </transition-group>
  69. </draggable>
  70. </a-form-item>
  71. <div
  72. class="copy"
  73. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  74. @click.stop="$emit('handleCopy')"
  75. >
  76. <a-icon type="copy" />
  77. </div>
  78. <div
  79. class="delete"
  80. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  81. @click.stop="$emit('handleDelete')"
  82. >
  83. <a-icon type="delete" />
  84. </div>
  85. </div>
  86. </template>
  87. <!-- 动态表格设计模块 end -->
  88. <!-- 选择输入列 start -->
  89. <template v-else-if="record.type === 'selectInputList'">
  90. <div
  91. class="select-input-list-box"
  92. :class="{ active: record.key === selectItem.key }"
  93. @click.stop="handleSelectItem(record)"
  94. >
  95. <a-form-item
  96. :label="!record.options.showLabel ? '' : record.label"
  97. :label-col="
  98. config.layout === 'horizontal' && record.options.showLabel
  99. ? config.labelLayout === 'flex'
  100. ? { style: `width:${config.labelWidth}px` }
  101. : config.labelCol
  102. : {}
  103. "
  104. :wrapper-col="
  105. config.layout === 'horizontal' && record.options.showLabel
  106. ? config.labelLayout === 'flex'
  107. ? { style: 'width:auto;flex:1' }
  108. : config.wrapperCol
  109. : {}
  110. "
  111. :style="
  112. config.layout === 'horizontal' &&
  113. config.labelLayout === 'flex' &&
  114. record.options.showLabel
  115. ? { display: 'flex' }
  116. : {}
  117. "
  118. >
  119. <div
  120. class="column-box"
  121. v-for="(column, index) in record.columns"
  122. :key="index"
  123. >
  124. <div class="check-box">
  125. <a-checkbox v-if="record.options.multiple" disabled>
  126. {{ column.label }}
  127. </a-checkbox>
  128. <a-radio-group v-else disabled name="radio">
  129. <a-radio :value="column.value">{{ column.label }}</a-radio>
  130. </a-radio-group>
  131. </div>
  132. <draggable
  133. tag="div"
  134. class="draggable-box"
  135. v-bind="{
  136. group: insertAllowed ? 'form-draggable' : '',
  137. ghostClass: 'moving',
  138. animation: 180,
  139. handle: '.drag-move'
  140. }"
  141. v-model="column.list"
  142. @start="$emit('dragStart', $event, column.list)"
  143. @add="$emit('handleColAdd', $event, column.list)"
  144. >
  145. <transition-group tag="div" name="list" class="list-main">
  146. <formNode
  147. v-for="item in column.list"
  148. :key="item.key"
  149. class="drag-move"
  150. :selectItem.sync="selectItem"
  151. :record="item"
  152. :hideModel="hideModel"
  153. :config="config"
  154. @handleSelectItem="handleSelectItem"
  155. @handleColAdd="handleColAdd"
  156. @handleCopy="$emit('handleCopy')"
  157. @handleShowRightMenu="handleShowRightMenu"
  158. @handleDelete="$emit('handleDelete')"
  159. />
  160. </transition-group>
  161. </draggable>
  162. </div>
  163. </a-form-item>
  164. <div
  165. class="copy"
  166. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  167. @click.stop="$emit('handleCopy')"
  168. >
  169. <a-icon type="copy" />
  170. </div>
  171. <div
  172. class="delete"
  173. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  174. @click.stop="$emit('handleDelete')"
  175. >
  176. <a-icon type="delete" />
  177. </div>
  178. </div>
  179. </template>
  180. <!-- 选择输入列 end -->
  181. <!-- 标签Tabs布局 start -->
  182. <template v-else-if="record.type === 'tabs'">
  183. <div
  184. class="grid-box"
  185. :class="{ active: record.key === selectItem.key }"
  186. @click.stop="handleSelectItem(record)"
  187. >
  188. <a-tabs
  189. class="grid-row"
  190. :default-active-key="0"
  191. :tabBarGutter="record.options.tabBarGutter || null"
  192. :type="record.options.type"
  193. :size="record.options.size"
  194. :tabPosition="record.options.tabPosition"
  195. :animated="record.options.animated"
  196. >
  197. <a-tab-pane
  198. v-for="(tabItem, index) in record.columns"
  199. :key="index"
  200. :tab="tabItem.label"
  201. >
  202. <div class="grid-col">
  203. <draggable
  204. tag="div"
  205. class="draggable-box"
  206. v-bind="{
  207. group: 'form-draggable',
  208. ghostClass: 'moving',
  209. animation: 180,
  210. handle: '.drag-move'
  211. }"
  212. v-model="tabItem.list"
  213. @start="$emit('dragStart', $event, tabItem.list)"
  214. @add="$emit('handleColAdd', $event, tabItem.list)"
  215. >
  216. <transition-group tag="div" name="list" class="list-main">
  217. <layoutItem
  218. class="drag-move"
  219. v-for="item in tabItem.list"
  220. :key="item.key"
  221. :selectItem.sync="selectItem"
  222. :startType="startType"
  223. :insertAllowedType="insertAllowedType"
  224. :record="item"
  225. :hideModel="hideModel"
  226. :config="config"
  227. @handleSelectItem="handleSelectItem"
  228. @handleColAdd="handleColAdd"
  229. @handleCopy="$emit('handleCopy')"
  230. @handleShowRightMenu="handleShowRightMenu"
  231. @handleDelete="$emit('handleDelete')"
  232. />
  233. </transition-group>
  234. </draggable>
  235. </div>
  236. </a-tab-pane>
  237. </a-tabs>
  238. <div
  239. class="copy"
  240. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  241. @click.stop="$emit('handleCopy')"
  242. >
  243. <a-icon type="copy" />
  244. </div>
  245. <div
  246. class="delete"
  247. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  248. @click.stop="$emit('handleDelete')"
  249. >
  250. <a-icon type="delete" />
  251. </div>
  252. </div>
  253. </template>
  254. <!-- 标签Tabs布局 end -->
  255. <!-- 栅格布局 start -->
  256. <template v-else-if="record.type === 'grid'">
  257. <div
  258. class="grid-box"
  259. :class="{ active: record.key === selectItem.key }"
  260. @click.stop="handleSelectItem(record)"
  261. >
  262. <a-row class="grid-row" :gutter="record.options.gutter">
  263. <a-col
  264. class="grid-col"
  265. v-for="(colItem, idnex) in record.columns"
  266. :key="idnex"
  267. :span="colItem.span || 0"
  268. >
  269. <draggable
  270. tag="div"
  271. class="draggable-box"
  272. v-bind="{
  273. group: 'form-draggable',
  274. ghostClass: 'moving',
  275. animation: 180,
  276. handle: '.drag-move'
  277. }"
  278. v-model="colItem.list"
  279. @start="$emit('dragStart', $event, colItem.list)"
  280. @add="$emit('handleColAdd', $event, colItem.list)"
  281. >
  282. <transition-group tag="div" name="list" class="list-main">
  283. <layoutItem
  284. class="drag-move"
  285. v-for="item in colItem.list"
  286. :key="item.key"
  287. :selectItem.sync="selectItem"
  288. :startType="startType"
  289. :insertAllowedType="insertAllowedType"
  290. :record="item"
  291. :hideModel="hideModel"
  292. :config="config"
  293. @handleSelectItem="handleSelectItem"
  294. @handleColAdd="handleColAdd"
  295. @handleCopy="$emit('handleCopy')"
  296. @handleShowRightMenu="handleShowRightMenu"
  297. @handleDelete="$emit('handleDelete')"
  298. />
  299. </transition-group>
  300. </draggable>
  301. </a-col>
  302. </a-row>
  303. <div
  304. class="copy"
  305. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  306. @click.stop="$emit('handleCopy')"
  307. >
  308. <a-icon type="copy" />
  309. </div>
  310. <div
  311. class="delete"
  312. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  313. @click.stop="$emit('handleDelete')"
  314. >
  315. <a-icon type="delete" />
  316. </div>
  317. </div>
  318. </template>
  319. <!-- 栅格布局 end -->
  320. <!-- 卡片布局 start -->
  321. <template v-else-if="record.type === 'card'">
  322. <div
  323. class="grid-box"
  324. :class="{ active: record.key === selectItem.key }"
  325. @click.stop="handleSelectItem(record)"
  326. >
  327. <a-card class="grid-row" :title="record.label">
  328. <div class="grid-col">
  329. <draggable
  330. tag="div"
  331. class="draggable-box"
  332. v-bind="{
  333. group: 'form-draggable',
  334. ghostClass: 'moving',
  335. animation: 180,
  336. handle: '.drag-move'
  337. }"
  338. v-model="record.list"
  339. @start="$emit('dragStart', $event, record.list)"
  340. @add="$emit('handleColAdd', $event, record.list)"
  341. >
  342. <transition-group tag="div" name="list" class="list-main">
  343. <layoutItem
  344. class="drag-move"
  345. v-for="item in record.list"
  346. :key="item.key"
  347. :selectItem.sync="selectItem"
  348. :startType="startType"
  349. :insertAllowedType="insertAllowedType"
  350. :record="item"
  351. :hideModel="hideModel"
  352. :config="config"
  353. @handleSelectItem="handleSelectItem"
  354. @handleColAdd="handleColAdd"
  355. @handleCopy="$emit('handleCopy')"
  356. @handleShowRightMenu="handleShowRightMenu"
  357. @handleDelete="$emit('handleDelete')"
  358. />
  359. </transition-group>
  360. </draggable>
  361. </div>
  362. </a-card>
  363. <div
  364. class="copy"
  365. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  366. @click.stop="$emit('handleCopy')"
  367. >
  368. <a-icon type="copy" />
  369. </div>
  370. <div
  371. class="delete"
  372. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  373. @click.stop="$emit('handleDelete')"
  374. >
  375. <a-icon type="delete" />
  376. </div>
  377. </div>
  378. </template>
  379. <!-- 卡片布局 end -->
  380. <!-- 表格布局 start -->
  381. <template v-else-if="record.type === 'table'">
  382. <div
  383. class="table-box"
  384. :class="{ active: record.key === selectItem.key }"
  385. @click.stop="handleSelectItem(record)"
  386. >
  387. <table
  388. class="table-layout kk-table-9136076486841527"
  389. :class="{
  390. bright: record.options.bright,
  391. small: record.options.small,
  392. bordered: record.options.bordered
  393. }"
  394. :style="record.options.customStyle"
  395. >
  396. <tr v-for="(trItem, trIndex) in record.trs" :key="trIndex">
  397. <td
  398. class="table-td"
  399. v-for="(tdItem, tdIndex) in trItem.tds"
  400. v-show="tdItem.colspan && tdItem.rowspan"
  401. :key="tdIndex"
  402. :colspan="tdItem.colspan"
  403. :rowspan="tdItem.rowspan"
  404. @contextmenu.prevent="
  405. $emit('handleShowRightMenu', $event, record, trIndex, tdIndex)
  406. "
  407. >
  408. <draggable
  409. tag="div"
  410. class="draggable-box"
  411. v-bind="{
  412. group: 'form-draggable',
  413. ghostClass: 'moving',
  414. animation: 180,
  415. handle: '.drag-move'
  416. }"
  417. v-model="tdItem.list"
  418. @start="$emit('dragStart', $event, tdItem.list)"
  419. @add="$emit('handleColAdd', $event, tdItem.list)"
  420. >
  421. <transition-group tag="div" name="list" class="list-main">
  422. <layoutItem
  423. class="drag-move"
  424. v-for="item in tdItem.list"
  425. :key="item.key"
  426. :selectItem.sync="selectItem"
  427. :startType="startType"
  428. :insertAllowedType="insertAllowedType"
  429. :record="item"
  430. :hideModel="hideModel"
  431. :config="config"
  432. @handleSelectItem="handleSelectItem"
  433. @handleColAdd="handleColAdd"
  434. @handleCopy="$emit('handleCopy')"
  435. @handleShowRightMenu="handleShowRightMenu"
  436. @handleDelete="$emit('handleDelete')"
  437. />
  438. </transition-group>
  439. </draggable>
  440. </td>
  441. </tr>
  442. </table>
  443. <div
  444. class="copy"
  445. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  446. @click.stop="$emit('handleCopy')"
  447. >
  448. <a-icon type="copy" />
  449. </div>
  450. <div
  451. class="delete"
  452. :class="record.key === selectItem.key ? 'active' : 'unactivated'"
  453. @click.stop="$emit('handleDelete')"
  454. >
  455. <a-icon type="delete" />
  456. </div>
  457. </div>
  458. </template>
  459. <!-- 表格布局 end -->
  460. <template v-else>
  461. <formNode
  462. :key="record.key"
  463. :selectItem.sync="selectItem"
  464. :record="record"
  465. :config="config"
  466. :hideModel="hideModel"
  467. @handleSelectItem="handleSelectItem"
  468. @handleCopy="$emit('handleCopy')"
  469. @handleDelete="$emit('handleDelete')"
  470. @handleShowRightMenu="$emit('handleShowRightMenu')"
  471. />
  472. </template>
  473. </div>
  474. </template>
  475. <script>
  476. /*
  477. * author kcz
  478. * date 2019-11-20
  479. * description 使用递归组件调用自己,生成布局结构及表单
  480. */
  481. import draggable from "vuedraggable";
  482. import formNode from "./formNode";
  483. export default {
  484. name: "layoutItem",
  485. props: {
  486. record: {
  487. type: Object,
  488. required: true
  489. },
  490. selectItem: {
  491. type: Object,
  492. required: true
  493. },
  494. config: {
  495. type: Object,
  496. required: true
  497. },
  498. startType: {
  499. type: String,
  500. required: true
  501. },
  502. insertAllowedType: {
  503. type: Array,
  504. required: true
  505. },
  506. hideModel: {
  507. type: Boolean,
  508. default: false
  509. }
  510. },
  511. computed: {
  512. insertAllowed() {
  513. return this.insertAllowedType.includes(this.startType);
  514. }
  515. },
  516. components: {
  517. formNode,
  518. draggable
  519. },
  520. methods: {
  521. handleShowRightMenu(e, record, trIndex, tdIndex) {
  522. this.$emit("handleShowRightMenu", e, record, trIndex, tdIndex);
  523. },
  524. handleSelectItem(record) {
  525. this.$emit("handleSelectItem", record);
  526. },
  527. handleColAdd(e, list) {
  528. this.$emit("handleColAdd", e, list);
  529. }
  530. }
  531. };
  532. </script>