| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- <template>
- <el-table-column
- :prop="itemCol.prop"
- :show-overflow-tooltip="itemCol.tooltip"
- :align="handleAlign(itemCol)"
- :label="itemCol.label"
- :fixed="itemCol.fixed ? itemCol.fixed : false"
- :width="itemCol.width"
- :formatter="itemCol.formatter"
- :min-width="itemCol.minWidth"
- >
- <!-- 单列中嵌套多列数据 -->
- <template v-if="itemCol.type === 'innerColumn' && itemCol.children && itemCol.children.length">
- <TableColumn
- v-for="(innerItem, index) in itemCol.children"
- :key="index"
- :align="innerItem && innerItem.align"
- :itemCol="innerItem">
- <!-- 传递插槽 -->
- <template v-for="(slot, name) in $scopedSlots" :slot="name" slot-scope="slotScope">
- {{slot}}
- <slot :name="name" v-bind="slotScope"></slot>
- </template>
- </TableColumn>
- </template>
- <!-- 自定义表头 -->
- <template slot="header" slot-scope="scope">
- <div v-if="itemCol.headerIcon" style="display: flex;align-items: center;justify-content: center;">
- {{ itemCol.label }}<i @click="delColumn((scope.$index))" style="font-size: 25px;" :class="itemCol.headerIcon"></i>
- </div>
- <div v-else style="display: flex;align-items: center;justify-content: center;">
- {{ itemCol.label }}
- </div>
- </template>
- <template slot-scope="scope">
- <!-- 操作列 -->
- <div v-if="itemCol.prop == 'operation'">
- <template v-if="!itemCol.type">
- <span v-for="oper in itemCol.children" :key="oper.key">
- <el-button
- v-if="!oper.popover && scope.row[oper.key] != 'hide' && !oper.hide"
- class="btn-item"
- :class="{ 'danger': oper.key === 'delete'}"
- type="text"
- size="small"
- @click="operClick(scope, oper.click)"
- >
- {{ oper.name }}
- </el-button>
- <el-button
- v-if="scope.row[oper.key] == 'hide' || oper.hide"
- class="btn-item"
- type="text"
- size="small"
- >
- </el-button>
- <el-popover
- v-if="
- oper.popover &&
- scope.row[oper.key] != 'hide' &&
- oper.hide !== 'hide'
- "
- placement="top"
- width="160"
- v-model="oper.visible"
- >
- <p>{{ oper.content }}</p>
- <div style="text-align: right; margin: 0">
- <el-button size="mini" type="text" @click="oper.visible = false">取消</el-button>
- <el-button type="primary" size="mini" @click="operClick(scope, oper.click); oper.visible = false">确定</el-button>
- </div>
- <el-button
- slot="reference"
- class="btn-item"
- type="text"
- :class="{ 'danger': oper.key === 'delete' || oper.key === 'obsolete' }"
- size="small"
- >{{ oper.name }}</el-button
- >
- </el-popover>
- </span>
- </template>
- <template v-if="itemCol.type == 'custom'">
- <slot name="operation" v-bind="scope.row"></slot>
- </template>
- </div>
- <!-- 序号列 -->
- <div v-else-if="itemCol.prop == 'seq'">
- <span>
- {{itemCol.getIndex ? itemCol.getIndex(scope.$index) : scope.$index + 1 }}
- </span>
- </div>
- <!-- 小图预览 -->
- <div v-else-if="itemCol.type == 'imagePreview'">
- <el-image
- style="width: 50px; height: 50px"
- :src="scope.row[itemCol.prop]"
- @click="onPreview(scope.row, itemCol)"
- v-if="scope.row[itemCol.prop]"
- fit="cover"
- />
- <span v-else>--</span>
- </div>
- <!-- 字段合并 -->
- <div v-else-if="itemCol.type == 'merge'">
- <span>{{scope.row[itemCol.prop.split(',')[0]] || '--'}}{{scope.row[itemCol.prop.split(',')[1]]}}</span>
- </div>
- <!-- 表格可编辑列 -->
- <div v-else-if="itemCol.type == 'editItem'" style="display: flex;align-items: center;">
- <el-input
- @change="editItemChange(scope.row, itemCol)"
- v-if="itemCol.tag == 'input'"
- v-model="scope.row[itemCol.prop]"
- :disabled="isDisabled"
- placeholder="请输入"
- clearable
- size="small"
- />
- <el-input-number
- @change="editItemNumChange(scope.row, itemCol)"
- v-if="itemCol.tag == 'inputNumber'"
- v-model="scope.row[itemCol.prop]"
- :disabled="isDisabled"
- placeholder="请输入"
- size="small"
- :precision="itemCol.precision"
- :step="itemCol.step"
- clearable
- />
- <el-select v-if="itemCol.tag == 'select'" v-model="scope.row[itemCol.prop]" :disabled="isDisabled" clearable filterable placeholder="" size="small">
- <el-option v-for="(ele, idx) in itemCol.oprion" :key="idx" :label="ele[itemCol.optionLabel]" :value="ele[itemCol.optionValue]" />
- </el-select>
- <i @click="delRow(scope.$index)" v-if="itemCol.icon" style="font-size: 25px;" :class="itemCol.icon"></i>
- </div>
- <!-- 链接跳转 -->
- <div v-else-if="itemCol.type == 'link'">
- <el-button
- type="text"
- size="small"
- class="linkBtn"
- v-if="!scope.row['disabled'] && scope.row[itemCol.prop] !== '无'"
- @click="operClick(scope, itemCol.click)"
- >
- <!-- 除0外,其他空值(null、undefined)转为'--'-->
- {{
- scope.row[itemCol.prop] === ""
- ? "--"
- : (scope.row[itemCol.prop] !== null && scope.row[itemCol.prop] !== undefined) ? scope.row[itemCol.prop] : "--"
- }}
- </el-button>
- <span class="text-disable linkBtn" v-else>{{
- scope.row[itemCol.prop] === ""
- ? "--"
- : (scope.row[itemCol.prop] !== null && scope.row[itemCol.prop] !== undefined) ? scope.row[itemCol.prop] : "--"
- }}</span>
- </div>
- <!-- 单选/多选 -->
- <div v-else-if="itemCol.type == 'choice'">
- <div v-if="scope.row[itemCol.prop]">
- <div
- v-if="
- scope.row[itemCol.isRadioChecked] == '0' ||
- (scope.row[itemCol.prop] && scope.row[itemCol.prop][0] && scope.row[itemCol.prop][0][itemCol.isRadioChecked] == '0')
- "
- >
- <el-radio-group
- :value="scope.row[itemCol.model].join()"
- class="ml-4"
- >
- <el-radio
- v-for="radioItem in scope.row[itemCol.prop]"
- :label="radioItem.argumentsCode"
- size="large"
- :key="radioItem.argumentsName"
- >{{ radioItem.argumentsName }}</el-radio
- >
- </el-radio-group>
- </div>
- <div v-else>
- <el-checkbox-group :value="scope.row[itemCol.model]">
- <el-checkbox
- v-for="checkboxItem in scope.row[itemCol.prop]"
- :label="checkboxItem.argumentsCode"
- size="large"
- :key="checkboxItem.argumentsCode"
- >{{ checkboxItem.argumentsName }}</el-checkbox
- >
- </el-checkbox-group>
- </div>
- </div>
- </div>
- <!-- 需要遍历查找 -->
- <div v-else-if="itemCol.type == 'find'">
- <el-tooltip
- v-if="Boolean(scope.row[itemCol.customTip])"
- effect="dark"
- :content="scope.row[itemCol.customTip]"
- placement="top"
- >
- <span>{{
- toLabel(
- itemCol.option,
- scope.row[itemCol.prop],
- itemCol.optionValue,
- itemCol.optionLabel,
- itemCol.isNum
- )
- }}</span>
- </el-tooltip>
- <span v-else>
- {{
- toLabel(
- itemCol.option,
- scope.row[itemCol.prop],
- itemCol.optionValue,
- itemCol.optionLabel,
- itemCol.isNum
- )
- }}</span>
- </div>
- <div v-else-if="itemCol.type == 'tooltips'">
- <el-tooltip placement="top">
- <template slot="content" v-if="!itemCol.customTip">
- <p style="max-width: 15vw">
- {{ scope.row[itemCol.prop] }}
- </p>
- </template>
- <template slot="content" v-if="itemCol.customTip" >
- <p style="max-width: 15vw">
- {{ scope.row[itemCol.customTip] }}
- </p>
- </template>
- <div
- class="table-ellipsis"
- :style="`color:${itemCol.color}`"
- style="
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- "
- >
- {{ scope.row[itemCol.prop] }}
- </div>
- </el-tooltip>
- </div>
- <!-- 转化数据字典,支持显示多选结果 -->
- <span v-else-if="itemCol.type == 'dict2Name'">
- <template v-if="scope.row[itemCol.prop]">
- {{ parseDictValue2Name(scope.row[itemCol.prop], itemCol.dictList, itemCol) }}
- </template>
- <template v-else>--</template>
- </span>
- <!-- 自定义 -->
- <span v-else-if="itemCol.type == 'diy'">
- <slot :name="itemCol.prop" v-bind="scope.row"></slot>
- <span v-if="!$scopedSlots[itemCol.prop]">{{ scope.row[itemCol.prop] === '' ? '--' : scope.row[itemCol.prop] }}</span>
- </span>
- <span :style="`color:${itemCol.color}`" v-else>
- {{ scope.row[itemCol.prop] === '' ? '--' : scope.row[itemCol.prop] }}
- </span>
- </template>
- </el-table-column>
- </template>
- <script>
- import TableColumn from "./TableColumn.vue";
- export default {
- name: "TableColumn",
- components: {
- TableColumn,
- },
- props: {
- // 编辑时可传
- isDisabled: {
- type: Boolean,
- default: false,
- },
- itemCol: {
- type: Object,
- default: function() {
- return {};
- },
- },
- selection: {
- type: Boolean,
- default: true,
- },
- },
- data() {
- return {
- showViewer: false,
- };
- },
- computed: {
- customSlots() {
- return {
- ...this.$slots,
- };
- },
- },
- methods: {
- toLabel(
- option = [],
- val,
- value = "value",
- label = "label",
- isNum = false
- ) {
- // 该代码以后删掉
- if (isNum) {
- val = Number(val);
- }
- let labelName = option.find((item) => item[value] == val);
- return labelName ? labelName[label] : "--";
- },
- handleSelection(row) {
- return !row.selectionDisabled;
- },
- handleAlign(item) {
- if (item.align == "center") {
- return "center";
- }
- if (item.type == "innerColumn") {
- return "center";
- }
- if (item.prop == "seq") {
- return "center";
- } else {
- return "left";
- }
- // return item.align
- },
- operClick(scope, funName) {
- if (typeof funName === 'function') {
- funName(scope.row, scope.column, scope.$index);
- }
- },
- // 根据字典中的value转为name
- parseDictValue2Name(val, list, item) {
- if (!item || !item.multiple) {
- let name = '';
- list.map((e) => {
- if (e.value == val) {
- name = e.label;
- }
- });
- return name || val || '--';
- } else {
- let str = '';
- let arr = val.split(',');
- list.map((e) => {
- if (arr.includes(e.value)) {
- str += e.label + '、';
- }
- });
- return str ? str.slice(0, str.length - 1) : '--';
- }
- },
- // 图片展示弹框显示
- onPreview(row, itemCol) {
- // 判断该图片展示是否需要接口查询 (处理字段为base64的情况)
- if (itemCol && itemCol.imgQuery) {
- let axios = itemCol.imgQuery.queryFn;
- if (axios) {
- axios({
- id: row[itemCol.imgQuery.primaryKey],
- }).then((res) => {
- if (res.code == 200) {
- if (res.data[[itemCol.prop]].indexOf("/file") === -1) {
- // 使用base64时,拼接标识处理
- this.$emit("imgPreview", [
- `data:image/png;base64, ${res.data[[itemCol.prop]]}`,
- ]);
- } else {
- // 使用链接时直接反回
- this.$emit("imgPreview", [res.data[itemCol.prop]]);
- }
- }
- });
- }
- } else {
- this.$emit("imgPreview", row[itemCol.prop] ? row[itemCol.prop].split(",") : []);
- }
- },
- editItemChange(val, itemCol) {
- this.$emit("editItemChange", val, itemCol);
- },
- editItemNumChange(val, itemCol) {
- this.$emit("editItemNumChange", val, itemCol);
- },
- delRow(index){
- this.$emit("delRow", index);
- },
- delColumn(index){
- this.$emit("delColumn", index);
- }
- },
- };
- </script>
- <style lang="scss" scoped>
- .btn-item {
- margin: 0 10px;
- }
- .btn-item:nth-child(1) {
- margin-left: 0;
- }
- // 2.1.9版本之后新增此样式
- .btn-item.el-button--small:nth-child(1) {
- padding-left: 0 !important;
- }
- .danger {
- color: #f56455 !important;
- }
- .linkBtn {
- font-size: 14px;
- white-space: normal;
- line-height: 16px;
- text-align: left;
- height: auto;
- }
- // ::v-deep(.linkBtn) {
- // padding: 0;
- // >span {
- // overflow: hidden;
- // text-overflow: ellipsis;
- // white-space: nowrap;
- // width: 80px;
- // display: block;
- // }
- // }
- .text-disable {
- // padding-left: 12px;
- }
- //有自带的border
- // .el-input,.el-input-number,.el-select{
- // width: 100%;
- // border: 1px solid #dedede;
- // }
- </style>
|