前端学习笔记(二)

前端学习笔记(二)

1.解决数据字典带出问题

当前效果:当前办公地点都为数据字典英文
需求效果
在这里插入图片描述

index.vue(原生代码,未使用公共组件)
<template>
  <el-table-column
    label="办公地点"
    :show-overflow-tooltip="true"
    // formatter调用方法
    :formatter="dictFormat"
    prop="place"
    align="center"
    min-width="100"
  ></el-table-column>
</template>

<script>
// 引入数据字典js方法
import SysDict from '@/api/business/sys/sysDict.js';

export default {
  data() {
    return {
      // 初始化变量
      dict: {},
      dictVal: 'place'
    }
  },
  created() {
    // 调方法
    this.getDict(this.dictVal);
  },
  methods: {
    // 获取表格中需要使用的数据字典
    async getDict(val) {
      let catCodes = [val];
      // 等待数据字典加载完毕 调用引入的SysDict里的方法
      let res = await SysDict.mapDictByCatCodes(catCodes);
      if (res.success === true) {
        this.dict = res.data;
      }
    },
    dictFormat(cellValue) {
      if (cellValue.place == this.dict[this.dictVal][cellValue.place].dictCode) {
        return this.dict[this.dictVal][cellValue.place].dictName;
      } else {
        return '';
      }
    }
  }
}
</script>

2.解决element-ui输入框按回车刷新页面和不搜索问题

// 页面有两个组件都有搜索功能  @submit.native.prevent关闭刷新
<el-form class="sBar" :inline="true" size="mini" @submit.native.prevent>
  <el-form-item>
    // @keyup.enter.native="getUserData"  element-ui使用的按下回车调用方法
    <el-input v-model="req.search" placeholder="姓名或工号" @keyup.enter.native="getUserData"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button class="line" @click="getUserData">查询</el-button>
  </el-form-item>
</el-form>

3.前后端交互查询数据显示在列表中

需求效果
三层组件显示

(1)后端方法

service层:PrjTrackService.java

@Service
public class PrjTrackService extends ServiceImpl<PrjTrackMapper, PrjTrack> {
	public List<PrjTrack> getAllTrackList(String cstmPrjCode){
        return this.baseMapper.selectList(new QueryWrapper<PrjTrack>().lambda().eq(PrjTrack::getCstmPrjCode, cstmPrjCode));
    }
}

controller层:PrjTrackController.java

@Api(value = "PrjTrackController", tags = {"PrjTrack接口"})
@RequestMapping("/PrjTrack")
@RestController
public class PrjTrackController extends BaseController {
    private static final Logger LOG = LoggerFactory.getLogger(PrjTrackController.class);
    @Autowired
    private PrjTrackService prjTrackService;

	@ApiOperation("根据项目编号或客户编号查询某项目所有的数据")
    @GetMapping(value = "/listAllTrack")
    public ResponseData<Object> getAllTrackList(String cstmPrjCode){
        return  ResponseData.success(prjTrackService.getAllTrackList(cstmPrjCode));
    }
}
2.前端页面

track.js

import http from '@/utils/serviceHttp';

export default {
  //获取跟踪数据
  getAllTrack: cstmPrjCode => {
    http.sales.get('/PrjTrack/listTrack', { cstmPrjCode: cstmPrjCode });
  }
};
组件排序: 爷组件(A层)–父组件(B层)–子组件(C层)

(1)A层:index.vue

<template>
  <div class="layout vflex" v-loading="loading" v-keydown:search="'enter'">
    <el-row :gutter="20" class="shrink1 end">
      <el-col :span="24" style="height: 100%;">
        <el-card class="vflex h4">
          <div class="clearfix h3" slot="header">
            <span class="co-rect">{{ alias }}</span>
          </div>
          <im-table
            class="getHeight vflex singlePage"
            ref="im_table"
            api="/im-gateway/im-project/PrjCustomer/sale/search"
            http_method="get"
            :table_header="tableHeader"
            :show_operate="true"
            @cell-click="cell_click"
          >
            <template v-slot:operate="{ row }">
              // 点击查看编辑调用show方法显示组件
              <el-link type="primary" @click.stop="show(row)">查看</el-link>
              <template v-if="btnShow">
                <el-link type="primary" @click.stop="edit(row)">编辑</el-link>
                <el-link type="primary" @click.stop="track(row, 'edit')">客户跟进</el-link>
              </template>
              <template v-if="!btnShow">
                <el-link type="primary" @click.stop="track(row, 'show')">客户跟进</el-link>
              </template>
            </template>
          </im-table>
        </el-card>
      </el-col>
    </el-row>
    
    // is_show_addDialog默认为false 不显示
    <el-dialog
      :visible.sync="is_show_addDialog"
      :title="dialogTitle"
      width="70%"
      class="send-dialog"
      v-dialogDrag
      :before-close="close"
      :close-on-click-modal="false"
      custom-class="min-form-dialog fit "
    >
      // 4.传参给子组件(B层),  :[子组件中的props中接收] = "[父组件要传入子组件的参数或属性]"
      <cust-popup
        v-if="is_show_addDialog"
        // ☆☆☆
        :form_param="popupParam"
      />
    </el-dialog>
  </div>
</template>

<script>
import IMTable from '@/components/imTable/imTable.vue';
// 1.引入子组件
import CustPopup from './components/cust-popup.vue';

export default{
  name: 'my-client',
  components: {
    'im-table': IMTable,
    // 2.在此处将组件重命名,自定义组件,即可以使用<cust-popup />
    'cust-popup': CustPopup
  },
  data() {
    return {
      // 3.初始化要用的变量
      is_show_addDialog: false,
      popupParam: {},
      customerCode: ''
    }
  },
  method() {
    // 点击调用查看方法
    show(param) {
      this.popupParam = param;  // param为点击查看获取到的整行数据,将param赋值给popupParam传给B层
      this.is_show_addDialog = true; // 显示表单dialog
    }
  }
}
</script>
(2)B层:cust-popup.vue 管理3个小组件在一个表单中显示

效果:联系人、项目、时间线,拆分为3个子组件
在这里插入图片描述

<template>
  <div class="layout vflex" v-loading="loading">
    <cust-form v-model="formData.main" :edit_type="edit_type" :edit_param="edit_param" @close="close" @refresh_main="getMainData" />
    <fieldset>
      <legend>联系人</legend>
      <contacts v-model="formData.contacts" :edit_type="edit_type" :edit_param="edit_param" @close="close" />
    </fieldset>
    <fieldset>
      <legend>项目</legend>
      <project ref="proj" v-model="formData.project" :edit_type="edit_type" :edit_param="edit_param" @close="close" />
    </fieldset>

    // 以上仅为演示效果
    <fieldset>
      <legend>时间线</legend>
      // ※※※ 4.将参数传给C层: 从A层接收来的,在props中定义的form_param传给C层,C层以edit_param接收
      <form-track v-model="formData.track" :edit_param="form_param" ref="track_table" @close="close" />
    </fieldset>
    
    <div class="footbutton">
      <el-button @click="close" class="line">取消</el-button>
      <el-button v-if="edit_type !== 'info'" @click="submit" type="primary">提交</el-button>
    </div>
  </div>
</template>

<script>
// 1.引入组件依赖
import Track from './cust-form-track.vue';

export default {
  name: 'cust-popup',
  components: {
    // 2.命名组件 <form-track />
    'form-track': Track
  },
  props: {
    // 3.从A层☆☆☆处传入的数据,在props中接收,form_param是一行数据的集合,包含多种属性值
    form_param: {
      type: Object,
      required: false,
      default: () => {}
    }
  },
  data() {
    return {
      // 初始化值
      loading: false,
      formData: {
        track: []
      }
    }
  }
}
(3)C层:cust-form-track.vue,表单具体内容,获取表单data都是在此层显示
<template>
  <div class="layout vflex">
    <im-table
      style="height: 260px;"
      // $$$地址
      ref="im_table_track"
      // 定位到上面controller层的listAllTrack方法
      api="/im-gateway/im-sales/PrjTrack/listAllTrack"
      // get请求
      http_method="get"
      // 表头数据
      :table_header="tableHeader"
    ></im-table>
  </div>
</template>

<script>
// 1.引入im-table组件
import IMTable from '@/components/imTable/imTable.vue';

export default {
  name: 'cust-form-track',
  components: {
    // 2.定义组件,可以<im-table />形式使用
    'im-table': IMTable
  },
  props: {
    // 3.从B层中的※※※处传入的参数,在此接收并可以用this调用参数的属性
    edit_param: {
      type: Object,
      required: false,
      default: () => {}
    }
  },
  data() {
    return {
    // 初始化值
      /** 客户跟进数据 */
      trackReport: [],
      /** 客户跟进表头 */
      tableHeader: []
    };
  },
  created() {
    this.initData();
  },
  mounted() {
    // 点击查看时调用该方法
    this.getTrackReport();
  },
  methods: {
    initData() {
      // 表头数据
      this.tableHeader = [
        {
          prop: 'customerName',
          label: '客户名称',
          width: 150,
          show: true
        },
        {
          prop: 'visitMode',
          label: '拜访方式',
          width: 150,
          show: true
        },
        {
          prop: 'visitors',
          label: '拜访对象',
          width: 150,
          show: true
        },
        {
          prop: 'visitTime',
          label: '拜访时间',
          width: 150,
          show: true
        },
        {
          prop: 'visitContents',
          label: '拜访内容',
          width: 'auto',
          show: true
        },
        {
          prop: 'rmk',
          label: '备注',
          width: 150,
          show: true
        }
      ];
    },

// ☆ 重点,通过传入的cstmPrjCode(此处是customer编码)来筛选数据
    /** 获取项目跟进 */
    getTrackReport() {
      // 筛选条件 = this.传来的参数.customerCode属性
      this.cstmPrjCode = this.edit_param.customerCode;
      // $refs后对应im-table组件中的$$$处地址
      // this.$refs.地址.getData方法({ 右边的this.cstmPrjCode赋值给左边的cstmPrjCode,使用这个cstmPrjCode进行筛选 })
      this.$refs.im_table_track.getData({ cstmPrjCode: this.cstmPrjCode }, data => {
        // ※数据库中没有存customerName属性,但是传来的edit_param参数是有这条属性值的,所以使用forEach循环给data循环添加customerName属性值,此处属性值对应表头中的客户名称prop
        data.forEach(x => (x.customerName = this.edit_param.customerName));
        //(x.表客户名称 = this.传入的参数.客户名称属性)
      });
    }
  }
};
</script>

4.导出表数据为excel案例

public  void exportModelRunStatistics(String startTime,String endTime,String unitName) throws UnsupportedEncodingException{
		List<ModelRunStatistics> result = modelRunStatisticsService.queryExportedModelRunStatistics(startTime,endTime,unitName);
		String[] columnNames = new String[]{"模型名称","统计年月","单位","专业","运行次数"};
		String fileName="模型监控运行.xls";
		if (result==null) {
			result = new ArrayList<ModelRunStatistics>();
		}
		//可通过通用方法实现,但由于已经写好,而且select * 所以自定义导出。
		exportExcel(fileName,columnNames,result);
	}
	
	
	private void exportExcel(String fileName,String[] columnNames,List<ModelRunStatistics> list) throws UnsupportedEncodingException{
	        fileName= URLEncoder.encode(fileName, "UTF-8");
	        response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
	        // 定义一个新的工作簿
	        HSSFWorkbook wb = new HSSFWorkbook();
	        // 创建一个Sheet页
	        HSSFSheet sheet = wb.createSheet("products");
	        sheet.setDefaultRowHeight((short) (2 * 256));//设置行高
	        sheet.setColumnWidth(0, 4000);//设置列宽
	        sheet.setColumnWidth(1,4000);
	        sheet.setColumnWidth(2,4000);
	        sheet.setColumnWidth(3,4000);
	        sheet.setColumnWidth(11,4000);
	        sheet.setColumnWidth(12,4000);
	        sheet.setColumnWidth(13,4000);
	        HSSFFont font = wb.createFont();
	        font.setFontName("宋体");
	        font.setFontHeightInPoints((short) 16);
			//获得表格第一行
	        HSSFRow row = sheet.createRow(0);
	        HSSFCell cell;
			//根据需要给第一行每一列设置标题
	        for (int i = 0; i < columnNames.length; i++) {
	        	cell = row.createCell(i);
	        	cell.setCellValue(columnNames[i]);
			}
	        HSSFRow rows;
	        HSSFCell cells;
			//循环后台拿到的数据给所有行每一列设置对应的值
	        for (int i=0;i<list.size();i++){
	            // 在这个sheet页里创建一行
	            rows = sheet.createRow(i+1);
	            // 该行创建一个单元格,在该单元格里设置值
	            cells = rows.createCell(0);
	            cells.setCellValue(list.get(i).getModelName());
	            cells = rows.createCell(1);
	            cells.setCellValue(list.get(i).getStatisticsDate());
	            cells = rows.createCell(2);
	            cells.setCellValue(list.get(i).getUnitName());
	            cells = rows.createCell(3);
	            cells.setCellValue(list.get(i).getTypeName());
	            cells = rows.createCell(4);
	            cells.setCellValue(String.valueOf( list.get(i).getRunNum()));
	        }
	        OutputStream out=null;
	        try {
	        	out = response.getOutputStream();
	        	//response.getWriter();
	        	wb.write(out);
	        }catch (IOException e){
	            e.printStackTrace();
	        }finally {
	            try {
	                out.close();
	                wb.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	}

5.在日期区间选择器限制中添加自调用方法

<template>
  <el-col :span="10">
    <el-form-item label="开始时间:" size="medium">
      <el-date-picker
        v-model="startDate"
        format="yyyy-MM"
        type="month"
        placeholder="选择月份"
        :picker-options="firstPickerOption"
      >
       </el-date-picker>
    </el-form-item>
  </el-col>
</template

<script>
import { addYear } from "@/plugins/common/dateUtils.js";

export default {
  name: "manual-access",
  data() {
    return {
      startDate: "",
      beforeDate: "",

      // 只可以选本月之前的 自调用,将this的作用域改为可以调用外部变量
      firstPickerOption: {
        disabledDate:(function(_this){
          return function(time){
            return (time.getTime() < _this.beforeDate) || (time.getTime() > Date.now());
          };
        })(this)
      },
    };
  },
  created() {
    this.beforeDate = addYear(new Date(), -1);
  },
};
</script>


// 从api中引入的addYear()方法
//日期添加年份
export function addYear(curDate,years){
    var date = new Date(curDate);
    date.setFullYear(date.getFullYear() + years);
    if (date.getMonth() < curDate.getMonth()) 
        date.setDate(0);
    return date;
}

6.子组件调用父组件中的方法

1.父组件页面,调用子组件dialog
<el-dialog
  :visible.sync="is_show_accessDialog"
  :title="dialogTitle"
>
  // ☆ @传给子组件 = '方法名'
  <manual-access @closeAccess='closeManual' v-if="is_show_accessDialog" />
</el-dialog>

<script>
export default {
    name: 'model_function',
    data () {
      return {}
    },
    components: {
    	// 引入子组件
        'manual-access': ManualAccess
    },
    methods: {
    	// 关闭子组件
        closeManual() {
            this.is_show_accessDialog = false;
        }
    }
</script>
2.子组件页面
<el-button class="mybtn" size="medium" @click="cancel">取消</el-button>

<script>
name: "manual-access",
  components: {},
  data() {
    return {}
  },

  methods: {
  // 关闭组件
    cancel() {
    	// 通过$emit调用父组件中的方法,方法名与☆中@ 后的方法名对应
        this.$emit("closeAccess");
    }
  },
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值