Ver Fonte

2022-9-14

codeMan há 2 anos atrás
pai
commit
1fecc6516a
26 ficheiros alterados com 2712 adições e 5 exclusões
  1. 60 0
      src/SManagement/personal_target/components/selectPanel.vue
  2. 115 0
      src/SManagement/personal_target/index.vue
  3. 94 0
      src/SManagement/personal_target/modules/detail.vue
  4. 244 0
      src/SManagement/project_target/components/addProject.vue
  5. 28 0
      src/SManagement/project_target/components/delete.vue
  6. 84 0
      src/SManagement/project_target/components/editBtn.vue
  7. 60 0
      src/SManagement/project_target/components/selectPanel.vue
  8. 506 0
      src/SManagement/project_target/components/table.vue
  9. 53 0
      src/SManagement/project_target/index.vue
  10. 121 0
      src/SManagement/project_target/modules/detailInfo.vue
  11. 132 0
      src/SManagement/project_target/modules/editInfo.vue
  12. 160 0
      src/SManagement/sales_forecast/components/addProduct.vue
  13. 95 0
      src/SManagement/sales_forecast/components/addProject.vue
  14. 32 0
      src/SManagement/sales_forecast/components/delete.vue
  15. 114 0
      src/SManagement/sales_forecast/components/edit.vue
  16. 86 0
      src/SManagement/sales_forecast/components/mergeTable.vue
  17. 210 0
      src/SManagement/sales_forecast/index.vue
  18. 180 0
      src/SManagement/sales_forecast/modules/editSales.vue
  19. 95 0
      src/SManagement/sales_forecast/modules/productDetail.vue
  20. 96 0
      src/SManagement/sales_forecast/modules/projectDetail.vue
  21. 4 1
      src/SManagement/submitedit_one/components/TimeSelect.vue
  22. BIN
      src/assets/sales.png
  23. 49 0
      src/components/down_select/index.vue
  24. 2 2
      src/components/table/index.vue
  25. 90 0
      src/router/SManagement.js
  26. 2 2
      src/store/index.js

+ 60 - 0
src/SManagement/personal_target/components/selectPanel.vue

@@ -0,0 +1,60 @@
+<template>
+  <div class="select">
+    <div class="year">
+      <span>年度:</span>
+      <el-date-picker v-model="year" type="date" size="small" placeholder="选择年度" />
+    </div>
+    <Search />
+    <div class="target">
+      <span>考核指标:</span>
+      <el-select v-model="target" placeholder="请选择" size="small">
+        <el-option
+          v-for="item in options"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value">
+        </el-option>
+      </el-select>
+    </div>
+  </div>
+</template>
+
+<script>
+import Search from '@/components/search/index'
+export default {
+  name: '',
+  data() {
+    return {
+      year:'',
+      target:'',
+      options:[
+        {label:'开票指标',value:'1'},
+        {label:'订单金额',value:'2'},
+        {label:'出货金额',value:'3'},
+      ]
+    };
+  },
+  components: { Search, },
+  computed:{
+  },
+  watch:{
+  },
+  methods: {},
+};
+</script>
+
+<style scoped>
+  .select {
+    font-size: 14px;
+    display: flex;
+    align-items: center;
+  }
+  .select .year,.target {
+    display: flex;
+    align-items: center;
+    margin-right: 16px;
+  }
+  .select span,.target span {
+    margin-right: 8px;
+  }
+</style>

+ 115 - 0
src/SManagement/personal_target/index.vue

@@ -0,0 +1,115 @@
+<template>
+  <div class="personal-target">
+    <Header>
+      <el-button size="small" @click="export1">导出</el-button>
+    </Header>
+    <div class="container normal-panel">
+      <select-panel />
+    </div>
+    <tableLayout :layout="tablecols" :custom="true" :data="list">
+      <template v-slot:customcol="scope">
+          <div v-if="scope.column.columnname == 'baseTarget'" class="base-target">
+            <input type="text" @input="baseTargetChange($event,scope.column.data)">
+          </div>
+          <div v-if="scope.column.columnname == 'doubleTarget'" class="base-target">
+            <input type="text" @input="dealTargetChange($event,scope.column.data)">
+          </div>
+          <div v-if="scope.column.columnname == 'dealTime'">
+            <el-date-picker
+              type="date"
+              placeholder="选择日期"
+              size="small"
+              :ref="scope.column.data.projectnum"
+              @input="timeChange($refs[scope.column.data.projectnum],$event,scope.column.data)">
+            </el-date-picker>
+          </div>
+          <div v-if="scope.column.columnname == 'projectnum' || scope.column.columnname == 'projectname'">{{scope.column.data[scope.column.columnname]}}</div>
+      </template>
+    </tableLayout>
+  </div>
+</template>
+
+<script>
+import Header from '@/SManagement/archives_upload/components/Header';
+import selectPanel from './components/selectPanel'
+export default {
+  name: '',
+  data() {
+    return {
+      tablecols:'',
+      list:'',
+      reslut:''
+    };
+  },
+  components: { Header, selectPanel },
+  computed:{
+  },
+  watch:{
+  },
+  created() {
+    this.getTargetList()
+    this.tablecols = this.tool.tabelCol(this.$route.name).addProjectTargetTable.tablecols;
+  },
+  methods: {
+    async getTargetList() {
+      let res = await this.$api.requested({
+          "id": 20220905151902,
+          "content": {
+              "where": {
+                  "condition": "" 
+              }
+          },
+      })
+      this.list = res.data
+      console.log(this.list);
+    },
+    /* 基本目标更改 */
+    baseTargetChange(val,data) {
+      data.baseTarget = val.target.value
+    },
+    /* 挑战目标更改 */
+    dealTargetChange(val,data) {
+      data.doubleTarget = val.target.value
+    },
+    /* 预计时间 */
+    timeChange(el,val,data) {
+      let date = new Date(val)
+      let y = date.getFullYear()
+      let m = date.getMonth() + 1
+      m = m < 10 ? ('0' + m) : m
+      let d = date.getDate()
+      d = d < 10 ? ('0' + d) : d
+      const time =  y + '-' + m + '-' + d;
+      el.$el.querySelector('input').value = time
+
+      data.dealTime = time
+    },
+    export1() {
+            
+    }
+  },
+};
+</script>
+
+<style scoped>
+*{
+  box-sizing: border-box;
+}
+  .base-target {
+    width: 100%;
+    padding: 0 15px;
+    border: 1px solid #c0c4cc;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: normal;
+    word-break: break-all;
+    border-radius: 5px;
+    background: #ffffff;
+  }
+  .base-target input {
+    border: 0 none;
+    outline: none;
+    height: 32px;
+    width: 100%;
+  }
+</style>

+ 94 - 0
src/SManagement/personal_target/modules/detail.vue

@@ -0,0 +1,94 @@
+<template>
+  <div class="edit">
+    <Header>
+      <el-button type="warning" size="small">保存</el-button>
+    </Header>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">基础信息</p>
+      <el-descriptions :column="4">
+          <el-descriptions-item label="年度">{{detail.year}}</el-descriptions-item>
+          <el-descriptions-item label="部门">{{detail.depname}}</el-descriptions-item>
+          <el-descriptions-item label="人员姓名">{{detail.name}}</el-descriptions-item>
+          <el-descriptions-item label="职位">{{detail.position}}</el-descriptions-item>
+          <el-descriptions-item label="营销区域">{{detail.areaname}}</el-descriptions-item>
+          <el-descriptions-item label="状态">
+            <span :style="{color:detail.status=='下达' ? '#9BC464' : '#000000'}">{{detail.status}}</span>
+          </el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">基本信息</p>
+        <el-descriptions :column="4">
+          <el-descriptions-item label="创建人">{{detail.createby}}</el-descriptions-item>
+          <el-descriptions-item label="创建时间">{{detail.createdate}}</el-descriptions-item>
+          <el-descriptions-item label="最近调整人">{{detail.changeby}}</el-descriptions-item>
+          <el-descriptions-item label="最近调整时间">{{detail.changedate}}</el-descriptions-item>
+          <el-descriptions-item label="下达人">{{detail.checkby}}</el-descriptions-item>
+          <el-descriptions-item label="下达时间">{{detail.checkdate}}</el-descriptions-item>
+        </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <div class="header">
+        <Search />
+        <el-button type="primary" size="small">添加</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Header from '@/SManagement/archives_upload/components/Header'
+import Search from '@/components/search/index'
+import { log } from '@antv/g2plot/lib/utils';
+export default {
+  name: '',
+  data() {
+    return {
+      detail: ''
+    };
+  },
+  components: { Header , Search },
+  computed:{
+  },
+  watch:{
+  },
+  created() {
+    this.getPersonalDetail()
+    this.getTargetList()
+  },
+  methods: {
+    async getPersonalDetail() {
+      let res = await this.$api.requested({
+          "id": 20220904190202,
+          "content": {
+              "year": 2023,
+              "hrid":25
+          },
+      })
+      this.detail = res.data
+      console.log(this.detail);
+    },
+    async getTargetList() {
+      let res = await this.$api.requested({
+        "id": 20220904192002,
+        "content": {
+            "year": 2023,
+            "hrid":25,
+            "where":{
+                "condition":""//支持部门名称查询
+            }
+        }
+      })
+      console.log(res);
+      
+    }
+  },
+};
+</script>
+
+<style scoped>
+  .header {
+    display: flex;
+    justify-content: space-between;
+  }
+</style>

+ 244 - 0
src/SManagement/project_target/components/addProject.vue

@@ -0,0 +1,244 @@
+<template>
+  <div class="add-project">
+      <el-button type="primary" size="small" @click="dialogVisible=true">添加</el-button>
+      <!--选择项目弹框-->
+      <el-dialog
+        title="选择项目目标"
+        :visible.sync="dialogVisible"
+        width="50%">
+        <div class="base-info">
+          <div class="year">
+            <span style="margin-right:16px">年度:</span>
+            <el-date-picker v-model="year" disabled type="date" format="yy" size="small" placeholder="选择年度" />
+          </div>
+        </div>
+        <div class="content">
+          <p style="margin-bottom:16px">请编辑项目</p>
+          <Search style="margin-bottom:16px" @searchActive="searchActive" @clearData="clearData" />
+          <Table
+                ref="tables" 
+                v-if="projectList" 
+                :layout="tablecols" 
+                :data="projectList" 
+                :checkbox="true" 
+                :custom="false" 
+                height="calc(100vh - 495px)"
+                @checkboxCallBack="checkboxCallBack">
+          </Table>
+        </div>
+        <span slot="footer" class="dialog-footer" style="display:flex;justify-content: space-evenly">
+          <div>
+            <el-button @click="dialogVisible = false" size="small">取 消</el-button>
+            <el-button type="primary" @click="next" size="small" :disabled="!selectProject">下一步</el-button>
+          </div>
+        </span>
+      </el-dialog>
+      <!--添加目标弹窗-->
+      <el-dialog
+        title="添加项目目标"
+        :visible.sync="dialogVisible2"
+        width="80%"
+        v-if="dialogVisble2=true">
+        <div class="content">
+          <tableLayout :layout="tablecols2" :custom="true" :data="selectProject">
+            <template v-slot:customcol="scope">
+                <div v-if="scope.column.columnname == 'baseTarget'" class="base-target">
+                  <input type="text" @input="baseTargetChange($event,scope.column.data)">
+                </div>
+                <div v-if="scope.column.columnname == 'doubleTarget'" class="base-target">
+                  <input type="text" @input="dealTargetChange($event,scope.column.data)">
+                </div>
+                <div v-if="scope.column.columnname == 'dealTime'">
+                  <el-date-picker
+                    type="month"
+                    placeholder="请选择月份"
+                    size="small"
+                    :ref="scope.column.data.projectnum"
+                    @input="timeChange($refs[scope.column.data.projectnum],$event,scope.column.data)"
+                    :picker-options="{
+                      disabledDate(time) {
+                        return time.getTime() < Date.now() - 8.64e7
+                      },
+                    }" >
+                  </el-date-picker>
+                </div>
+                <div v-if="scope.column.columnname == 'projectnum' || scope.column.columnname == 'projectname'">{{scope.column.data[scope.column.columnname]}}</div>
+            </template>
+          </tableLayout>
+        </div>
+        <span slot="footer" class="dialog-footer" style="display:flex;justify-content: space-evenly">
+          <div>
+            <el-button @click="dialogVisible2 = false" size="small">取 消</el-button>
+            <el-button @click="prenv" size="small">上一步</el-button>
+            <el-button type="primary" @click="submit" size="small">确认添加</el-button>
+          </div>
+        </span>
+      </el-dialog>
+  </div>
+</template>
+
+<script>
+import Search from '@/components/search/index'
+import Table from '@/components/table/index'
+export default {
+  name: '',
+  data() {
+    return {
+      params: {
+        "id": 20220905151902,
+        "content": {
+            "where": {
+                "condition": "" 
+            }
+        },
+      },
+      tablecols:'',
+      tablecols2:'',
+      dialogVisible: false,
+      dialogVisible2: false,
+      year:new Date(),
+      selectProject:'',
+      projectList:''
+    };
+  },
+  components: { Search , Table },
+  computed:{
+  },
+  watch:{
+  },
+  created() {
+    this.getProjectList()
+    this.tablecols = this.tool.tabelCol(this.$route.name).projectTable.tablecols
+    this.tablecols2 = this.tool.tabelCol(this.$route.name).addProjectTargetTable.tablecols
+  },
+  methods: {
+    /* 获取已有的项目数据 */
+    async getProjectList() {
+      let res = await this.$api.requested(this.params)
+      
+      this.projectList = res.data
+    },
+    handleClose() {
+      this.dialogVisible = false
+    },
+    checkboxCallBack(data) {
+      console.log(data);
+      this.selectProject = data
+    },
+    next() {
+      if(!this.selectProject) return
+      this.dialogVisible = false
+      this.dialogVisible2 = true
+    },
+    prenv() {
+      this.dialogVisible = true
+      this.dialogVisible2 = false
+    },
+    /* 基本目标更改 */
+    baseTargetChange(val,data) {
+      data.baseTarget = val.target.value
+    },
+    /* 挑战目标更改 */
+    dealTargetChange(val,data) {
+      data.doubleTarget = val.target.value
+    },
+    /* 预计时间 */
+    timeChange(el,val,data) {
+      let dateNumber = new Date(val)
+      let y = dateNumber.getFullYear()
+      let m = dateNumber.getMonth() + 1
+      el.$el.querySelector('input').value = y + '-' + m
+      data.dealTime = m
+    },
+    /* 搜索 */
+    searchActive(data) {
+      this.params.content.where.condition = data
+      this.getProjectList()
+    },
+    /* 取消搜索 */
+    clearData() {
+      this.params.content.where.condition = ''
+      this.getProjectList()
+    },
+    /* 提交 */
+    async submit() {
+      try {
+        let temp = this.selectProject.map(item => {
+          if(!item.sa_projectid || !item.baseTarget || !item.doubleTarget || !item.dealTime) throw '111'
+          return {
+            "sa_projectid": item.sa_projectid,
+            "target_l": item.baseTarget,
+            "target_h": item.doubleTarget,
+            "month": item.dealTime
+          }
+        })
+        let res = await this.$api.requested({
+          "id": 20220905154102,
+          "content": {
+            "year": 2023,
+            "hrid": 23,
+            // "sa_salestargetbillid":2,//可不传
+            "project": temp
+          }
+        })
+        this.tool.showMessage(res,() => {
+          this.dialogVisible = false
+          this.dialogVisible2 = false
+          this.selectProject = []
+          this.$emit('addSuccess')
+          console.log(this.$refs.tables.$refs.tables.list);
+          
+          this.$refs.tables.$refs.tables.clearSelection()
+        })
+      } catch(err) {
+        this.$notify({
+          title:'提示',
+          message:'请完整填写数据',
+          type:'warning'
+        })
+      }
+    }
+  },
+};
+</script>
+
+<style scoped>
+  *{
+    box-sizing: border-box;
+  }
+  .base-info {
+    display: flex;
+    align-items: center;
+  }
+  .base-info .type {
+    display: flex;
+    align-items: center;
+    margin-left: 60px;
+  }
+  .content {
+    margin: 40px 0 16px 0;
+  }
+  /deep/.el-dialog__body {
+    padding: 10px 20px 0 20px;
+  }
+  /deep/.dialog-footer {
+    margin-top: 20px;
+  }
+  .base-target {
+    width: 100%;
+    padding: 0 15px;
+    border: 1px solid #c0c4cc;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: normal;
+    word-break: break-all;
+    border-radius: 5px;
+    background: #ffffff;
+  }
+  .base-target input {
+    border: 0 none;
+    outline: none;
+    height: 32px;
+    width: 100%;
+  }
+</style>

+ 28 - 0
src/SManagement/project_target/components/delete.vue

@@ -0,0 +1,28 @@
+<template>
+  <div style="display:inline;margin:0 16px">
+    <el-popconfirm title="确定删除当前数据吗?" @confirm="deleteRow()">
+      <el-button slot="reference" size="small" type="text">删 除</el-button>
+    </el-popconfirm>
+  </div>
+</template>
+
+<script>
+export default {
+  props: ['id'],
+  methods: {
+    async deleteRow() {
+      let res = await this.$api.requested({
+          "id": 20220905165302,
+          "content": {
+              "sa_salestargetid": this.id
+          },
+      })
+      console.log(res);
+      this.tool.showMessage(res,() => {
+        this.$emit('deleteSuccess')
+      })
+    },
+  }
+}
+
+</script>

+ 84 - 0
src/SManagement/project_target/components/editBtn.vue

@@ -0,0 +1,84 @@
+<template>
+  <div class="edit">
+    <el-button type="text" size="small" @click="editBtn">编辑</el-button>
+    <el-dialog
+      title="编辑"
+      :visible.sync="dialogVisible"
+      width="30%"
+      :before-close="handleClose">
+      <div class="info">
+        <el-form :model="currentData" ref="ruleForm" :rules="rules" label-width="100px" class="demo-ruleForm">
+        <el-form-item label="基本目标" prop="target_l">
+          <el-input v-model="currentData.target_l" size="small"></el-input>
+        </el-form-item>
+        <el-form-item label="挑战目标" prop="target_h">
+          <el-input v-model="currentData.target_h" size="small"></el-input>
+        </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <div class="bottom">
+          <el-button @click="dialogVisible = false" size="small">取 消</el-button>
+          <el-button type="primary" @click="submit" size="small">确 定</el-button>
+        </div>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: '',
+  data() {
+    return {
+      dialogVisible:false,
+      currentData: {
+        target_l:'',
+        target_h:'',
+        sa_salestargetid:''
+      },
+      rules:{
+        target_l:[
+          { required: true, message: '请填写基本目标', trigger: 'blur' }
+        ],
+        target_h:[
+          { required: true, message: '请填写挑战目标', trigger: 'blur' }
+        ]
+      }
+    };
+  },
+  props:['editData'],
+  computed:{
+  },
+  watch:{
+  },
+  methods: {
+    handleClose() {
+      this.dialogVisible = false
+    },
+    editBtn() {
+      this.dialogVisible = true
+      this.currentData = {
+        target_l:this.editData.data.target_l,
+        target_h:this.editData.data.target_h,
+        sa_salestargetid:this.editData.data.sa_salestargetid
+      }
+    },
+    async submit() {
+      let res = await this.$api.requested({
+        "id": 20220906112602,
+        "content": this.currentData,
+      })
+      console.log(res);
+      this.tool.showMessage(res,() => {
+        this.$emit('editSuccess')
+        this.dialogVisible = false
+      })
+    }
+  },
+};
+</script>
+
+<style scoped>
+
+</style>

+ 60 - 0
src/SManagement/project_target/components/selectPanel.vue

@@ -0,0 +1,60 @@
+<template>
+  <div class="select">
+    <div class="year">
+      <span>年度:</span>
+      <el-date-picker v-model="year" type="date" size="small" placeholder="选择年度" />
+    </div>
+    <Search />
+    <div class="target">
+      <span>考核指标:</span>
+      <el-select v-model="target" placeholder="请选择" size="small">
+        <el-option
+          v-for="item in options"
+          :key="item.value"
+          :label="item.label"
+          :value="item.value">
+        </el-option>
+      </el-select>
+    </div>
+  </div>
+</template>
+
+<script>
+import Search from '@/components/search/index'
+export default {
+  name: '',
+  data() {
+    return {
+      year:'',
+      target:'',
+      options:[
+        {label:'开票指标',value:'1'},
+        {label:'订单金额',value:'2'},
+        {label:'出货金额',value:'3'},
+      ]
+    };
+  },
+  components: { Search, },
+  computed:{
+  },
+  watch:{
+  },
+  methods: {},
+};
+</script>
+
+<style scoped>
+  .select {
+    font-size: 14px;
+    display: flex;
+    align-items: center;
+  }
+  .select .year,.target {
+    display: flex;
+    align-items: center;
+    margin-right: 16px;
+  }
+  .select span,.target span {
+    margin-right: 8px;
+  }
+</style>

+ 506 - 0
src/SManagement/project_target/components/table.vue

@@ -0,0 +1,506 @@
+<template>
+  <div style="margin-top:16px">
+    <el-table
+      :data="tableData"
+      style="width: 100%"
+      height="calc(100vh - 182px)"
+      size="small">
+      <el-table-column
+        prop="depfullname"
+        label="部门"
+        width="120"
+        fixed>
+        <template slot-scope="scope">
+          <p :style="{textIndent:scope.row.level === 0?'10px':''}">{{scope.row.level === 0?'--':scope.row.depfullname}}</p>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="name"
+        label="人员"
+        width="80"
+        fixed>
+        <template slot-scope="scope">
+          <p>{{scope.row.name?scope.row.name:'--'}}</p>
+        </template>
+      </el-table-column>
+      <el-table-column
+        prop="position"
+        label="职位"
+        width="100"
+        fixed>
+        <template slot-scope="scope">
+          <p>{{scope.row.position?scope.row.position:'--'}}</p>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="目标/实际"
+        width="100">
+        <template>
+          <p class="center d-text">目标</p>
+          <p class="border"></p>
+          <p class="center d-text">实际</p>
+        </template>
+      </el-table-column>
+      <el-table-column label="年度(万元)">
+        <el-table-column
+          prop="y1l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.y1l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.y1a}}</p>
+            <p class="center" :class="scope.row.y1pl < 0?'green':'red'">({{scope.row.y1pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="y1h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.y1h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.y1a}}</p>
+            <p class="center" :class="scope.row.y1ph < 0?'green':'red'">({{scope.row.y1ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="第一季度(万元)">
+        <el-table-column
+          prop="s1l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.s1l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.s1a}}</p>
+            <p class="center" :class="scope.row.s1pl < 0?'green':'red'">({{scope.row.s1pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="s1h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.s1h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.s1a}}</p>
+            <p class="center" :class="scope.row.s1ph < 0?'green':'red'">({{scope.row.s1ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="一月(万元)">
+        <el-table-column
+          prop="m1l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m1l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m1a}}</p>
+            <p class="center" :class="scope.row.m1pl < 0?'green':'red'">({{scope.row.m1pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m1h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m1h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m1a}}</p>
+            <p class="center" :class="scope.row.m1ph < 0?'green':'red'">({{scope.row.m1ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="二月(万元)">
+        <el-table-column
+          prop="m2l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m2l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m2a}}</p>
+            <p class="center" :class="scope.row.m2pl < 0?'green':'red'">({{scope.row.m2pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m2h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m2h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m2a}}</p>
+            <p class="center" :class="scope.row.m2ph < 0?'green':'red'">({{scope.row.m2ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="三月(万元)">
+        <el-table-column
+          prop="m3l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m3l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m3a}}</p>
+            <p class="center" :class="scope.row.m3pl < 0?'green':'red'">({{scope.row.m3pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m3h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m3h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m3a}}</p>
+            <p class="center" :class="scope.row.m3ph < 0?'green':'red'">({{scope.row.m3ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="第二季度(万元)">
+        <el-table-column
+          prop="s2l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.s2l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.s2a}}</p>
+            <p class="center" :class="scope.row.s2pl < 0?'green':'red'">({{scope.row.s2pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="s2h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.s2h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.s2a}}</p>
+            <p class="center" :class="scope.row.s2ph < 0?'green':'red'">({{scope.row.s2ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="四月(万元)">
+        <el-table-column
+          prop="m4l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m4l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m4a}}</p>
+            <p class="center" :class="scope.row.m4pl < 0?'green':'red'">({{scope.row.m4pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m4h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m4h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m4a}}</p>
+            <p class="center" :class="scope.row.m4ph < 0?'green':'red'">({{scope.row.m4ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="五月(万元)">
+        <el-table-column
+          prop="m5l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m5l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m5a}}</p>
+            <p class="center" :class="scope.row.m5pl < 0?'green':'red'">({{scope.row.m5pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m5h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m5h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m5a}}</p>
+            <p class="center" :class="scope.row.m5ph < 0?'green':'red'">({{scope.row.m5ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="六月(万元)">
+        <el-table-column
+          prop="m6l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m6l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m6a}}</p>
+            <p class="center" :class="scope.row.m6pl < 0?'green':'red'">({{scope.row.m6pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m6h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m6h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m6a}}</p>
+            <p class="center" :class="scope.row.m6ph < 0?'green':'red'">({{scope.row.m6ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="第三季度(万元)">
+        <el-table-column
+          prop="s3l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.s3l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.s3a}}</p>
+            <p class="center" :class="scope.row.s3pl < 0?'green':'red'">({{scope.row.s3pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="s3h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.s3h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.s3a}}</p>
+            <p class="center" :class="scope.row.s3ph < 0?'green':'red'">({{scope.row.s3ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="七月(万元)">
+        <el-table-column
+          prop="m7l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m7l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m7a}}</p>
+            <p class="center" :class="scope.row.m7pl < 0?'green':'red'">({{scope.row.m7pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m7h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m7h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m7a}}</p>
+            <p class="center" :class="scope.row.m7ph < 0?'green':'red'">({{scope.row.m7ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="八月(万元)">
+        <el-table-column
+          prop="m8l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m8l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m8a}}</p>
+            <p class="center" :class="scope.row.m8pl < 0?'green':'red'">({{scope.row.m8pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m8h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m8h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m8a}}</p>
+            <p class="center" :class="scope.row.m8ph < 0?'green':'red'">({{scope.row.m8ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="九月(万元)">
+        <el-table-column
+          prop="m9l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m9l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m9a}}</p>
+            <p class="center" :class="scope.row.m9pl < 0?'green':'red'">({{scope.row.m9pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m9h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m9h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m9a}}</p>
+            <p class="center" :class="scope.row.m9ph < 0?'green':'red'">({{scope.row.m9ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="第四季度(万元)">
+        <el-table-column
+          prop="s4l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.s4l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.s4a}}</p>
+            <p class="center" :class="scope.row.s4pl < 0?'green':'red'">({{scope.row.s4pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="s4h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.s4h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.s4a}}</p>
+            <p class="center" :class="scope.row.s4ph < 0?'green':'red'">({{scope.row.s4ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="十月(万元)">
+        <el-table-column
+          prop="m10l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m10l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m10a}}</p>
+            <p class="center" :class="scope.row.m10pl < 0?'green':'red'">({{scope.row.m10pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m10h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m10h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m10a}}</p>
+            <p class="center" :class="scope.row.m10ph < 0?'green':'red'">({{scope.row.m10ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="十一月(万元)">
+        <el-table-column
+          prop="m11l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m11l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m11a}}</p>
+            <p class="center" :class="scope.row.m11pl < 0?'green':'red'">({{scope.row.m11pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m11h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m11h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m11a}}</p>
+            <p class="center" :class="scope.row.m11ph < 0?'green':'red'">({{scope.row.m11ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+      <el-table-column label="十二月(万元)">
+        <el-table-column
+          prop="m12l"
+          label="基本"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m12l}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m12a}}</p>
+            <p class="center" :class="scope.row.m12pl < 0?'green':'red'">({{scope.row.m12pl}}%)</p>
+          </template>
+        </el-table-column>
+        <el-table-column
+          prop="m12h"
+          label="挑战"
+          width="120">
+          <template slot-scope="scope">
+            <p class="center d-text">{{scope.row.m12h}}</p>
+            <p class="border"></p>
+            <p class="center">{{scope.row.m12a}}</p>
+            <p class="center" :class="scope.row.m12ph < 0?'green':'red'">({{scope.row.m12ph}}%)</p>
+          </template>
+        </el-table-column>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      tableData:[],
+      year:String((new Date()).getFullYear()),
+      condition:''
+    }
+  },
+  methods:{
+    async queryData () {
+      const res = await this.$api.requested({
+        "id": 20220904134102,
+        "content": {
+          "year": this.year,
+          "type":1,
+          "where":{
+            "condition":this.condition
+          }
+        }
+      })
+      this.tableData = res.data
+    }
+  },
+  mounted () {
+    this.queryData()
+  }
+}
+
+</script>
+<style>
+</style>
+<style scoped>
+.d-text{
+  height: 46px;
+  line-height: 46px;
+}
+.border{
+  border:1px solid #c1bfbf;
+  transform: scale(1,.2);
+}
+.center{
+  text-align: center;
+}
+.red{
+  color:red
+}
+.green{
+  color:green
+}
+</style>

+ 53 - 0
src/SManagement/project_target/index.vue

@@ -0,0 +1,53 @@
+<template>
+  <div class="personal-target">
+    <Header>
+      <el-button size="small">导出</el-button>
+    </Header>
+    <div class="container normal-panel">
+      <select-panel />
+      <table1 />
+    </div>
+  </div>
+</template>
+
+<script>
+import Header from '@/SManagement/archives_upload/components/Header';
+import selectPanel from './components/selectPanel'
+import table1 from './components/table'
+export default {
+  name: '',
+  data() {
+    return {
+    };
+  },
+  components: { Header, selectPanel , table1},
+  computed:{
+  },
+  watch:{
+  },
+  created() {
+    this.getYearTarget()
+  },
+  methods: {
+    async getYearTarget() {
+      let res = await this.$api.requested({
+        "id": 20220903170002,
+        "content": {
+            "where": {
+                "condition": "",
+                "status": ""
+            },
+            "pageNumber": 1,
+            "pageSize": 20
+        },
+      })
+      console.log(res);
+      
+    }
+  },
+};
+</script>
+
+<style scoped>
+
+</style>

+ 121 - 0
src/SManagement/project_target/modules/detailInfo.vue

@@ -0,0 +1,121 @@
+<template>
+  <div class="edit">
+    <Header>
+      <el-button type="warning" size="small">保存</el-button>
+    </Header>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">基础信息</p>
+      <el-descriptions :column="4">
+          <el-descriptions-item label="年度">{{detail.year?detail.year:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="部门">{{detail.depname?detail.depname:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="人员姓名">{{detail.name?detail.name:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="职位">{{detail.position?detail.position:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="营销区域">{{detail.areaname?detail.areaname:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="状态"><span :style="detail.status === '已下达'?'color:#52C41A':'color:#000000'">{{detail.status}}</span></el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">系统信息</p>
+      <el-descriptions :column="4">
+          <el-descriptions-item label="创建人">{{detail.createby?detail.createby:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="创建时间">{{detail.createdate?detail.createdate:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="最近调整人">{{detail.changeby?detail.changeby:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="最近调整时间">{{detail.changedate?detail.changedate:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="下达人">{{detail.checkby?detail.checkby:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="下达时间">{{detail.checkdate?detail.checkdate:'未知'}}</el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">项目统计</p>
+      <el-descriptions :column="4">
+          <el-descriptions-item label="项目总数">{{detail.projectnum?detail.projectnum:'暂无'}}</el-descriptions-item>
+          <el-descriptions-item label="项目基本目标(万元)">{{detail.target_l?detail.target_l:'暂无'}}</el-descriptions-item>
+          <el-descriptions-item label="项目挑战目标(万元)">{{detail.target_h?detail.target_h:'暂无'}}</el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <div class="header" style="margin-bottom:16px">
+        <Search @searchActive="searchActive" @clearData="clearData" />
+      </div>
+      <tableLayout v-if="list" :layout="tablecols" :data="list" :custom="false" height="300">
+      </tableLayout>
+    </div>
+  </div>
+</template>
+
+<script>
+import Header from '@/SManagement/archives_upload/components/Header'
+import Search from '@/components/search/index'
+export default {
+  name: '',
+  data() {
+    return {
+      params: {
+        "id": 20220906104002,
+        "content": {
+            "year": 2023,
+            "hrid": 23,
+            "where": {
+                "condition": ""
+            },
+            "pageNumber": 1,
+            "pageSize": 20
+        }
+      },
+      tablecols:'',
+      detail:'',
+      list:'',
+      hrid:JSON.parse(window.sessionStorage.getItem('active_account')).hrid
+    };
+  },
+  components: { Header , Search },
+  computed:{
+  },
+  watch:{
+  },
+  created () {
+    this.ProjectInfo()
+    this.getprojectTargetList()
+    this.tablecols = this.tool.tabelCol(this.$route.name).projectTargetTable.tablecols
+    this.tablecols.pop()
+  },
+  methods: {
+    /* 获取项目信息 */
+    async ProjectInfo () {
+      let res = await this.$api.requested({
+          "id": 20220906094602,
+          "content": {
+              "year": 2023,
+              "hrid": this.hrid,
+              // "sa_salestargetbillid": 2//可不传
+          }
+      })
+      this.detail = res.data
+      console.log(this.detail);
+    },
+    /* 获取项目目标数据 */
+    async getprojectTargetList() {
+      this.params.content.hrid = this.hrid
+      let res = await this.$api.requested(this.params)
+      this.list = res.data
+      console.log(this.list);
+      
+    },
+    searchActive(data) {
+      this.params.content.where.condition = data
+      this.getprojectTargetList()
+    },
+    clearData() {
+      this.params.content.where.condition = ''
+      this.getprojectTargetList()
+    }
+  },
+};
+</script>
+
+<style scoped>
+  .header {
+    display: flex;
+    justify-content: space-between;
+  }
+</style>

+ 132 - 0
src/SManagement/project_target/modules/editInfo.vue

@@ -0,0 +1,132 @@
+<template>
+  <div class="edit">
+    <Header>
+      <el-button type="warning" size="small">保存</el-button>
+    </Header>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">基础信息</p>
+      <el-descriptions :column="4">
+          <el-descriptions-item label="年度">{{detail.year?detail.year:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="部门">{{detail.depname?detail.depname:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="人员姓名">{{detail.name?detail.name:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="职位">{{detail.position?detail.position:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="营销区域">{{detail.areaname?detail.areaname:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="状态"><span :style="detail.status === '已下达'?'color:#52C41A':'color:#000000'">{{detail.status}}</span></el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">系统信息</p>
+      <el-descriptions :column="4">
+          <el-descriptions-item label="创建人">{{detail.createby?detail.createby:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="创建时间">{{detail.createdate?detail.createdate:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="最近调整人">{{detail.changeby?detail.changeby:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="最近调整时间">{{detail.changedate?detail.changedate:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="下达人">{{detail.checkby?detail.checkby:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="下达时间">{{detail.checkdate?detail.checkdate:'未知'}}</el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">项目统计</p>
+      <el-descriptions :column="4">
+          <el-descriptions-item label="项目总数">{{detail.projectnum?detail.projectnum:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="项目基本目标(万元)">{{detail.target_l?detail.target_l:'暂无'}}</el-descriptions-item>
+          <el-descriptions-item label="项目挑战目标(万元)">{{detail.target_h?detail.target_h:'暂无'}}</el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <div class="header" style="margin-bottom:16px">
+        <Search />
+        <add-project @addSuccess="getprojectTargetList" />
+      </div>
+      <tableLayout v-if="list" :layout="tablecols" :data="list" :custom="false" height="300">
+        <template v-slot:opreation="scope">
+            <div style="display:flex;"> 
+              <edit-btn :editData="scope" @editSuccess="getprojectTargetList" v-if="tool.checkAuth($route.name,'update')"/>
+              <Delete :id="scope.data.sa_salestargetid" @deleteSuccess="getprojectTargetList" v-if="tool.checkAuth($route.name,'delete')"/>
+            </div>
+        </template>
+      </tableLayout>
+    </div>
+  </div>
+</template>
+
+<script>
+import Header from '@/SManagement/archives_upload/components/Header'
+import Search from '@/components/search/index'
+import addProject from '../components/addProject'
+import editBtn from '../components/editBtn'
+import Delete from '../components/delete'
+export default {
+  name: '',
+  data() {
+    return {
+      params: {
+        "id": 20220906104002,
+        "content": {
+            "year": 2023,
+            "hrid": 0,
+            "where": {
+                "condition": ""
+            },
+            "pageNumber": 1,
+            "pageSize": 20
+        }
+      },
+      tablecols:'',
+      detail:'',
+      list:'',
+      hrid:JSON.parse(window.sessionStorage.getItem('active_account')).hrid
+    };
+  },
+  components: { Header , Search , addProject , editBtn , Delete},
+  computed:{
+  },
+  watch:{
+  },
+  created () {
+    this.ProjectInfo()
+    this.getprojectTargetList()
+    this.tablecols = this.tool.tabelCol(this.$route.name).projectTargetTable.tablecols
+  },
+  methods: {
+    /* 获取项目信息 */
+    async ProjectInfo () {
+      let res = await this.$api.requested({
+          "id": 20220906094602,
+          "content": {
+              "year": 2023,
+              "hrid": this.hrid,
+              // "sa_salestargetbillid": 2//可不传
+          }
+      })
+      this.detail = res.data
+      console.log(this.detail);
+    },
+    /* 获取项目目标数据 */
+    async getprojectTargetList() {
+      this.params.content.hrid = this.hrid
+      let res = await this.$api.requested(this.params)
+      this.list = res.data
+      console.log(this.list);
+    },
+    searchActive(data) {
+      this.params.content.where.condition = data
+      this.getprojectTargetList()
+    },
+    clearData() {
+      this.params.content.where.condition = ''
+      this.getprojectTargetList()
+    }
+  },
+};
+</script>
+
+<style scoped>
+  .header {
+    display: flex;
+    justify-content: space-between;
+  }
+  /deep/.el-dialog__body {
+    padding-bottom: 0 !important;
+  }
+</style>

+ 160 - 0
src/SManagement/sales_forecast/components/addProduct.vue

@@ -0,0 +1,160 @@
+<template>
+  <div class="add">
+    <el-button @click="dialogVisible=true" type="text" size="small">添加</el-button>
+    <!--添加产品-->
+    <el-dialog title="添加产品" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
+      <div style="display:flex;margin-bottom:20px">
+        <span style="margin-right:20px"> 项目编号: {{data1.data.projectnum}}</span>
+        <span>项目名称: {{data1.data.projectname}}</span>
+      </div>
+      <el-select v-model="idArr" @change="selectChange" multiple placeholder="请选择" size="small">
+        <el-option v-for="(item,index) in productList" :key="index" :label="item.itemclassfullname"
+          :value="item.itemclassid">
+        </el-option>
+      </el-select>
+      <span slot="footer" class="dialog-footer" style="display:flex;justify-content: space-evenly">
+        <div>
+          <el-button @click="dialogVisible = false" size="small">取 消</el-button>
+          <el-button type="primary" @click="addProject" :disabled="!selectProject == true" size="small">确定添加</el-button>
+        </div>
+      </span>
+    </el-dialog>
+    <!--编辑产品数据-->
+    <el-dialog title="添加产品" :visible.sync="dialogVisible2" width="60%" :before-close="handleClose2">
+      <div style="display:flex;margin-bottom:20px">
+        <span style="margin-right:20px"> 项目编号: {{data1.data.projectnum}}</span>
+        <span>项目名称: {{data1.data.projectname}}</span>
+      </div>
+      <tableLayout :layout="tablecols" :custom="true" :data="selectProject">
+        <template v-slot:customcol="scope">
+            <div v-if="scope.column.columnname != 'itemclassfullname'" class="base-target">
+              <input type="text" @input="baseTargetChange($event,scope.column.data,scope.column.columnname)">
+            </div>
+            <div v-else>
+              {{scope.column.data[scope.column.columnname]}}
+            </div>
+        </template>
+      </tableLayout>
+      <span slot="footer" class="dialog-footer" style="display:flex;justify-content: space-evenly">
+        <div>
+          <el-button @click="dialogVisible2 = false" size="small">取 消</el-button>
+          <el-button type="primary" @click="editNum" size="small">确定提交</el-button>
+        </div>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: '',
+  data () {
+    return {
+      dialogVisible: false,
+      dialogVisible2:false,
+      /* 选中的产品 */
+      selectProject:'',
+      idArr: ''
+    };
+  },
+  props: ['data1', 'productList','tablecols'],
+  computed: {
+  },
+  watch: {
+
+  },
+  methods: {
+    addProject () {
+      if(!this.selectProject) return 
+      this.dialogVisible = false
+      this.dialogVisible2 = true
+    },
+    /* 编辑产品数据 */
+    async editNum() {
+      try {
+        this.selectProject.forEach(item => {
+          if(!item.invoiceamount || !item.invoiceqty || !item.orderamount || !item.orderqty || !item.outamount || !item.outqty) throw '111'
+        })   
+        let res = await this.$api.requested({
+            "id": 20220906155003,
+            "version":1,
+            "content": {
+                "sa_salesforecastmodelid":this.$route.query.id2,
+                "sa_salesforecastbillid":this.data1.data.sa_salesforecastbillid,
+                "sa_projectid": this.data1.data.sa_projectid,
+                "itemclassinfos": this.selectProject
+            }
+        })
+        this.tool.showMessage(res,() => {
+          this.$emit('addSuccess')
+          this.dialogVisible2 = false
+        })
+      } catch (err) {
+        this.$notify({
+          title:'提示',
+          message:'请完整填写数据',
+          type:'warning'
+        })
+      }
+         
+    },
+    handleClose () {
+      this.dialogVisible = false
+    },
+    handleClose2() {
+      this.dialogVisible2 = false
+    },
+    selectChange(data) {
+      this.selectProject = data.map(item => {
+        let result = this.productList.find(item2 => {
+          return item2.itemclassid == item
+        })
+        console.log(result);
+        return {
+          sa_salesforecastid:0,
+          itemclassnum:result.itemclassnum,
+          itemclassfullname:result.itemclassfullname,
+          orderqty:'',
+          orderamount:'',
+          invoiceqty:'',
+          invoiceamount:'',
+          outqty:'',
+          outamount:'',
+        }
+      })
+    console.log(this.selectProject);
+    
+    },
+    /* 基本目标更改 */
+    baseTargetChange(val,data,name) {
+      data[name] = val.target.value
+    },
+  },
+};
+</script>
+
+<style scoped>
+/deep/.el-select {
+  width: 100% !important;
+}
+/deep/.el-dialog__body {
+  padding-bottom: 0 !important;
+}
+.base-target {
+  width: 100%;
+  padding: 0 15px;
+  border: 1px solid #c0c4cc;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: normal;
+  word-break: break-all;
+  border-radius: 5px;
+  background: #ffffff;
+}
+.base-target input {
+  border: 0 none;
+  outline: none;
+  height: 32px;
+  width: 100%;
+}
+</style>

+ 95 - 0
src/SManagement/sales_forecast/components/addProject.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="add">
+    <el-button @click="dialogVisible=true" size="small">添加项目</el-button>
+    <el-dialog
+      title="选择项目"
+      :visible.sync="dialogVisible"
+      width="50%"
+      :before-close="handleClose">
+      <Search style="margin-bottom:16px" />
+      <table1 v-if="projectList" :layout="tablecols" :custom="false" :checkbox="true" :data="projectList" height="40vh"
+        @checkboxCallBack="checkboxCallBack">
+      </table1>
+      <span slot="footer" class="dialog-footer" style="display:flex;justify-content: space-evenly">
+        <div>
+          <el-button @click="dialogVisible = false" size="small">取 消</el-button>
+          <el-button type="primary" @click="addProject" size="small" :disabled="!this.selectProject==true">确定添加</el-button>
+        </div>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import Search from '@/components/search/index'
+import table1 from '@/components/table/index'
+export default {
+  name: '',
+  data() {
+    return {
+      dialogVisible:false,
+      tablecols:'',
+      projectList:'',
+      selectProject:''
+    };
+  },
+  components:{Search , table1},
+  computed:{
+  },
+  watch:{
+  },
+  created() {
+    this.getProjectList()
+    this.tablecols = this.tool.tabelCol(this.$route.name).projectListTable.tablecols
+  },
+  methods: {
+    async getProjectList() {
+      let res = await this.$api.requested({
+        "id": 20220906154803,
+        "version":1,
+        "content": {
+            "where":{
+                "condition":"万达"
+            }
+        }
+      })
+      this.projectList = res.data
+      console.log(this.projectList);
+      
+    },
+    async addProject() {
+      if(!this.selectProject) return
+      let idArr = this.selectProject.map(item => item.sa_projectid)
+      let res = await this.$api.requested({
+        "id": 20220913154403,
+        "version":1,
+        "content": {
+            "sa_salesforecastmodelid":this.$route.query.id2,
+            "sa_salesforecastbillid":this.$route.query.id,
+            "sa_projectids": idArr
+        }
+      })
+        console.log(res)
+      this.tool.showMessage(res,() => {
+        this.dialogVisible = false
+        this.$emit('addSuccess')
+        console.log(res)
+      })
+      
+    },
+    checkboxCallBack(data) {
+      console.log(data);
+      this.selectProject = data
+    },
+    handleClose() {
+      this.dialogVisible = false
+    }
+  },
+};
+</script>
+
+<style scoped>
+  /deep/.el-dialog__body {
+    padding-bottom: 0;
+  }
+</style>

+ 32 - 0
src/SManagement/sales_forecast/components/delete.vue

@@ -0,0 +1,32 @@
+<template>
+  <div style="display:inline;margin:0 16px">
+    <el-popconfirm title="确定删除当前产品吗?" @confirm="deleteRow()">
+      <el-button slot="reference" size="small" type="text" :disabled="!rowData.itemclassname && projectid == 0">删 除</el-button>
+    </el-popconfirm>
+  </div>
+</template>
+
+<script>
+export default {
+  props: ['rowData','projectid'],
+  methods: {
+    async deleteRow() {
+      let res = await this.$api.requested({
+        "id": 20220906155103,
+        "version":1,
+        "content": {
+            "sa_salesforecastid":this.rowData.sa_salesforecastid,
+            "sa_projectid":this.projectid,
+            "sa_salesforecastbillid":this.rowData.sa_salesforecastbillid
+        }
+      })
+      this.tool.showMessage(res,() => {
+        console.log(111);
+        
+        this.$emit('deleteSuccess')
+      })
+    },
+  }
+}
+
+</script>

+ 114 - 0
src/SManagement/sales_forecast/components/edit.vue

@@ -0,0 +1,114 @@
+<template>
+  <div class="add">
+    <el-button @click="dialogVisible=true" type="text" size="small" :disabled="!editData.itemclassname">编辑</el-button>
+    <el-dialog
+      title="编辑产品数据"
+      :visible.sync="dialogVisible"
+      width="60%"
+      :before-close="handleClose">
+      <tableLayout v-if="editData" :layout="tablecols" :custom="true" :data="[editData]">
+        <template v-slot:customcol="scope">
+            <div v-if="scope.column.columnname != 'itemclassfullname'" class="base-target">
+              <input type="text" v-model="editData[scope.column.columnname]" @input="baseTargetChange($event,scope.column.data,scope.column.columnname)">
+            </div>
+            <div v-else>
+              {{scope.column.data.itemclassname}}
+            </div>
+        </template>
+      </tableLayout>
+      <span slot="footer" class="dialog-footer" style="display:flex;justify-content: space-evenly">
+        <div>
+          <el-button @click="dialogVisible = false" size="small">取 消</el-button>
+          <el-button type="primary" @click="editProject" size="small">确定添加</el-button>
+        </div>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  name: '',
+  data() {
+    return {
+      dialogVisible:false
+    };
+  },
+  props:['editData','tablecols'],
+  computed:{
+  },
+  watch:{
+  },
+  methods: {
+    async editProject() {
+      return console.log(this.editData);
+      
+      let itemInfo = {
+        sa_salesforecastid:this.editData.sa_salesforecastid,
+        itemclassnum:'123456',
+        itemclassfullname:this.editData.itemclassfullname,
+        orderqty:this.editData.orderqty,
+        orderamount:this.editData.orderamount,
+        invoiceqty:this.editData.invoiceqty,
+        invoiceamount:this.editData.invoiceamount,
+        outqty:this.editData.outqty,
+        outamount:this.editData.outamount,
+      }
+      
+      try {
+        if(!this.editData.invoiceamount || !this.editData.invoiceqty || !this.editData.orderamount || !this.editData.orderqty || !this.editData.outamount || !this.editData.outqty) throw '111'
+        let res = await this.$api.requested({
+            "id": 20220906155003,
+            "version":1,
+            "content": {
+                "sa_salesforecastmodelid":this.$route.query.id2,
+                "sa_salesforecastbillid":this.editData.sa_salesforecastbillid,
+                "sa_projectid": this.editData.sa_projectid,
+                "itemclassinfos": [itemInfo]
+            }
+        })
+        console.log(res);
+        
+        this.tool.showMessage(res,() => {
+          this.$emit('editSuccess')
+          this.dialogVisible = false
+        })
+      } catch (err) {
+        this.$notify({
+          title:'提示',
+          message:'请完整填写数据',
+          type:'warning'
+        })
+      }
+         
+    },
+    handleClose() {
+      this.dialogVisible = false
+    },
+    /* 基本目标更改 */
+    baseTargetChange(val,data,name) {
+      data[name] = val.target.value
+    }
+  }
+}
+</script>
+
+<style scoped>
+.base-target {
+  width: 100%;
+  padding: 0 15px;
+  border: 1px solid #c0c4cc;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: normal;
+  word-break: break-all;
+  border-radius: 5px;
+  background: #ffffff;
+}
+.base-target input {
+  border: 0 none;
+  outline: none;
+  height: 32px;
+  width: 100%;
+}
+</style>

+ 86 - 0
src/SManagement/sales_forecast/components/mergeTable.vue

@@ -0,0 +1,86 @@
+<template>
+  <div>
+    <el-table :span-method="arraySpanMethod" :row-class-name="tableClassName" v-loading="loading" highlight-current-row :data="data1" :header-cell-style="{background:'#EEEEEE',color:'#333'}" size="mini" :height="height" @row-click="rowClick" style="width:100%"  border>
+      <el-table-column v-for="col in layout" :key="col.tablecolid" :prop="col.columnname" :label="col.title" :width="col.width">
+        <template slot-scope="scope">
+          <!-- 自定义表格显示内容 -->
+          <slot v-if="custom" name="customcol" :column="{data:scope.row,columnname:col.columnname}"></slot>
+          <!-- 否则就是默认 -->
+          <span v-else>{{scope.row[col.columnname]}}</span>
+          <!-- 操作结构内容 -->
+          <slot v-if="col.columnname === 'product_handle'" name="product_handle" :data="scope.row"></slot>
+          <slot v-if="col.columnname === 'project_handle'" name="project_handle" :data="scope.row"></slot>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import {mapGetters} from "vuex"
+export default {
+  /*
+    layout:表结构数据;
+    data:表渲染数据;
+    custom:是否启用自定义结构;
+    opwidth:操作列宽度
+  */
+  props:['layout','data1','custom','height','endFalse'],
+  data () {
+    return {
+    }
+  },
+  computed:{
+    ...mapGetters({
+      loading:'loading'
+    })
+  },
+  methods:{
+    rowClick (row) {
+      this.$emit('rowClick',row)
+    },
+    tableClassName ({row,rowIndex}) {
+      row.index = rowIndex
+    },
+    arraySpanMethod({row, column, rowIndex, columnIndex}) {
+      if(columnIndex == 0 || columnIndex == 1 || columnIndex == this.layout.length - 1 && this.endFalse) {
+        let _row = this.calcMerge().row[rowIndex]
+        let _col = _row > 0 ? 1 : 0
+        return {
+          rowspan: _row,
+          colspan:_col
+        }
+      }
+    },
+    calcMerge() {
+      let rowArr = [],
+          colArr = [],
+          rowIndex = 0,
+          colIndex = 0
+      this.data1.forEach((item,index) => {
+        if(index == 0) {
+          rowArr.push(1)
+          colArr.push(1)
+        } else {
+          if(item.projectnum == this.data1[index - 1].projectnum) {
+            rowArr[rowIndex] +=1
+            rowArr.push(0)
+          } else {
+            rowArr.push(1)
+            rowIndex = index
+          }
+        }
+      })
+      return {
+        row:rowArr,
+        col:colArr
+      }
+    }
+  },
+  mounted () {
+  }
+}
+
+</script>
+<style>
+</style>

+ 210 - 0
src/SManagement/sales_forecast/index.vue

@@ -0,0 +1,210 @@
+<template>
+  <div class="sales">
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">预测提报任务</p>
+      <tableLayout v-if="salesPanelList" :layout="tablecols" :data="salesPanelList" :custom="true" height="30vh" @rowClick="rowClick">
+        <template v-slot:customcol="scope">
+          <div v-if="scope.column.columnname == 'periodtype'">
+            <span>
+              {{scope.column.data.periodpoint | timer(scope.column.data[scope.column.columnname])}}
+            </span>
+          </div>
+          <div v-if="scope.column.columnname == 'date'">
+            <span>{{scope.column.data.begdate}}至{{scope.column.data.enddate}}</span>
+          </div>
+          <span v-else>{{scope.column.data[scope.column.columnname]}}</span>
+        </template>
+        <template v-slot:opreation="scope">
+          <el-button type="text" size="small"
+            @click="addBuill(scope)"
+            v-if="tool.checkAuth($route.name,'update')">创建提报</el-button>
+        </template>
+      </tableLayout>
+      <pagination :total="total" :pageSize="params.content.pageSize" :currentPage="params.content.pageNumber"
+        @pageChange="pageChange" style="margin-top:16px;display:flex;justify-content: flex-end;">
+      </pagination>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">销售预测记录</p>
+      <div class="header-handle">
+        <Search />
+        <DownSelect title="提报要求:" :list="[{value:'按产品类别'},{value:'按产品类别 + 项目'}]" style="margin-right:16px" />
+        <time-select @clearSelect="clearSelect" @timeChange="timeChange" title="提报时间:"></time-select>
+      </div>
+      <tableLayout v-if="historyList" :layout="tablecols2" :data="historyList" :custom="true" height="30vh">
+        <template v-slot:customcol="scope">
+          <div v-if="scope.column.columnname == 'periodtype'">
+            <span>
+              {{scope.column.data.periodpoint | timer(scope.column.data[scope.column.columnname])}}
+            </span>
+          </div>
+          <div v-else-if="scope.column.columnname == 'baseonproject'">
+            <span v-if="scope.column.data[scope.column.columnname] == '1'">按项目及产品类别预测</span>
+            <span v-else>按产品类别预测</span>
+          </div>
+          <span v-else>{{scope.column.data[scope.column.columnname]}}</span>
+        </template>
+        <template v-slot:opreation="scope">
+          <el-button type="text" size="small"
+            @click="goDetail(scope.data)"
+            v-if="tool.checkAuth($route.name,'read') && scope.data.isoverdue == 1">详情</el-button>
+          <el-button type="text" size="small"
+            @click="goEdit(scope.data)"
+            v-else-if="tool.checkAuth($route.name,'update') && scope.data.isoverdue == 0">编辑</el-button>
+        </template>
+      </tableLayout>
+    </div>
+
+  </div>
+</template>
+
+<script>
+import Header from '@/SManagement/archives_upload/components/Header'
+import Search from '@/components/search/index'
+import DownSelect from '@/components/down_select/index'
+import TimeSelect from '@/SManagement/submitedit_one/components/TimeSelect'
+import Pagination from '@/components/pagination/Pagination'
+import { log } from '@antv/g2plot/lib/utils'
+export default {
+  name: '',
+  data () {
+    return {
+      params: {
+        "id": 20220906154403,
+        "version": 1,
+        "content": {
+          "nocache":true,
+          "pageNumber": 1,
+          "pageSize": 12,
+          "where": {
+            "condition": "",
+            
+          }
+        }
+      },
+      /* 销售模板list */
+      salesPanelList: '',
+      /* 当前选中的模板id */
+      selectPanelId: '',
+      /* 提报记录数据 */
+      historyList:'',
+      tablecols: '',
+      tablecols2: '',
+      total:0
+    };
+  },
+  components: { Header, Search, DownSelect, TimeSelect , Pagination},
+  computed: {
+  },
+  watch: {
+  },
+  filters: {
+    timer (val, type) {
+      if (type == '月') {
+        return '每月' + val.substr(1, val.length - 2) + '日'
+      } else {
+        return '每周' + val.substr(1, val.length - 2)
+      }
+    }
+  },
+  created () {
+    this.getSalesPanel()
+    this.tablecols = this.tool.tabelCol(this.$route.name).SalesPanelTable.tablecols
+    this.tablecols2 = this.tool.tabelCol(this.$route.name).salesHistoryTable.tablecols
+  },
+  methods: {
+    /* 获取销售预测模板 */
+    async getSalesPanel () {
+      let res = await this.$api.requested(this.params)
+      this.salesPanelList = res.data
+      this.total = res.total
+      this.selectPanelId = this.salesPanelList[0].sa_salesforecastmodelid
+      this.getSalesDetail()
+      console.log(res);
+    },
+    /* 获取提报记录数据 */
+    async getSalesDetail () {
+      let res = await this.$api.requested({
+        "id": 20220908134403,
+        "version": 1,
+        "content": {
+          "nocache":true,
+          "sa_salesforecastmodelid": this.selectPanelId
+        }
+      })
+      this.historyList = res.data
+      console.log(this.historyList);
+    },
+    async rowClick(data) {
+      let res = await this.$api.requested({
+        "id": 20220908134403,
+        "version": 1,
+        "content": {
+          "sa_salesforecastmodelid": data.sa_salesforecastmodelid
+        }
+      })
+      this.historyList = res.data
+      console.log(this.historyList);
+      
+    },
+    /* 创建提报 */
+    async addBuill(data) {
+      let res = await this.$api.requested({
+        "id": 20220913154403,
+        "version":1,
+        "content": {
+            "sa_salesforecastmodelid":data.data.sa_salesforecastmodelid,
+            "sa_salesforecastbillid":0,
+            "sa_projectids": []
+        }
+      })
+      if(res.code == 0) {
+        this.$notify({
+          title:'提示',
+          message:res.msg,
+          type:'warning'
+        })
+      } else {
+        console.log(res);
+        this.$router.push({path:'/edit_sales',query:{id:res.data[0].sa_salesforecastbillid,id2:data.data.sa_salesforecastmodelid,type:'panel'}})
+      }
+    },
+    /* 前往详情页 */
+    goDetail(data) {
+      if (data.baseonproject == 0) {
+        this.$router.push({path:'/product_detail',query:{id:data.sa_salesforecastbillid}})
+      } else {
+        this.$router.push({path:'/project_detail',query:{id:data.sa_salesforecastbillid}})
+      }
+    },
+    /* 前往编辑页 */
+    goEdit(data) {
+      /* 跳转到产品编辑页 */
+      if(data.baseonproject == 0) {
+        this.$router.push({path:'/edit_sales',query:{id:data.sa_salesforecastbillid,id2:data.sa_salesforecastmodelid,type:'product'}})
+        /* 跳转到项目编辑页 */
+      } else {
+        this.$router.push({path:'/edit_sales',query:{id:data.sa_salesforecastbillid,id2:data.sa_salesforecastmodelid,type:'panel'}})
+      }
+    },
+    pageChange(n) {
+      this.params.content.pageNumber = n
+      this.getSalesPanel()
+    },
+    clearSelect () {
+
+    },
+    timeChange () {
+
+    }
+  },
+};
+</script>
+
+<style scoped>
+.sales .header-handle {
+  display: flex;
+  align-items: center;
+  margin-bottom: 16px;
+}
+</style>

+ 180 - 0
src/SManagement/sales_forecast/modules/editSales.vue

@@ -0,0 +1,180 @@
+<template>
+  <div>
+    <!--模板头部-->
+    <div class="container normal-panel" style="margin-top:16px" v-if="$route.query.type == 'panel'">
+      <p class="normal-title normal-margin">模板信息</p>
+      <el-descriptions :column="3" v-if="detail">
+          <el-descriptions-item label="模板编号">{{detail.billnum?detail.billnum:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="提报要求">
+            <span v-if="detail.baseonproject == '1'">按项目及产品类别预测</span>
+            <span v-else>按产品类别预测</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="提报周期">{{detail.periodpoint | timer(detail.periodtype)}}</el-descriptions-item>
+          <el-descriptions-item label="模板名称">{{detail.title?detail.title:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="提报有效期">{{detail.begdate}}至{{detail.enddate}}</el-descriptions-item>
+          <el-descriptions-item label="备注">暂无</el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <!--提报头部-->
+    <div class="container normal-panel" style="margin-top:16px" v-else>
+      <p class="normal-title normal-margin">基础信息</p>
+      <el-descriptions :column="3" v-if="detail">
+          <el-descriptions-item label="单号">{{detail.billnum?detail.billnum:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="预测模板">{{detail.title?detail.title:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="提报周期">{{detail.periodpoint | timer(detail.periodtype)}}</el-descriptions-item>
+          <el-descriptions-item label="提报要求">
+            <span v-if="detail.baseonproject == '1'">按项目及产品类别预测</span>
+            <span v-else>按产品类别预测</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="提报人">{{detail.createby}}</el-descriptions-item>
+          <el-descriptions-item label="部门">{{detail.depname}}</el-descriptions-item>
+          <el-descriptions-item label="职位">{{detail.position}}</el-descriptions-item>
+          <el-descriptions-item label="提报时间">{{detail.createdate}}</el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">提报内容</p>
+      <div class="handle">
+        <div class="left">
+          <Search />
+          <DownSelect title="提报要求:" :list="[{value:'按产品类别'},{value:'按产品类别 + 项目'}]" style="margin-right:16px" />
+        </div>
+        <div class="right">
+          <add-project @addSuccess="getSubmitList" />
+        </div>
+      </div>
+    </div>
+    <merge-table v-if="list" :layout="tablecols" :custom="true" :data1="list" :endFalse="true">
+      <template v-slot:customcol="scope">
+        <span v-if="scope.column.data[scope.column.columnname]">{{scope.column.data[scope.column.columnname]}}</span>
+        <span v-if="!scope.column.data[scope.column.columnname] && scope.column.columnname != 'product_handle' && scope.column.columnname != 'project_handle'">-</span>
+      </template>
+      <template v-slot:product_handle="scope">
+        <div style="display:flex">
+          <edit :editData="scope.data" :tablecols="addProductTablecols" @editSuccess="getSubmitList" />
+          <delete :rowData="scope.data" :projectid="0" @deleteSuccess="getSubmitList"/>
+        </div>
+      </template>
+      <template v-slot:project_handle="scope">
+        <div style="display:flex">
+          <add-product :data1="scope" :productList="productList" :tablecols="addProductTablecols" @addSuccess="getSubmitList" />
+          <delete :rowData="scope.data" :projectid="scope.data.sa_projectid" @deleteSuccess="getSubmitList" />
+        </div>
+      </template>
+    </merge-table>
+  </div>
+</template>
+
+<script>
+import Search from '@/components/search/index'
+import DownSelect from '@/components/down_select/index'
+import addProject from '../components/addProject'
+import mergeTable from '../components/mergeTable'
+import edit from '../components/edit'
+import Delete from '../components/delete'
+import addProduct from '../components/addProduct'
+export default {
+  name: '',
+  data() {
+    return {
+      id:this.$route.query.id,
+      detail:'',
+      list:'',
+      tablecols:'',
+      /* 添加产品表格 */
+      addProductTablecols:'',
+      productList:''
+    };
+  },
+  components:{Search, DownSelect , addProject , mergeTable , edit , Delete , addProduct},
+  computed:{
+  },
+  watch:{
+  },
+  filters: {
+    timer (val, type) {
+      if (type == '月') {
+        return '每月' + val.substr(1, val.length - 2) + '日'
+      } else {
+        return '每周' + val.substr(1, val.length - 2)
+      }
+    }
+  },
+  created() {
+    this.getHeaderDetail()
+    this.getProductList()
+    this.tablecols = this.tool.tabelCol(this.$route.name).salesEditTable.tablecols
+    this.addProductTablecols = this.tool.tabelCol(this.$route.name).addProductTable.tablecols
+    console.log(this.addProductTablecols);
+    
+  },
+  methods: {
+    /* 获取详情表头数据 */
+    async getHeaderDetail() {
+      let res
+      if(this.$route.query.type == 'panel') {
+        res = await this.$api.requested({
+          "id": 20220906154603,
+          "version":1,
+          "content": {
+              "sa_salesforecastmodelid":this.$route.query.id2
+          }
+        })
+        this.detail = res.data
+      } else {
+        res = await this.$api.requested({
+          "id": 20220914104603,
+          "version":1,
+          "content": {
+              "sa_salesforecastbillid":this.id
+          }
+        })
+        this.detail = res.data[0]
+      }
+      this.getSubmitList()
+      console.log(this.detail);
+    },
+    /* 获取详情提报内容数据 */
+    async getSubmitList() {
+      let res = await this.$api.requested({
+          "id": 20220906154703,
+          "version":1,
+          "content": {
+              "nocache":true,
+              "sa_salesforecastbillid":this.id,
+              "where":{
+                  "condition":""
+              }
+          }
+      })
+      console.log(res.data);
+      
+      res.data[0].sa_projectid ? this.list = res.data : this.list = []
+    },
+    /* 获取所有产品数据 */
+    async getProductList() {
+      let res = await this.$api.requested({
+          "id": 20220906154903,
+          "version":1,
+          "content": {
+          }
+      })
+      this.productList = res.data
+      console.log(this.productList);
+      
+    }
+  },
+};
+</script>
+
+<style scoped>
+  .handle {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+  .handle .left {
+    display: flex;
+    align-items: center;
+  }
+</style>

+ 95 - 0
src/SManagement/sales_forecast/modules/productDetail.vue

@@ -0,0 +1,95 @@
+<template>
+  <div class="detail">
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">基础信息</p>
+      <el-descriptions :column="3" v-if="Object.keys(projectList).length > 0">
+          <el-descriptions-item label="单号">{{projectList[0].billnum?projectList[0].billnum:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="预测模板">{{projectList[0].title?projectList[0].remarks:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="提报周期">{{projectList[0].periodpoint | timer(projectList[0].periodtype)}}</el-descriptions-item>
+          <el-descriptions-item label="提报要求">
+            <span v-if="projectList[0].baseonproject == 1">按项目及产品类别预测</span>
+            <span v-else>按产品类别预测</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="提报人">{{projectList[0]?projectList[0].createby : '未知'}}</el-descriptions-item>
+          <el-descriptions-item label="部门">{{projectList[0]?projectList[0].depname:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="职位">{{projectList[0]?projectList[0].position:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="提报时间">{{projectList[0]?projectList[0].title:'未知'}}</el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">提报内容</p>
+      <div class="handle">
+        <div class="left">
+          <Search />
+          <DownSelect title="提报要求:" :list="[{value:'按产品类别'},{value:'按产品类别 + 项目'}]" style="margin-right:16px" />
+        </div>
+      </div>
+      <tableLayout v-if="projectList" :layout="tablecols" :custom="false" :data="projectList">
+      </tableLayout>
+    </div>
+  </div>
+</template>
+
+<script>
+import Search from '@/components/search/index'
+import DownSelect from '@/components/down_select/index'
+export default {
+  name: 'historyDetail',
+  data() {
+    return {
+      id:this.$route.query.id,
+      detail:'',
+      tablecols:'',
+      projectList:''
+    };
+  },
+  components:{Search,DownSelect},
+  computed:{
+  },
+  filters: {
+    timer (val, type) {
+      if (type == '月') {
+        return '每月' + val.substr(1, val.length - 2) + '日'
+      } else {
+        return '每周' + val.substr(1, val.length - 2)
+      }
+    }
+  },
+  watch:{
+  },
+  created() {
+    this.getDetail()
+    this.tablecols = this.tool.tabelCol(this.$route.name).salesEditTable.tablecols.splice(0,8)
+  },
+  methods: {
+    async getDetail() {
+      let res = await this.$api.requested({
+        "id": 20220906154703,
+        "version":1,
+        "content": {
+            "sa_salesforecastbillid":this.id,
+            "where":{
+                "condition":""
+            }
+        }
+      })
+      this.projectList = res.data
+      console.log(this.projectList);
+      
+    }
+  },
+};
+</script>
+
+<style scoped>
+  .handle {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 16px;
+  }
+  .handle .left {
+    display: flex;
+    align-items: center;
+  }
+</style>

+ 96 - 0
src/SManagement/sales_forecast/modules/projectDetail.vue

@@ -0,0 +1,96 @@
+<template>
+  <div class="detail">
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">基础信息</p>
+      <el-descriptions :column="3" v-if="projectList">
+          <el-descriptions-item label="单号">{{projectList[0].billnum?projectList[0].billnum:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="预测模板">{{projectList[0].title?projectList[0].remarks:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="提报周期">{{projectList[0].periodpoint | timer(projectList[0].periodtype)}}</el-descriptions-item>
+          <el-descriptions-item label="提报要求">
+            <span v-if="projectList[0].baseonproject == 1">按项目及产品类别预测</span>
+            <span v-else>按产品类别预测</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="提报人">{{projectList[0]?projectList[0].createby : '未知'}}</el-descriptions-item>
+          <el-descriptions-item label="部门">{{projectList[0]?projectList[0].depname:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="职位">{{projectList[0]?projectList[0].position:'未知'}}</el-descriptions-item>
+          <el-descriptions-item label="提报时间">{{projectList[0]?projectList[0].title:'未知'}}</el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <div class="container normal-panel" style="margin-top:16px">
+      <p class="normal-title normal-margin">提报内容</p>
+      <div class="handle">
+        <div class="left">
+          <Search />
+          <DownSelect title="提报要求:" :list="[{value:'按产品类别'},{value:'按产品类别 + 项目'}]" style="margin-right:16px" />
+        </div>
+      </div>
+      <merge-table v-if="projectList" :layout="tablecols" :custom="false" :data1="projectList" :endFalse="false">
+      </merge-table>
+    </div>
+  </div>
+</template>
+
+<script>
+import Search from '@/components/search/index'
+import DownSelect from '@/components/down_select/index'
+import mergeTable from '../components/mergeTable'
+export default {
+  name: 'historyDetail',
+  data() {
+    return {
+      id:this.$route.query.id,
+      detail:'',
+      tablecols:'',
+      projectList:''
+    };
+  },
+  components:{Search,DownSelect,mergeTable},
+  computed:{
+  },
+  filters: {
+    timer (val, type) {
+      if (type == '月') {
+        return '每月' + val.substr(1, val.length - 2) + '日'
+      } else {
+        return '每周' + val.substr(1, val.length - 2)
+      }
+    }
+  },
+  watch:{
+  },
+  created() {
+    this.getDetail()
+    this.tablecols = this.tool.tabelCol(this.$route.name).salesEditTable.tablecols.splice(0,8)
+  },
+  methods: {
+    async getDetail() {
+      let res = await this.$api.requested({
+        "id": 20220906154703,
+        "version":1,
+        "content": {
+            "sa_salesforecastbillid":this.id,
+            "where":{
+                "condition":""
+            }
+        }
+      })
+      this.projectList = res.data
+      console.log(res);
+      
+    }
+  },
+};
+</script>
+
+<style scoped>
+  .handle {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 16px;
+  }
+  .handle .left {
+    display: flex;
+    align-items: center;
+  }
+</style>

+ 4 - 1
src/SManagement/submitedit_one/components/TimeSelect.vue

@@ -1,11 +1,13 @@
 <template>
   <div>
+    <span style="font-size:14px;margin-right:16px">{{title && title}}</span>
     <el-date-picker
       v-model="time"
       type="daterange"
       start-placeholder="开始日期"
       end-placeholder="结束日期"
-      @change="timeChange">
+      @change="timeChange"
+      size="small">
     </el-date-picker>
   </div>
 </template>
@@ -20,6 +22,7 @@ export default {
       time:''
     };
   },
+  props: ['title'],
   computed:{
   },
   watch:{

BIN
src/assets/sales.png


+ 49 - 0
src/components/down_select/index.vue

@@ -0,0 +1,49 @@
+<template>
+  <div class="select1">
+    <p>{{title}}</p>
+    <el-select v-model="result" clearable placeholder="请选择" size="small" @change="change" width="100px">
+      <el-option
+        v-for="item in list"
+        :key="item.value"
+        :label="item.label"
+        :value="item.value">
+      </el-option>
+    </el-select>
+  </div>
+</template>
+
+<script>
+export default {
+  name: '',
+  data() {
+    return {
+      result:''
+    };
+  },
+  props:['title','list'],
+  computed:{
+  },
+  watch:{
+  },
+  methods: {
+    change() {
+      this.$emit('selectChange',this.result)
+    }
+  },
+};
+</script>
+
+<style scoped>
+  .select1 {
+    display: flex;
+    align-items: center;
+  }
+  p {
+    margin-right: 8px;
+    font-size: 14px;
+    color: #666666;
+  }
+  /deep/.el-select {
+    width: 150px !important;
+  }
+</style>

+ 2 - 2
src/components/table/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <el-table :row-class-name="tableClassName" v-loading="loading" highlight-current-row :data="data" :header-cell-style="{background:'#EEEEEE',color:'#333'}" size="mini" :height="height" @row-click="rowClick" style="width:100%" @selection-change="handleSelectionChange"  border>
+    <el-table ref="tables" :row-class-name="tableClassName" v-loading="loading" highlight-current-row :data="data" :header-cell-style="{background:'#EEEEEE',color:'#333'}" size="mini" :height="height" @row-click="rowClick" style="width:100%" @selection-change="handleSelectionChange"  border>
       <el-table-column
         type="selection"
         width="55" @handleSelectionChange="handleSelectionChange" v-if="checkbox" :selectable="isCheck">
@@ -51,7 +51,7 @@ export default {
     },
     isCheck(row,rowIndex) {
       if (!row.status) return true
-      if(row.status == '待跟进' || row.status == '跟进中') {
+      if(row.status == '待跟进' || row.status == '跟进中' || row.projectnum) {
         return true
       } else {
         return false

+ 90 - 0
src/router/SManagement.js

@@ -162,6 +162,96 @@ const SManagement = [{
     keeproute:true
   },
   component: () => import(/* webpackChunkName: "about" */ '@/SManagement/orderclue_detail/index')
+},
+{
+  path: '/sm_projectTarget',
+  name: 'projectTarget',
+  meta: {
+    title: '我的项目目标',
+    ast_nav: true,
+    keeproute:true
+  },
+  component: () => import(/* webpackChunkName: "about" */ '@/SManagement/project_target/index')
+},
+{
+  path: '/editProjectInfo',
+  name: 'projectTarget',
+  meta: {
+    title: '编辑项目目标',
+    ast_nav: true,
+    keeproute:true
+  },
+  component: () => import(/* webpackChunkName: "about" */ '@/SManagement/project_target/modules/editInfo')
+},
+{
+  path: '/projectDetail',
+  name: 'projectTarget',
+  meta: {
+    title: '项目详情',
+    ast_nav: true,
+    keeproute:true
+  },
+  component: () => import(/* webpackChunkName: "about" */ '@/SManagement/project_target/modules/detailInfo')
+},
+{
+  path: '/sm_personalTarget',
+  name: 'smPersonalTarget',
+  meta: {
+    title: '我的人员目标',
+    ast_nav: true,
+    keeproute:true
+  },
+  component: () => import(/* webpackChunkName: "about" */ '@/SManagement/personal_target/index')
+},
+{
+  path: '/PersonalDetail',
+  name: 'smPersonalTarget',
+  meta: {
+    title: '人员目标详情',
+    ast_nav: true,
+    keeproute:true
+  },
+  component: () => import(/* webpackChunkName: "about" */ '@/SManagement/personal_target/modules/detail')
+},
+{
+  path: '/sm_sales_forecast',
+  name: 'salesForecast',
+  meta: {
+    title: '销售预测',
+    ast_nav: true,
+    keeproute:true
+  },
+  component: () => import(/* webpackChunkName: "about" */ '@/SManagement/sales_forecast/index')
+},
+{
+  path: '/edit_sales',
+  name: 'salesForecast',
+  meta: {
+    title: '产品项目编辑',
+    ast_nav: true,
+    keeproute:true
+  },
+  component: () => import(/* webpackChunkName: "about" */ '@/SManagement/sales_forecast/modules/editSales')
+},
+{
+  path: '/project_detail',
+  name: 'salesForecast',
+  meta: {
+    title: '产品项目详情',
+    ast_nav: true,
+    keeproute:true
+  },
+  component: () => import(/* webpackChunkName: "about" */ '@/SManagement/sales_forecast/modules/projectDetail')
+},
+{
+  path: '/product_detail',
+  name: 'salesForecast',
+  meta: {
+    title: '产品类别详情',
+    ast_nav: true,
+    keeproute:true
+  },
+  component: () => import(/* webpackChunkName: "about" */ '@/SManagement/sales_forecast/modules/productDetail')
 }
 ]
 export default SManagement

+ 2 - 2
src/store/index.js

@@ -15,7 +15,7 @@ export default new Vuex.Store({
     deplist:[],
     sys_options:[],
     shortcutlist:[],
-    active_modules:{}
+    active_modules:{},
   },
   getters: {
     siteinfo:state => state.siteinfo,
@@ -24,7 +24,7 @@ export default new Vuex.Store({
     sys_options:state => state.sys_options,
     pageOnlyRead:state => state.pageOnlyRead,
     shortcutlist:state => state.shortcutlist,
-    active_modules:state => state.active_modules
+    active_modules:state => state.active_modules,
   },
   mutations: {
     setSiteInfo(state,res) {