Browse Source

阶段性提交

ljb 10 months ago
parent
commit
ef32d69c29

+ 41 - 0
src/api/RDSystemManage/list.js

@@ -0,0 +1,41 @@
+import request from '@/router/axios';
+
+export const getList = (current, size, params) => {
+  return request({
+    url: '/api/kd-scientific/yfzd/detail',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+export const add = (row) => {
+  return request({
+    url: '/api/kd-scientific/yfzd/save',
+    method: 'post',
+    data: row
+  })
+}
+
+
+export const update = (row) => {
+  return request({
+    url: '/api/kd-scientific/yfzd/save',
+    method: 'post',
+    data: row
+  })
+}
+
+
+export const remove = (ids) => {
+  return request({
+    url: '/api/kd-scientific/yfzd/remove',
+    method: 'post',
+    params: {
+      ids,
+    }
+  })
+}

+ 49 - 0
src/api/yfCostManage/basicDataSetting/attenInfo.js

@@ -0,0 +1,49 @@
+import request from '@/router/axios';
+
+export const getList = (current, size, params) => {
+  return request({
+    url: '/api/kd-scientific/technician/page',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+export const add = (row) => {
+  return request({
+    url: '/api/kd-scientific/technician/save',
+    method: 'post',
+    data: row
+  })
+}
+
+
+export const update = (row) => {
+  return request({
+    url: '/api/kd-scientific/technician/update',
+    method: 'post',
+    data: row
+  })
+}
+
+
+export const remove = (data) => {
+  return request({
+    url: '/api/kd-scientific/technician/remove',
+    method: 'post',
+    data
+  })
+}
+
+export const getLastMonthData = params => {
+  return request({
+    url: '/api/kd-scientific/technician/fetchLastMonthData',
+    method: 'get',
+    params: {
+      ...params,
+    }
+  })
+}

+ 49 - 0
src/api/yfCostManage/basicDataSetting/monthSalaryList.js

@@ -0,0 +1,49 @@
+import request from '@/router/axios';
+
+export const getList = (current, size, params) => {
+  return request({
+    url: '/api/kd-scientific/salary/page',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+export const add = (row) => {
+  return request({
+    url: '/api/kd-scientific/salary/save',
+    method: 'post',
+    data: row
+  })
+}
+
+
+export const update = (row) => {
+  return request({
+    url: '/api/kd-scientific/salary/update',
+    method: 'post',
+    data: row
+  })
+}
+
+
+export const remove = (data) => {
+  return request({
+    url: '/api/kd-scientific/salary/remove',
+    method: 'post',
+    data
+  })
+}
+
+export const getLastMonthData = params => {
+  return request({
+    url: '/api/kd-scientific/salary/fetchLastYearData',
+    method: 'get',
+    params: {
+      ...params,
+    }
+  })
+}

+ 4 - 1
src/mixins/crud.js

@@ -55,9 +55,12 @@ export default (app, option = {}) => {
       getList() {
         this.loadData();
       },
+      getSearchParams() {
+        return this.params;
+      },
       loadData() {
         this.loading = true;
-        this.api[option.list || 'getList'](this.page.currentPage, this.page.pageSize, this.params).then(res => {
+        this.api[option.list || 'getList'](this.page.currentPage, this.page.pageSize, this.getSearchParams()).then(res => {
           let data;
           if (option.res) {
             data = option.res(res.data);

+ 108 - 0
src/option/RDSystemManage/list.js

@@ -0,0 +1,108 @@
+const dict = [{
+  name: '有效',
+  code: true
+}, {
+  name: '无效',
+  code: false
+}];
+
+export default {
+  height: 'auto',
+  calcHeight: 30,
+  tip: false,
+  searchShow: true,
+  searchMenuSpan: 6,
+  border: true,
+  index: true,
+  selection: true,
+  searchLabelWidth: 160,
+  labelWidth: 145,
+  menuWidth: 160,
+  dialogClickModal: false,
+  dialogType: "drawer",
+  dialogWidth: 520,
+  addBtnText: "上传制度",
+  column: [
+    {
+      label: '文件类型',
+      prop: 'wjlx',
+      type: 'select',
+      span: 24,
+      search: true,
+      dicUrl: '/api/kd-system/dict-biz/dictionary?code=system_doc_type',
+      editDisabled: true,
+      props: {
+        label: 'dictValue',
+        value: 'dictKey',
+      },
+      rules: [
+        {
+          required: true,
+          message: '请选择文件类型',
+          trigger: 'blur',
+        },
+      ],
+    },
+    {
+      label: '企业制度的文件名称',
+      prop: 'zdwjdz',
+      type: "upload",
+      search: true,
+      multiple: true,
+      span: 24,
+      action: '/api/kd-resource/oss/endpoint/put-file',
+      dataType: "object",
+      propsHttp: {
+        url: "link",
+        name: "originalName",
+        res: "data",
+      },
+      tip: '注:可一次上传多个相关文件(文档、表格、图片等)。支持格式:DOC, PDF, Excel, PNG, JPG, PPT 等。请确保文件内容清晰有效。'
+    },
+    {
+      label: '企业制度实施证明',
+      prop: 'zdsszm',
+      type: "upload",
+      multiple: true,
+      span: 24,
+      action: '/api/kd-resource/oss/endpoint/put-file',
+      dataType: "object",
+      propsHttp: {
+        url: "link",
+        name: "originalName",
+        res: "data",
+      },
+      tip: '注:可一次上传多个相关文件(文档、表格、图片等)。支持格式:DOC, PDF, Excel, PNG, JPG, PPT 等。请确保文件内容清晰有效。'
+    },
+    {
+      label: '制度有效性',
+      prop: 'zdyxx',
+      type: 'select',
+      span: 24,
+      props:{
+        label:'name',
+        value:'code'
+      },
+      dicData: dict,
+      align: 'center',
+      search: true,
+      width: 90,
+      rules: [
+        {
+          required: true,
+          message: '请选择制度有效性',
+          trigger: 'blur',
+        },
+      ],
+    },
+    {
+      label: '制度上传时间',
+      prop: 'createTime',
+      span: 24,
+      display: false,
+      align: 'center',
+      width: 140,
+      search: true,
+    },
+  ],
+};

+ 0 - 1
src/option/techPerson/monthSjcyry.js

@@ -31,7 +31,6 @@ export default {
       span: 24,
       search: true,
       minWidth: 140,
-      align: 'center',
       showOverflowTooltip: true,
     },
     {

+ 88 - 0
src/option/yfCostManage/basicDataSetting/attenInfo.js

@@ -0,0 +1,88 @@
+export default {
+  height: 'auto',
+  calcHeight: 30,
+  tip: false,
+  searchShow: true,
+  searchMenuSpan: 6,
+  border: true,
+  index: true,
+  selection: true,
+  searchLabelWidth: 140,
+  labelWidth: 100,
+  menuWidth: 140,
+  dialogClickModal: false,
+  dialogWidth: 500,
+  dialogType: "drawer",
+  column: [
+    {
+      label: '姓名',
+      prop: 'name',
+      span: 24,
+      search: true,
+      width: 90,
+      cell: true,
+      align: 'center',
+      type: 'select',
+      showOverflowTooltip: true,
+      dicUrl: '',
+      dicFlag: true,
+      dicFormatter:(res)=>{     
+        return res.data.records
+      },
+      dicQuery: {
+        current: 1,
+        size: 99999,
+        yearAndMonth: ''
+      },
+      props: {
+        label: 'name',
+        value: 'id',
+      },
+      rules: [
+        {
+          required: true,
+          message: '请选择技术人员',
+          trigger: 'blur',
+        },
+      ],
+    },
+    {
+      label: '工号',
+      prop: 'number',
+      type: 'input',
+      span: 24,
+      width: 90,
+      align: 'center',
+      search: true,
+      disabled: true,
+      showOverflowTooltip: true,
+    },
+    {
+      label: '身份证号',
+      prop: 'identityCard',
+      type: 'input',
+      span: 24,
+      search: true,
+      disabled: true,
+      width: 150,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '科研人员类别',
+      prop: 'personnelType',
+      type: 'select',
+      span: 24,
+      width: 100,
+      align: 'center',
+      search: true,
+      disabled: true,
+      dicUrl: '/api/kd-system/dict-biz/dictionary?code=renyuanleixing',
+      props: {
+        label: 'dictValue',
+        value: 'dictKey',
+      },
+      showOverflowTooltip: true,
+    },
+  ],
+};

+ 251 - 0
src/option/yfCostManage/basicDataSetting/monthSalaryList.js

@@ -0,0 +1,251 @@
+export default {
+  height: 'auto',
+  calcHeight: 30,
+  tip: false,
+  searchShow: true,
+  searchMenuSpan: 6,
+  border: true,
+  index: true,
+  selection: true,
+  searchLabelWidth: 140,
+  labelWidth: 200,
+  menuWidth: 140,
+  dialogClickModal: false,
+  dialogWidth: 500,
+  dialogType: "drawer",
+  column: [
+    {
+      label: '月份',
+      prop: 'yearAndMonth',
+      type: 'input',
+      span: 24,
+      width: 65,
+      align: 'center',
+      showOverflowTooltip: true,
+      display: false,
+    },
+    {
+      label: '姓名',
+      prop: 'name',
+      span: 24,
+      search: true,
+      width: 75,
+      align: 'center',
+      type: 'select',
+      searchType: 'input',
+      showOverflowTooltip: true,
+      dicFlag: true,
+      editDisabled: true,
+      dicUrl: '',
+      dicFormatter:(res)=>{     
+        return res.data.records
+      },
+      dicQuery: {
+        current: 1,
+        size: 99999,
+        yearAndMonth: ''
+      },
+      props: {
+        label: 'name',
+        value: 'id',
+      },
+      rules: [
+        {
+          required: true,
+          message: '请选择技术人员',
+          trigger: 'blur',
+        },
+      ],
+    },
+    {
+      label: '工号',
+      prop: 'number',
+      type: 'input',
+      span: 24,
+      width: 90,
+      align: 'center',
+      search: true,
+      disabled: true,
+      showOverflowTooltip: true,
+    },
+    {
+      label: '身份证号',
+      prop: 'identityCard',
+      type: 'input',
+      span: 24,
+      search: true,
+      disabled: true,
+      width: 150,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '部门',
+      prop: 'department',
+      type: 'input',
+      span: 24,
+      width: 100,
+      search: true,
+      disabled: true,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '科研人员类别',
+      prop: 'personnelType',
+      type: 'select',
+      span: 24,
+      width: 80,
+      align: 'center',
+      search: true,
+      disabled: true,
+      dicUrl: '/api/kd-system/dict-biz/dictionary?code=renyuanleixing',
+      props: {
+        label: 'dictValue',
+        value: 'dictKey',
+      },
+      showOverflowTooltip: true,
+    },
+    {
+      label: '月均工资(元)',
+      prop: 'averageMonthlySalary',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      width: 80,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '养老保险单位部分(元)',
+      prop: 'pensionInsurance',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 100,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '医疗保险单位部分(元)',
+      prop: 'medicalInsurance',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 100,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '失业保险单位部分(元)',
+      prop: 'unemploymentInsurance',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 100,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '工伤保险单位部分(元)',
+      prop: 'injuryInsurance',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 110,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '生育保险单位部分(元)',
+      prop: 'maternityInsurance',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 100,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '社保单位部分(元)',
+      prop: 'socialInsurance',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 90,
+      align: 'center',
+      addDisplay: false,
+      editDisplay: false,
+      showOverflowTooltip: true,
+    },
+    {
+      label: '公积金单位部分(元)',
+      prop: 'providentFund',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 90,
+      align: 'center',
+      showOverflowTooltip: true,
+    },
+    {
+      label: '奖金(元)',
+      prop: 'total',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 100,
+      align: 'center',
+      addDisplay: false,
+      editDisplay: false,
+      showOverflowTooltip: true,
+    },
+    {
+      label: '补充养老保险(元)',
+      prop: 'total',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 100,
+      align: 'center',
+      addDisplay: false,
+      editDisplay: false,
+      showOverflowTooltip: true,
+    },
+    {
+      label: '补充医疗保险(元)',
+      prop: 'total',
+      type: 'number',
+      min: 0,
+      precision: 2,
+      span: 24,
+      minWidth: 100,
+      align: 'center',
+      addDisplay: false,
+      editDisplay: false,
+      showOverflowTooltip: true,
+    },
+  ],
+
+  showSummary: true,
+  sumColumnList: [
+    {
+      label:'合计',
+      name: 'yearAndMonth',
+    },
+    {
+      name: 'averageMonthlySalary',
+      type: 'sum'
+    },
+  ],
+};

+ 19 - 1
src/styles/element-ui.scss

@@ -89,4 +89,22 @@
 
 .avue-crud__search .el-form-item--mini.el-form-item, .avue-crud__search .el-form-item--small.el-form-item {
   margin-bottom: 9px;
-}
+}
+
+.el-upload__tip {
+  line-height: 16px;
+  color: red;
+}
+
+.avue-crud__search {
+  .avue-form__group .el-col {
+    width: auto !important;
+    margin-right: 8px;
+  }
+  .el-form-item--small .el-form-item__label {
+    display: none;
+  }
+  .el-form-item--small .el-form-item__content {
+    margin-left: 0 !important;
+  }
+}

+ 196 - 0
src/views/RD-system-manage/list.vue

@@ -0,0 +1,196 @@
+<template>
+  <basic-container>
+    <avue-crud
+      v-bind="bindVal"
+      v-on="onEvent"
+      v-model="form"
+      :spanMethod="spanMethod"
+    >
+      <template slot="menuLeft">
+        <el-button
+          type="danger"
+          size="small"
+          icon="el-icon-delete"
+          plain
+          @click="handleDelete"
+        >
+          删 除
+        </el-button>
+        <el-button
+          type="warning"
+          size="small"
+          plain
+          icon="el-icon-download"
+          @click="handleExport"
+        >
+          导出
+        </el-button>
+        <el-button
+          type="primary"
+          size="small"
+          plain
+        >
+          一键下载
+        </el-button>
+        <print-table-btn @click="printTable" />
+        
+        <div style="display: flex; align-items: center;">
+          <year-month-select v-model="params.yearAndMonth" :showMonth="false"></year-month-select>
+        </div>
+      </template>
+
+      <template slot="zdwjdzSearch">
+        <el-input placeholder="请输入制度文件关键字" v-model="params.zdwjmc"></el-input>
+      </template>
+
+      <template slot="createTimeSearch">
+        <el-date-picker
+          v-model="params.createTime"
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+        >
+        </el-date-picker>
+      </template>
+
+      <template slot="zdwjdz" slot-scope="{row}">
+        <div v-for="(item, index) of row.zdwjdz" :key="index">
+          <el-link @click="handleDownFile(item)">{{ item.label }}</el-link>
+        </div>
+      </template>
+
+      <template slot="zdsszm" slot-scope="{row}">
+        <div v-for="(item, index) of row.zdsszm" :key="index">
+          <el-link @click="handleDownFile(item)">{{ item.label }}</el-link>
+        </div>
+      </template>
+      
+    </avue-crud>
+
+    <WideTablePrinter
+      ref="printWideTable"
+      :columns="wideTableColumns"
+      :data="data"
+      :print-title="printTitle"
+      :rows-per-page="30"
+      :default-landscape="true"
+    />
+  </basic-container>
+</template>
+
+<script>
+import {exportBloByPost} from "@/api/common";
+import YearMonthSelect from "@/components/year-month-select";
+import moment from "moment";
+import {getToken} from "@/util/auth";
+import {downloadXls} from "@/util/util";
+
+
+export default window.$crudCommon({
+  components: {
+    YearMonthSelect,
+  },
+  data() {
+    return {
+      params: {
+        yearAndMonth: moment(new Date()).format('YYYY'),
+      },
+
+      wideTableColumns: [],
+      printTitle: "",
+    };
+  },
+  watch: {
+    'params.yearAndMonth'(newVal) {
+      this.page.currentPage = 1;
+      this.getList(this.page);
+    }
+  },
+  methods: {
+    getSearchParams() {
+      let searchParams = { ...this.params };
+      if (!!searchParams.createTime) {
+        searchParams.createTimeStart = searchParams.createTime[0];
+        searchParams.createTimeEnd = searchParams.createTime[1];
+      }
+      console.log(searchParams)
+      return searchParams;
+    },
+    spanMethod({ row, column, rowIndex, columnIndex }) {
+      let fields = ["wjlx"];
+      let cellValue = row[column.property];
+      if (cellValue && fields.includes(column.property)) {
+        let prevRow = this.data[rowIndex - 1];
+        let nextRow = this.data[rowIndex + 1];
+        if (prevRow && prevRow[column.property] === cellValue) {
+          return { rowspan: 0, colspan: 0 };
+        } else {
+          let countRowspan = 1;
+          while (nextRow && nextRow[column.property] === cellValue) {
+            nextRow = this.data[++countRowspan + rowIndex];
+          }
+          if (countRowspan > 1) {
+            row.hbFlag = true;
+            return { rowspan: countRowspan, colspan: 1 };
+          }
+        }
+      }
+    },
+    getFormData() {
+      const params = { ...this.form };
+      let zdwjmc = [];
+      params.zdwjmc.forEach(item => {
+        zdwjmc.push(item.label);
+      });
+      params.zdwjdz = JSON.stringify(params.zdwjmc);
+      params.zdwjmc = zdwjmc.join(',');
+      params.zdsszm = JSON.stringify(params.zdsszm);
+      params.yearAndMonth = this.params.yearAndMonth;
+      return params;
+    },
+    handleExport() {
+      exportBloByPost(`/api/kd-scientific/technician/export?${this.website.tokenHeader}=${getToken()}`, this.params).then(res => {
+        downloadXls(res.data, `研发制度${this.params.yearAndMonth}.xlsx`);
+      });
+    },
+    /**
+     * 打印表格
+     * @param isLandscape 是否横向打印
+     */
+    printTable(isLandscape) {
+      this.wideTableColumns = this.$refs.crud.columnOption;
+      this.printTitle = `研发制度${this.params.yearAndMonth}`;
+      this.$nextTick(() => {
+        this.$refs.printWideTable.printTable(isLandscape);
+      })
+    },
+    handleDownFile(file) {
+      window.open(file.value);
+    }
+  },
+}, {
+  // 模块路径
+  name: 'RDSystemManage/list',
+  res: ({ data }) => {
+    let newList = [];
+    Object.keys(data).forEach(fileType => {
+      if (data[fileType].length) {
+        data[fileType].forEach(item => {
+          newList.push({
+            wjlx: fileType,
+            ...item,
+            zdwjdz: !!item.zdwjdz ? JSON.parse(item.zdwjdz) : [],
+            zdsszm: !!item.zdsszm ? JSON.parse(item.zdsszm) : [],
+          });
+        });
+      } else {
+        newList.push({ wjlx: fileType });
+      }
+    });
+
+    data.records = newList;
+    return data;
+  },
+});
+</script>

+ 147 - 0
src/views/yf-cost-manage/basic-data-setting/atten-info.vue

@@ -0,0 +1,147 @@
+<template>
+  <basic-container>
+    <avue-crud
+      v-bind="bindVal"
+      v-on="onEvent"
+      v-model="form"
+      :page.sync="page"
+      :before-open="handleBeforeOpen"
+      :permission="permissionList"
+      :header-cell-style="headerCellStyle" 
+    >
+      <template slot="menuLeft">
+        <el-button
+          type="warning"
+          size="small"
+          plain
+          icon="el-icon-download"
+          @click="handleExport"
+        >
+          导出
+        </el-button>
+        <print-table-btn @click="printTable" />
+        
+        <div style="display: flex; align-items: center;">
+          <year-month-select v-model="params.yearAndMonth" :showAllYear="false"></year-month-select>
+        </div>
+      </template>
+
+      <!-- 使用工时 -->
+      <template slot="gsTotalSearch">
+        <div style="display: flex; align-items: center;">
+          <avue-input-number v-model="params.gsTotalStart" :min="0"></avue-input-number>
+          <span style="width: 70px; text-align: center;">至</span>
+          <avue-input-number v-model="params.gsTotalEnd" :min="0"></avue-input-number>
+        </div>
+      </template>
+      
+    </avue-crud>
+
+    <WideTablePrinter
+      ref="printWideTable"
+      :columns="wideTableColumns"
+      :data="data"
+      :print-title="printTitle"
+      :rows-per-page="30"
+      :default-landscape="true"
+    />
+  </basic-container>
+</template>
+
+<script>
+import YearMonthSelect from "@/components/year-month-select";
+import UploadExcelDialog from "@/components/upload-excel-dialog";
+import { deepClone, getMonthDatesWithMarkers } from "@/util/util";
+import moment from "moment";
+import ChineseHoliday from "@chnlib/chinese-holiday";
+
+
+export default window.$crudCommon({
+  components: {
+    YearMonthSelect,
+    UploadExcelDialog,
+  },
+  data() {
+    return {
+      params: {
+        yearAndMonth: moment(new Date()).format('YYYYMM'),
+      },
+      defaultColumns: [],
+
+      wideTableColumns: [],
+      printTitle: "",
+    };
+  },
+  watch: {
+    'params.yearAndMonth'(newVal) {
+      this.refreshTableCol(newVal);
+      this.page.currentPage = 1;
+      this.getList(this.page);
+    }
+  },
+  async created() {
+    this.defaultColumns = deepClone(this.option.column);
+    console.log(this.option.column)
+    this.refreshTableCol(this.params.yearAndMonth);
+  },
+  beforeDestroy() {
+    this.option.column = deepClone(this.defaultColumns);
+  },
+  methods: {
+    refreshTableCol(yearAndMonth) {
+      let yearMonth = moment(yearAndMonth).format("YYYY-MM").split("-");
+      const monthDays = getMonthDatesWithMarkers(Number(yearMonth[0]), Number(yearMonth[1]));
+      console.log(monthDays)
+
+      let newColumns = deepClone(this.defaultColumns);
+
+       monthDays.forEach(item => {
+        let col = {
+          label: item.dayName.replace(/周/g, ''),
+          align: 'center',
+          children: [{
+            prop: item.day.toString(),
+            label: item.day,
+            type: 'number',
+            min: 0,
+            width: 40,
+            align: 'center',
+            isWorkDay: ChineseHoliday.isWorkday(item.dateString)
+          }],
+          
+        };
+        if (!ChineseHoliday.isWorkday(item.dateString)) {
+          col.labelClassName = 'red';
+          col.children[0].labelClassName = 'red';
+        }
+        newColumns.push(col);
+      });
+
+      this.option.column = newColumns;
+    },
+    /**
+     * 打印表格
+     * @param isLandscape 是否横向打印
+     */
+    printTable(isLandscape) {
+      this.wideTableColumns = this.$refs.crud.columnOption;
+      this.printTitle = `仪器设备工时记录表${this.params.yearAndMonth}`;
+      this.$nextTick(() => {
+        this.$refs.printWideTable.printTable(isLandscape);
+      })
+    },
+    headerCellStyle ({ column }) {
+      let color = column.labelClassName ? 'red' : 'rgba(0,0,0,.85)';
+      return {
+        color
+      }
+    }
+  },
+}, {
+  // 模块路径
+  name: 'yfCostManage/basicDataSetting/attenInfo',
+  res: ({ data }) => {
+    return data;
+  },
+});
+</script>

+ 0 - 0
src/views/yf-cost-manage/basic-data-setting/lease-records.vue


+ 252 - 0
src/views/yf-cost-manage/basic-data-setting/month-salary-list.vue

@@ -0,0 +1,252 @@
+<template>
+  <basic-container>
+    <avue-crud
+      ref="crud"
+      v-bind="bindVal"
+      v-on="onEvent"
+      v-model="form"
+      :page.sync="page"
+      :before-open="handleBeforeOpen"
+      :permission="permissionList"
+    >
+      <template slot="menuLeft">
+        <el-button
+          type="danger"
+          size="small"
+          icon="el-icon-delete"
+          plain
+          @click="handleDelete"
+        >
+          删除
+        </el-button>
+        <el-button
+          type="success"
+          size="small"
+          plain
+          icon="el-icon-upload2"
+          @click="handleImport"
+        >
+          导入
+        </el-button>
+        <el-button
+          type="warning"
+          size="small"
+          plain
+          icon="el-icon-download"
+          @click="handleExport"
+        >
+          导出
+        </el-button>
+        <el-button
+          type="primary"
+          size="small"
+          plain
+        >
+          引用当月研发人员名单
+        </el-button>
+        <print-table-btn @click="printTable" />
+        <div>
+          <year-month-select v-model="params.yearAndMonth"></year-month-select>
+        </div>
+      </template>
+
+      <!-- <div v-for="key of watchUpdateKey" :slot="key" slot-scope="scope" :key="key">
+        <updated-text v-if="scope.row[key+'Edit'] === 1" :text="scope.row[key]"></updated-text>
+        <span v-else>{{ scope.row[key] }}</span>
+      </div> -->
+      
+    </avue-crud>
+
+    <upload-excel-dialog ref="uploadExcelDialog" :uploadAfter="uploadAfter"/>
+
+
+    <WideTablePrinter
+      ref="printWideTable"
+      :columns="wideTableColumns"
+      :data="data"
+      :print-title="printTitle"
+      :rows-per-page="30"
+      :default-landscape="true"
+    />
+  </basic-container>
+</template>
+
+<script>
+import { getLastMonthData } from "@/api/basicResource/technicianMonthAvgSales";
+import {exportBloByPost} from "@/api/common";
+import YearMonthSelect from "@/components/year-month-select";
+import UpdatedText from "@/components/updated-text";
+import UploadExcelDialog from "@/components/upload-excel-dialog";
+import moment from "moment";
+import {getToken} from "@/util/auth";
+import {downloadXls} from "@/util/util";
+import Decimal from "decimal.js";
+import PrintTableBtn from "@/components/print-table-btn";
+import WideTablePrinter from '@/components/print-wide-table'
+
+export default window.$crudCommon({
+  components: {
+    YearMonthSelect,
+    UpdatedText,
+    UploadExcelDialog,
+    WideTablePrinter,
+    PrintTableBtn
+  },
+  data() {
+    return {
+      params: {
+        yearAndMonth: moment(new Date()).format('yyyyMM'),
+      },
+
+      operateType: '',
+      watchUpdateKey: ["averageMonthlySalary", "pensionInsurance", "medicalInsurance", "unemploymentInsurance", "injuryInsurance", "maternityInsurance", "providentFund"],
+      beforeUpdatedData: {},
+      updatedFormData: {},
+
+      wideTableColumns: [],
+      printTitle: "",
+    };
+  },
+  watch: {
+    'params.yearAndMonth'(newVal) {
+      this.page.currentPage = 1;
+      this.getList(this.page);
+    }
+  },
+  created() {
+    let newOption = { ...this.option };
+    // 姓名下拉框,设置监听事件
+    newOption.column.forEach(item => {
+      if (item.prop == "name") {
+        item.change = ({ item }) => {
+          if (!!item) {
+            this.form = {
+              ...this.form,
+              name: item.name,
+              number: item.number,
+              identityCard: item.identityCard,
+              department: item.department,
+              personnelType: item.personnelType,
+            };
+          }
+        }
+      }
+    });
+    this.option = { ...newOption };
+  },
+  methods: {
+    handleBeforeOpen(done, type) {
+      this.operateType = type;
+      this.beforeUpdatedData = { ...this.form };
+      this.option.column.forEach(item => {
+        if (item.prop == "name") {
+          item.dicUrl = '/api/kd-scientific/technician/page';
+          item.dicQuery.yearAndMonth = this.params.yearAndMonth;
+        }
+      });
+      done();
+    },
+    getFormData() {
+      if (this.operateType === 'edit') {
+        return this.updatedFormData
+      }
+      return this.form;
+    },
+    updateBefore(loading, callback) {
+      let updatedData = {};
+      this.watchUpdateKey.forEach(key => {
+        if (Number(this.form[key]) != Number(this.beforeUpdatedData[key])) {
+          updatedData[key] = this.form[key];
+        }
+      });
+      this.updatedFormData = {
+        technicianId: this.form.technicianId,
+        yearAndMonth: this.params.yearAndMonth,
+        ...updatedData
+      };
+      callback && callback();
+    },
+    getDelParams(row) {
+      return [{ yearAndMonth: this.params.yearAndMonth, technicianId: row.technicianId }]
+    },
+    getBatchDelParams() {
+      let delArr = [];
+      this.data.forEach(item => {
+        if (this.ids.indexOf(item.id) > -1) {
+          delArr.push({ yearAndMonth: this.params.yearAndMonth, technicianId: item.technicianId });
+        }
+      });
+      return delArr;
+    },
+    handleImport() {
+      let excelParams = { yearAndMonth: this.params.yearAndMonth };
+      this.$refs.uploadExcelDialog.open('/api/kd-scientific/salary/import', excelParams);
+    },
+    uploadAfter() {
+      this.page.currentPage = 1;
+      this.getList(this.page);
+    },
+    handleExport() {
+      exportBloByPost(`/api/kd-scientific/salary/export-salary?${this.website.tokenHeader}=${getToken()}`, this.params).then(res => {
+        downloadXls(res.data, `技术人员${this.params.yearAndMonth}年度平均工资.xlsx`);
+      });
+    },
+    handleReadyLastMonData() {
+      this.$confirm("确认读取上年度工资明细吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        getLastMonthData({ yearAndMonth: this.params.yearAndMonth}).then(res => {
+          let data = res.data;
+          if (data.success) {
+            this.$message.success('读取成功!');
+            this.page.currentPage = 1;
+            this.getList(this.page);
+          }
+        });
+      });
+    },
+    printTable(isLandscape) {
+      this.wideTableColumns = this.$refs.crud.columnOption;
+      this.printTitle = `技术人员${this.params.yearAndMonth}年度平均工资`;
+      this.$nextTick(() => {
+        this.$refs.printWideTable.printTable(isLandscape);
+      });
+    },
+  },
+}, {
+  // 模块路径
+  name: 'yfCostManage/basicDataSetting/monthSalaryList',
+  res: ({ data }) => {
+    data.records = data.records.map(item => {
+      // 处理id为空的时候,批量清除数据无法获取数据的问题
+      item.id = !item.id ? (item.number || item.identityCard) : item.id;
+      item.averageMonthlySalary = Number(item.averageMonthlySalary || 0).toFixed(2);
+      item.pensionInsurance =  Number(item.pensionInsurance || 0).toFixed(2);
+      item.medicalInsurance =  Number(item.medicalInsurance || 0).toFixed(2);
+      item.unemploymentInsurance =  Number(item.unemploymentInsurance || 0).toFixed(2);
+      item.injuryInsurance =  Number(item.injuryInsurance || 0).toFixed(2);
+      item.maternityInsurance = Number(item.maternityInsurance || 0).toFixed(2);
+      item.providentFund =  Number(item.providentFund || 0).toFixed(2);
+
+      let pensionInsurance = new Decimal(item.pensionInsurance);
+      let medicalInsurance = new Decimal(item.medicalInsurance);
+      let unemploymentInsurance = new Decimal(item.unemploymentInsurance);
+      let injuryInsurance = new Decimal(item.injuryInsurance);
+      let maternityInsurance = new Decimal(item.maternityInsurance);
+      let providentFund = new Decimal(item.providentFund);
+
+      // 社保合计
+      let socialInsurance = pensionInsurance.add(medicalInsurance).add(unemploymentInsurance).add(injuryInsurance).add(maternityInsurance);
+      // 总计
+      let total = socialInsurance.add(providentFund);
+
+      item.socialInsurance = socialInsurance.toFixed(2);
+      item.total = total.toFixed(2);
+      return item;
+    });
+    return data;
+  },
+});
+</script>

+ 0 - 0
src/views/yf-cost-manage/basic-data-setting/picking-detail.vue


+ 147 - 0
src/views/yf-cost-manage/basic-data-setting/working-hours-records.vue

@@ -0,0 +1,147 @@
+<template>
+  <basic-container>
+    <avue-crud
+      v-bind="bindVal"
+      v-on="onEvent"
+      v-model="form"
+      :page.sync="page"
+      :before-open="handleBeforeOpen"
+      :permission="permissionList"
+      :header-cell-style="headerCellStyle" 
+    >
+      <template slot="menuLeft">
+        <el-button
+          type="warning"
+          size="small"
+          plain
+          icon="el-icon-download"
+          @click="handleExport"
+        >
+          导出
+        </el-button>
+        <print-table-btn @click="printTable" />
+        
+        <div style="display: flex; align-items: center;">
+          <year-month-select v-model="params.yearAndMonth" :showAllYear="false"></year-month-select>
+        </div>
+      </template>
+
+      <!-- 使用工时 -->
+      <template slot="gsTotalSearch">
+        <div style="display: flex; align-items: center;">
+          <avue-input-number v-model="params.gsTotalStart" :min="0"></avue-input-number>
+          <span style="width: 70px; text-align: center;">至</span>
+          <avue-input-number v-model="params.gsTotalEnd" :min="0"></avue-input-number>
+        </div>
+      </template>
+      
+    </avue-crud>
+
+    <WideTablePrinter
+      ref="printWideTable"
+      :columns="wideTableColumns"
+      :data="data"
+      :print-title="printTitle"
+      :rows-per-page="30"
+      :default-landscape="true"
+    />
+  </basic-container>
+</template>
+
+<script>
+import YearMonthSelect from "@/components/year-month-select";
+import UploadExcelDialog from "@/components/upload-excel-dialog";
+import { deepClone, getMonthDatesWithMarkers } from "@/util/util";
+import moment from "moment";
+import ChineseHoliday from "@chnlib/chinese-holiday";
+
+
+export default window.$crudCommon({
+  components: {
+    YearMonthSelect,
+    UploadExcelDialog,
+  },
+  data() {
+    return {
+      params: {
+        yearAndMonth: moment(new Date()).format('YYYYMM'),
+      },
+      defaultColumns: [],
+
+      wideTableColumns: [],
+      printTitle: "",
+    };
+  },
+  watch: {
+    'params.yearAndMonth'(newVal) {
+      this.refreshTableCol(newVal);
+      this.page.currentPage = 1;
+      this.getList(this.page);
+    }
+  },
+  async created() {
+    this.defaultColumns = deepClone(this.option.column);
+    console.log(this.option.column)
+    this.refreshTableCol(this.params.yearAndMonth);
+  },
+  beforeDestroy() {
+    this.option.column = deepClone(this.defaultColumns);
+  },
+  methods: {
+    refreshTableCol(yearAndMonth) {
+      let yearMonth = moment(yearAndMonth).format("YYYY-MM").split("-");
+      const monthDays = getMonthDatesWithMarkers(Number(yearMonth[0]), Number(yearMonth[1]));
+      console.log(monthDays)
+
+      let newColumns = deepClone(this.defaultColumns);
+
+       monthDays.forEach(item => {
+        let col = {
+          label: item.dayName.replace(/周/g, ''),
+          align: 'center',
+          children: [{
+            prop: item.day.toString(),
+            label: item.day,
+            type: 'number',
+            min: 0,
+            width: 40,
+            align: 'center',
+            isWorkDay: ChineseHoliday.isWorkday(item.dateString)
+          }],
+          
+        };
+        if (!ChineseHoliday.isWorkday(item.dateString)) {
+          col.labelClassName = 'red';
+          col.children[0].labelClassName = 'red';
+        }
+        newColumns.push(col);
+      });
+
+      this.option.column = newColumns;
+    },
+    /**
+     * 打印表格
+     * @param isLandscape 是否横向打印
+     */
+    printTable(isLandscape) {
+      this.wideTableColumns = this.$refs.crud.columnOption;
+      this.printTitle = `仪器设备工时记录表${this.params.yearAndMonth}`;
+      this.$nextTick(() => {
+        this.$refs.printWideTable.printTable(isLandscape);
+      })
+    },
+    headerCellStyle ({ column }) {
+      let color = column.labelClassName ? 'red' : 'rgba(0,0,0,.85)';
+      return {
+        color
+      }
+    }
+  },
+}, {
+  // 模块路径
+  name: 'yfCostManage/basicDataSetting/attenInfo',
+  res: ({ data }) => {
+    return data;
+  },
+});
+</script>