赞
踩
1)、按后台返回的数据进行合并单元格;
2)、点击新增,表格里面内容新增一行新的数据到最下方,并且序号加一;
3)、批量删除,勾选复选框点击删除,删除所勾选的数据,并且序号重新排序;
4)、勾选复选框,点击复制,复制所选的数据到列表最下方,并且序号重新排序;
5)、表格里面也有新增和删除功能,删除是删除当前行,新增是新增到当前行的下面,并且前面列动态合并,序号也重新排序;
1)、新增
2)、删除
3)、复制
4)、table表格里的删除新增
1)、HTML结构
注:N20是我们公司自己封装的组件,但是底层还是elementUI,结构并不是很重要,主要是结构上的:span-method="objectSpanMethod"方法。
- <template>
- <div style="position: static !important;" >
- <N20-expandable-pane title="风险场景规则" class="risk_scenario_form_class">
- <template slot="tips">
- <el-button type="primary" size="mini" @click="handleClick('add')">新增</el-button>
- <el-button size="mini" plain @click="handleClick('copy')">复制</el-button>
- <el-button type="danger" size="mini" plain @click="handleClick('delete')">删除</el-button>
- </template>
- <el-form :model="formTableData" ref="formTableData" >
- <N20-table :showSetsize="true" :data="formTableData.tableData" :columns="columns" @select="handleTableSelection" @select-all="handleTableSelectionAll" :span-method="objectSpanMethod" border>
- <el-table-column label="指标模型名称" slot="name" align="center" width="248" :render-header="addRedStar" >
- <template slot-scope="scope">
- <el-form-item :rules="[ { required: true, message: '', trigger: 'change' } ]" :prop="'tableData.' + scope.$index + '.name'">
- <N20-input-search class="defind-input-width" v-model="scope.row.name" readonly @click.native="chooseIndicator(scope.$index,scope.row)" :is-clearable="true" v-title="scope.row.name"/>
- </el-form-item>
- </template>
- </el-table-column>
-
- <el-table-column label="风险管控类型" slot="fxgklx" align="center" width="248" :render-header="addRedStar">
- <template slot-scope="scope">
- <el-form-item :rules="[ { required: true, message: '', trigger: 'change' } ]" :prop="'tableData.' + scope.$index + '.fxgklx'">
- <el-select style="width:224px" v-model="scope.row.fxgklx" clearable>
- <el-option v-for="item in fxgklxOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
- </el-select>
- </el-form-item>
- </template>
- </el-table-column>
-
- <el-table-column label="触发数据/业务类型" slot="ywlx" align="center" width="248" :render-header="addRedStar">
- <template slot-scope="scope">
- <el-form-item :rules="[ { required: true, message: '', trigger: 'change' } ]" :prop="'tableData.' + scope.$index + '.ywlx'">
- <N20-input-search class="defind-input-width" v-model="scope.row.ywlx" readonly @click.native="chooseIndicator(scope.$index,scope.row)" :is-clearable="true" v-title="scope.row.ywlx"/>
- </el-form-item>
- </template>
- </el-table-column>
-
- <el-table-column label="频率" slot="pl" align="center" width="116" :render-header="addRedStar">
- <template slot-scope="scope">
- <el-form-item :rules="[ { required: true, message: '', trigger: 'change' } ]" :prop="'tableData.' + scope.$index + '.pl'">
- <el-select style="width:100px" v-model="scope.row.pl" clearable>
- <el-option v-for="item in fxgklxOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
- </el-select>
- </el-form-item>
- </template>
- </el-table-column>
-
- <el-table-column label="适用单位设置" slot="sydwsz" align="center" width="118" >
- <template slot-scope="scope">
- <el-form-item>
- <el-button type="text" @click="handleSetting(scope.row)">设置</el-button>
- </el-form-item>
- </template>
- </el-table-column>
-
- <el-table-column slot="yz" align="center" width="400">
- <template slot="header">
- <span><span style="color:red;margin-right: 4px">*</span>阈值</span><i class="n20-icon-xinxitishi" style="margin-left: 4px" v-title="'实际场景规则无对比阈值的,此项可空,比例类型阈值需转换成小数类型数值项输入'" />
- </template>
- <template slot-scope="scope">
- <el-form-item :rules="[ { required: true, message: '', trigger: 'change' } ]" :prop="'tableData.' + scope.$index + '.yz'">
- <el-select style="width:100px;margin-right:4px" v-model="scope.row.yz" clearable>
- <el-option v-for="item in fxgklxOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
- </el-select>
- <el-input style="width:224px;margin-right:4px" v-model="scope.row.yz" clearable/>
- <el-button icon="n20-icon-xinzeng" type="text" @click="handleTableAdd(scope.row,scope.$index)"></el-button>
- <el-button icon="n20-icon-a-shanchuxuanzhong" type="text" @click="handleTableDel(scope.row,scope.$index)"></el-button>
- </el-form-item>
- </template>
- </el-table-column>
-
- <el-table-column label="风险等级" slot="fxdj" align="center" width="118" :render-header="addRedStar">
- <template slot-scope="scope">
- <el-form-item :rules="[ { required: true, message: '', trigger: 'change' } ]" :prop="'tableData.' + scope.$index + '.fxdj'">
- <el-select style="width:100px" v-model="scope.row.fxdj" clearable>
- <el-option v-for="item in fxgklxOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
- </el-select>
- </el-form-item>
- </template>
- </el-table-column>
-
- <el-table-column label="风险事件设置" slot="fxsjsz" align="center" width="118" >
- <template slot-scope="scope">
- <el-form-item>
- <el-button type="text" @click="handleSetting(scope.row)">设置</el-button>
- </el-form-item>
- </template>
- </el-table-column>
- </N20-table>
- </el-form>
- </N20-expandable-pane>
- <div class="operate-box" style="right:6px;width: calc(100% - 12px);left: 6px;">
- <el-button @click="handleConfirm('saveAndStart')" type="primary">保存启用</el-button>
- <el-button plain @click="handleConfirm('save')" >保存</el-button>
- </div>
- </div>
- </template>

2)、JS代码
- export default {
- name: 'dispositionAdd',//风险场景配置 新增
- data () {
- return {
- isIndexShow: false,
- indexRecordData: {},
- indexNum:0,
- formData: {
- yjfxcj: null,//一级风险场景
- ywcjbh:null,//业务场景编号
- ywcjmc:null,//业务场景名称
- gzmc:null,//规则名称
- gzlx:null,//规则类型
- ywcjms:null,//业务场景描述
- },
- formUnitData: {
- hyfl:null,//行业分类
- dwmc:null,//单位名称
- dwbh: null,//单位编号
- current: 1,
- size: 100,
- total: 0,
- },
- flag:false,
- rules: {
- yjfxcj: [
- { required: true, message: '请输入', trigger: 'blur' }
- ],
- ywcjbh: [
- { required: true, message: '请输入', trigger: 'blur' }
- ],
- ywcjmc: [
- { required: true, message: '请输入', trigger: 'blur' }
- ],
- gzmc: [
- { required: true, message: '请输入', trigger: 'blur' }
- ],
- },
- formTableData: {
- tableData: [
- { name: '上下游单位同名', type: '指标', fxgklx: '事前预测', ywlx: '',index:'1' },
- { name: '上下游单位同名', type: '指标', fxgklx: '事前预测', ywlx: '',index:'1' },
- { name: '上下游单位同名', type: '指标', fxgklx: '事前预测', ywlx: '',index:'1' },
- { name: '同名双向结算', type: '指标', fxgklx: '事后预警', ywlx: '', index: '2' },
- { name: '贸易合同异常模型', type: '评价模型', fxgklx: '事后预警', ywlx:'',index:'3' },
- { name: '反洗钱模型', type: '计算模型', fxgklx: '事后预警', ywlx:'',index:'4' },
- ]
- },
- fxgklxOptions: [],
- rowSpanArr: [],
- columns: [
- { type: 'selection', align: 'center', width: '46' },
- { prop: 'index', label:'序号', align: 'center', width: '80' },
- { label: '指标模型名称', align: 'center', slotName: 'name' },
- { label: '类型', align: 'center', prop: 'type' },
- { label: '风险管控类型', align: 'center', slotName: 'fxgklx' },
- { label: '触发数据/业务类型', align: 'center', slotName: 'ywlx' },
- { label: '频率', align: 'center', slotName: 'pl' },
- { label: '适用单位设置', align: 'center', slotName: 'sydwsz' },
- { label: '阈值', align: 'center', slotName: 'yz' },
- { label: '风险等级', align: 'center', slotName: 'fxdj' },
- { label: '风险事件设置', align: 'center', slotName: 'fxsjsz' },
- ],
- sltList: [],//table 复选框 选择集合
- }
- },
- created() {
- // 模拟 处理table数据 收集要合并的数据
- this.handleTableData(this.formTableData.tableData)
- },
- methods: {
- // 保存 和 保存启用
- handleConfirm (type) {
- console.log('formTableData',this.formTableData)
- if (this.handleValidate()) {
- switch (type) {
- case 'saveAndStart':
- break;
-
- default:
- break;
- }
- }
- },
- // 校验所有表单
- handleValidate () {
- let flag = false
- let validateList = ['formTableData','formRef']
- validateList.map(item=>{
- this.$refs[item].validate((valid) => {
- if (valid) {
- flag = true
- } else {
- flag = false
- }
- })
- })
- return flag
- },
- // table 新增
- handleTableAdd (row,index) {
- let tableData = JSON.parse(JSON.stringify(this.formTableData.tableData))
- tableData.splice(index,0,row)
- console.log('tableData----新增---->>>',tableData)
- this.$set(this.formTableData, 'tableData', tableData)
- // 处理table数据 收集要合并的数据
- this.handleTableData(this.formTableData.tableData)
- },
- // table 删除
- handleTableDel (row, index) {
- console.log('table---删除单个--->>>',row, index)
- let tableData = JSON.parse(JSON.stringify(this.formTableData.tableData))
- if (Array.isArray(tableData) && tableData.length && tableData.indexOf(row)) {
- tableData.splice(index, 1);
- let tableDataOther = JSON.parse(JSON.stringify(tableData))
- this.handleSetArray(tableDataOther).map((item, index) => {
- let num = index + 1
- tableData.map(ele => {
- if (item.index == ele.index) {
- ele.index = num
- }
- })
- })
- this.$set(this.formTableData, 'tableData', tableData)
- // 处理table数据 收集要合并的数据
- this.handleTableData(this.formTableData.tableData)
- }
- },
- // 新增 复制 删除
- handleClick (type) {
- // tableData table的数据源
- let tableData = JSON.parse(JSON.stringify(this.formTableData.tableData))
- // 复选之后数组收集
- let sltList = JSON.parse(JSON.stringify(this.sltList))
- if (type == 'add') {
- // 新增
- let num = this.handleSetArray(tableData).length
- let tableDataItem = { name: '', type: '', fxgklx: '', ywlx: '',index:num+1 }
- this.formTableData.tableData.push(tableDataItem)
- } else if(type == 'copy'){
- // 复制
- if (!sltList.length) this.$message.info('请选择数据')
- // this.flag为true则是全选 为false则为不全选,因为点击复制之后 复选框全部清除勾选,所以点击全选之后再点击单选,flag还是为true,则走的还是全选的逻辑,所以得重置为false
- this.flag = false
- // sltListOther 作用是 对比去重之后的数据 给index赋值
- let sltListOther = JSON.parse(JSON.stringify(this.sltList))
- // 收集 去重之后的table的长度,用于复制的序列号的使用
- let num = this.handleSetArray(tableData).length
- // 去重复选框勾选的集合
- sltList = this.handleSetArray(sltList)
- console.log('复制---sltList--->>>', sltList)
- sltList.map(item => {
- num++
- sltListOther.map((ele=>{
- if (item.index == ele.index) {
- ele.index = num
- }
- }))
- })
- console.log('复制---sltListOther--->>>', sltListOther)
- // 合并table和复选框选择的数据 最后赋值给tableData
- let copyArr = this.formTableData.tableData.concat(sltListOther)
- console.log('复制---copyArr--->>>',copyArr)
- this.formTableData.tableData = copyArr
- } else {
- // 删除
- if (sltList.length) {
- sltList.map(item => {
- tableData.map((ele,index) => {
- if (item.index == ele.index) {
- tableData.splice(index, 1);
- }
- })
- })
- console.log('删除---tableData--->>>',tableData)
- let tableDataOther = JSON.parse(JSON.stringify(tableData))
- console.log('删除---tableDataOther--->>>',tableDataOther)
- this.handleSetArray(tableData).map((item, index) => {
- let num = index + 1
- tableDataOther.map(ele => {
- if (item.index == ele.index) {
- ele.index = num
- }
- })
- })
- this.$set(this.formTableData,'tableData',tableDataOther)
- console.log('删除--->>>',this.formTableData.tableData)
- } else {
- this.$message.info('请选择数据')
- }
- }
- // 处理table数据 收集要合并的数据
- this.handleTableData(this.formTableData.tableData)
- this.sltList = []
- },
- // 根据index去重
- handleSetArray (arr = []) {
- if (Array.isArray(arr)) {
- for (let i = 0; i < arr.length; i++) {
- for (let j = i + 1; j < arr.length; j++) {
- if (arr[i].index == arr[j].index) {
- arr.splice(j, 1);
- j--
- }
- }
- }
- return arr
- } else {
- return []
- }
- },
- // @select="handleTableSelection" table的单选事件
- handleTableSelection(val,row){
- // table的数据源
- let tableData = [...this.formTableData.tableData]
- // 点击table复选框 收集 数据源
- let sltList = [...this.sltList]
- // flag为true的时候代表的是全选 为false则代表不全选
- // 全选--勾选or不勾选逻辑
- if(this.flag){
- // isSelect为true代表全选之后点击取消
- // isSelect为false代表全选之后点击取消然后又点勾选
- let isSelect = sltList.length && sltList.indexOf(row) > -1
- // 收集第一次勾选取消之后 收集原来勾选的数据
- let sltListCheck = []
- if(isSelect){
- tableData.forEach(item=>{
- if(item.index != row.index){
- sltListCheck.push(item)
- }
- })
- this.sltList = sltListCheck
- }else{
- // 当再次勾选的时候 在原有的sltList集合 push新的勾选数据
- tableData.forEach(item=>{
- if(item.index == row.index){
- this.sltList.push(item)
- }
- })
- }
- console.log('全选--勾选or不勾选逻辑-->>',this.sltList)
- }else{
- // 不全选--勾选or不勾选逻辑
- let checkList = []
- if (tableData.length && val.length) {
- // tableData为table数据数组
- // val为复选框选择之后的数组
- // 两个数组相互比较 如果index相同 则收集到checkList数组里面
- tableData.forEach(item => {
- val.forEach(ele => {
- if (item.index == ele.index) {
- checkList.push(item)
- }
- })
- })
- }
- this.sltList = checkList
- console.log('不全选--勾选or不勾选--sltList-->>>',this.sltList)
- }
- },
- // @select-all="handleTableSelectionAll" table的全选事件
- handleTableSelectionAll(sltList){
- if (sltList.length) {
- // flag为true的时候代表的是全选 为false则代表不全选
- // sltList 为点击table复选框 收集 数据源
- this.flag = true
- this.sltList = this.formTableData.tableData
- }else{
- this.flag = false
- this.sltList = []
- }
- console.log('handleTableSelectionAll',this.sltList)
- },
-
-
- // 单位选择 确认
- handleConfirmIndex (val) {
- console.log('单位选择 确认', val)
- let tableData = [ ...this.formTableData.tableData ]
- let indexRecordData = this.indexRecordData
- tableData.forEach((item,index) => {
- if (item.index == indexRecordData.index) {
- tableData[index].name = val.name
- }
- })
- this.$set( this.formTableData,'tableData',tableData)
- this.isIndexShow = false
- },
- // 单位选择 取消
- handleCloseUnit () {
- this.isIndexShow = false
- },
- // 设置
- handleSetting (row) {
-
- },
- // 处理table数据 收集要合并的数据
- handleTableData (tableData = []) {
- let rowSpanArr = []
- let position = 0
- if (!!tableData && Array.isArray(tableData)) {
- tableData.map((item, index) => {
- if (index == 0) {
- rowSpanArr.push(1)
- position = 0
- } else {
- if (item.index == tableData[index - 1].index) {
- rowSpanArr[position] += 1
- rowSpanArr.push(0)
- } else {
- rowSpanArr.push(1)
- position = index
- }
- }
- })
- }
-
- this.rowSpanArr = rowSpanArr
- },
- // table合并单元格
- objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
- if (columnIndex != 8 && columnIndex != 9 && columnIndex != 10) {
- let rowspan = this.rowSpanArr[rowIndex]
- return {
- rowspan: rowspan,
- colspan: 1
- };
- }
- },
- // 选择指标模型 并带出数据 和 下标
- // index 下标 indicator带出的数据
- chooseIndicator (index, indicator) {
- this.isIndexShow = true
- this.indexRecordData = indicator
- this.indexNum = index
- },
- // 处理table 星号 变红
- addRedStar(h, { column }) {
- return [
- h("span", { style: "color: red" }, "*"),
- h("span", " " + column.label),
- ];
- },
- },
- }
-
- </script>

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。