123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- <template>
- <div class="basic-table">
- <cip-table :offset="offset"
- v-model:data="proxyValue"
- :columns="options"
- :depend-on-values="dependOnValues"
- :border="!hideBorder"
- :field-key="fieldKey"
- :row-key="securityConfig.rowKey"
- :tree-props="optionProps"
- :default-expand-all="securityConfig.defaultExpendAll"
- :rule-key="securityConfig.ruleKey || fieldKey"
- :tableHeaderLabel="securityConfig.tableHeaderLabel"
- :hide-index="securityConfig.hideIndex"
- :index-fixed="securityConfig.indexFixed ?? true"
- :show-summary="securityConfig.showSummary"
- :span-method="securityConfig.spanMethod"
- :height="securityConfig.height"
- size="small"
- :stripe="true"
- :in-form="true">
- <el-table-column :min-width="isTreeTable && !securityConfig.hideAddChild ? '90px':'70px'" v-if="!securityConfig.hideDelete" fixed="right" label="操作">
- <template #default="{$index, row}">
- <cip-table-button v-if="!securityConfig.hideAdd" @click="insertItem($index)">
- <i class="el-icon-circle-plus-outline cip-primary-color handler-size"/>
- </cip-table-button>
- <template v-if="isTreeTable && !securityConfig.hideAddChild">
- <cip-table-button @click="insertChildItem($index,row)">
- <svg t="1656469520966" class="handler-size" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1591" width="1em" height="1em">
- <path style="transform: scale(0.5)" stroke-width="24px" stroke="currentColor" fill="currentColor" d="M778.5984 619.52H727.04v-51.5584c0-11.3152-9.1648-20.48-20.48-20.48s-20.48 9.1648-20.48 20.48V619.52h-51.5584c-11.3152 0-20.48 9.1648-20.48 20.48s9.1648 20.48 20.48 20.48H686.08v51.5584c0 11.3152 9.1648 20.48 20.48 20.48s20.48-9.1648 20.48-20.48V660.48h51.5584c11.3152 0 20.48-9.1648 20.48-20.48s-9.1648-20.48-20.48-20.48z" p-id="1592"></path>
- <path stroke-width="24px" stroke="currentColor" fill="currentColor" d="M704 404.48c-122.624 0-223.0784 94.8224-232.192 215.0912-0.256 0-0.512-0.0512-0.768-0.0512H286.72V194.56h419.84c11.3152 0 20.48-9.1648 20.48-20.48s-9.1648-20.48-20.48-20.48H107.52c-11.3152 0-20.48 9.1648-20.48 20.48s9.1648 20.48 20.48 20.48h138.24v445.44c0 11.3152 9.1648 20.48 20.48 20.48h204.8c0.4096 0 0.768-0.1024 1.1264-0.1024C483.6864 778.24 583.0656 870.4 704 870.4c128.6656 0 232.96-104.2944 232.96-232.96S832.6656 404.48 704 404.48z m0 424.96c-105.8816 0-192-86.1184-192-192S598.1184 445.44 704 445.44s192 86.1184 192 192-86.1184 192-192 192z" p-id="1593"></path>
- </svg>
- </cip-table-button>
- </template>
- <cip-table-button @click="deleteItem($index, row)">
- <i class="el-icon-remove-outline cip-danger-color handler-size"/>
- </cip-table-button>
- </template>
- </el-table-column>
- </cip-table>
- <div style="text-align: center" v-if="!securityConfig.hideAdd">
- <el-button size="medium" type="text" @click="addItem">
- <i class="el-icon-circle-plus create-handle" />
- </el-button>
- </div>
- </div>
- </template>
- <script>
- import { computed, defineAsyncComponent, nextTick } from 'vue'
- import { formInputProps, fromInputEmits } from '@cip/components/cip-form-input/form-input-props'
- import { ElButton, ElMessageBox, ElTableColumn } from 'element-plus'
- import { useFormInput, useElementFormEvent } from '@cip/components/hooks/form-input'
- import CipTableButton from '@cip/components/cip-table-button'
- import { v4 as uuid } from 'uuid'
- import { setOptionWritable } from './util'
- import { setFieldValue, getFieldValue } from '@cip/utils/util'
- import { analyseData, getPropertyKeyByPath } from '../../../cip-table/util'
- export default {
- name: 'basic-table',
- components: {
- CipTable: defineAsyncComponent(() => import('@cip/components/cip-table')),
- CipTableButton,
- ElButton,
- ElTableColumn
- },
- props: {
- ...formInputProps,
- type: {
- default: 'input'
- }
- },
- emits: [...fromInputEmits],
- setup (props, context) {
- const { handleChange } = useElementFormEvent() // inject('elFormItem', {})
- const formInput = useFormInput(props, context)
- const { proxyValue, securityConfig } = formInput
- const offset = computed(() => {
- return securityConfig.value.hideIndex ? undefined : 0
- })
- const hideBorder = computed(() => {
- return securityConfig.value.hideBorder
- })
- const optionProps = computed(() => {
- // el-table 默认treeProps参数
- return Object.assign({ children: 'children', hasChildren: 'hasChildren' }, securityConfig.value.optionProps)
- })
- const isTreeTable = computed(() => {
- // 只要设置了rowKey即认为该表单可能是树形表单
- return securityConfig.value.rowKey
- })
- const options = computed(() => {
- let options = securityConfig.value.options || []
- if (securityConfig.value.tableColumnStatus === 'writable') {
- options = setOptionWritable(options, true)
- }
- return options
- })
- const emitItemValidate = (val) => { // 触发验证
- nextTick(() => {
- handleChange(val)
- })
- }
- const getNewItem = () => {
- // tree 新增时必须由唯一key
- return isTreeTable.value ? { $id: uuid() } : {}
- }
- // 插入一个最后的行
- const addItem = () => {
- const val = Array.isArray(proxyValue.value) ? proxyValue.value : []
- const newItem = getNewItem()
- val.push(newItem)
- emitItemValidate(val)
- proxyValue.value = val
- }
- // 在当前行上方插入
- const insertItem = (index) => {
- const allArray = props.modelValue || []
- const newItem = getNewItem()
- if (isTreeTable.value) {
- const indexed = analyseData(allArray, optionProps.value)
- const realIndexArr = indexed[index]
- if (realIndexArr.length > 1) {
- const realIndex = realIndexArr.pop() // realIndex 为要剔除的index realIndexArr为父数组下标
- const key = getPropertyKeyByPath(realIndexArr, optionProps.value)
- const parentArr = getFieldValue(allArray, key)
- parentArr[optionProps.value.children].splice(realIndex, 0, newItem)
- } else {
- allArray.splice(realIndexArr[0], 0, newItem)
- }
- } else {
- allArray.splice(index, 0, newItem)
- }
- emitItemValidate(allArray)
- proxyValue.value = allArray
- }
- // 插入一个最后的子行
- const insertChildItem = (index, row) => {
- if (isTreeTable.value) {
- const newItem = getNewItem()
- const children = getFieldValue(row, optionProps.value.children)
- if (!children) {
- setFieldValue(row, optionProps.value.children, [newItem])
- } else {
- children.push(newItem)
- }
- }
- }
- // 删除当前行
- const deleteItem = (index) => {
- ElMessageBox.confirm('确实删除此列', '提示').then(() => {
- const allArray = props.modelValue || []
- if (isTreeTable.value) {
- const indexed = analyseData(allArray, optionProps.value)
- const realIndexArr = indexed[index]
- if (realIndexArr.length > 1) {
- const realIndex = realIndexArr.pop() // realIndex 为要剔除的index realIndexArr为父数组下标
- const key = getPropertyKeyByPath(realIndexArr, optionProps.value)
- const parentArr = getFieldValue(allArray, key)
- parentArr[optionProps.value.children].splice(realIndex, 1)
- } else {
- allArray.splice(realIndexArr[0], 1)
- }
- } else {
- allArray.splice(index, 1)
- }
- emitItemValidate(allArray)
- proxyValue.value = allArray
- }).catch(() => {})
- }
- return {
- offset,
- hideBorder,
- options,
- securityConfig,
- isTreeTable,
- insertItem,
- insertChildItem,
- deleteItem,
- addItem,
- proxyValue,
- optionProps
- }
- }
- }
- </script>
- <style lang="less">
- .el-form-item.is-error{
- .basic-table{
- outline: 1px solid @danger;
- }
- }
- .basic-table{
- overflow: hidden;
- width: 0;
- flex-grow: 2;
- .handler-size{
- font-size: 16px;
- width: 1em;
- height: 1em;
- vertical-align: -0.15em;
- fill: currentColor;
- overflow: hidden;
- }
- .create-handle{
- font-size: 24px;
- }
- }
- </style>
|