Browse Source

feat:需求订单

snow 1 year ago
parent
commit
ea81b29b97
26 changed files with 557 additions and 287 deletions
  1. 2 1
      src/apis/components/letter.js
  2. 1 0
      src/apis/components/search.js
  3. 2 0
      src/apis/service/customerService/workbench/index.js
  4. 15 10
      src/components/manage/src/letter/_columns.js
  5. 7 1
      src/components/manage/src/letter/_template.js
  6. 72 23
      src/components/manage/src/letter/index.vue
  7. 32 15
      src/components/manage/src/letter/xlsxUploadModal.vue
  8. 3 1
      src/components/search/index.js
  9. 60 0
      src/components/search/src/category.vue
  10. 1 1
      src/views/customerService/demandOrder/components/demandDetail/requsetPerpaymentModal.vue
  11. 1 1
      src/views/customerService/demandOrder/components/demandDetail/uploadCertificateModal.vue
  12. 20 8
      src/views/customerService/demandOrder/components/manageActivityScheme.vue
  13. 14 2
      src/views/customerService/demandOrder/components/manageBudgetLetter.vue
  14. 19 8
      src/views/customerService/demandOrder/components/manageProjectLetter.vue
  15. 5 0
      src/views/customerService/demandOrder/detail.vue
  16. 19 24
      src/views/customerService/demandOrder/index.vue
  17. 7 7
      src/views/customerService/invoiceApply/columns.js
  18. 21 18
      src/views/customerService/invoiceApply/components/createInvoiceApply.vue
  19. 31 5
      src/views/customerService/invoiceApply/components/demandModal.vue
  20. 8 18
      src/views/customerService/invoiceApply/detail.vue
  21. 20 25
      src/views/customerService/invoiceApply/index.vue
  22. 8 1
      src/views/customerService/workbench/_template.js
  23. 52 20
      src/views/customerService/workbench/detail.vue
  24. 36 34
      src/views/customerService/workbench/index.vue
  25. 44 44
      src/views/customerService/workbench/letterEditing.vue
  26. 57 20
      src/views/customerService/workbench/modal.vue

+ 2 - 1
src/apis/components/letter.js

@@ -4,6 +4,7 @@ export default {
   // 列表
   list: (data, params) => http(api + 'list', data, 'post', params),
   delete: (data, params) => http(api + 'delete', data, 'post', params),
-  detail: (data, params) => http(api + 'info', data, 'post', params)
+  detail: (data, params) => http(api + 'info', data, 'post', params),
+  create: (data, params) => http(api + 'create', data, 'post', params),
 }
 

+ 1 - 0
src/apis/components/search.js

@@ -8,4 +8,5 @@ export default {
     title: (data, params) => http("admin/invoiceTitle/index", data, "post", params),
     actType: (data, params) => http("admin/activityCat/index", data, "post", params),
     peoNum: (data, params) => http("admin/attendance/index", data, "post", params),
+    category: (data, params) => http("admin/serviceCat/query", data, "post", params),
 };

+ 2 - 0
src/apis/service/customerService/workbench/index.js

@@ -21,6 +21,8 @@ export default {
   planDelete:(data, params) => http(planAPI + 'deleteinfo', data, 'post', params),
   planUpdate:(data, params) => http(planAPI + 'save', data, 'post', params),
 
+  planUpdateInfo:(data, params) => http(planAPI + 'updateinfo', data, 'post', params),
+
   // 采返商品详情
   good_detail: (data, params) =>
     http(api + 'consultfeadinfo', data, 'post', params),

+ 15 - 10
src/components/manage/src/letter/_columns.js

@@ -2,7 +2,7 @@ const mapFields = {
   letterNo:'planCode', //评估预算函编号
   status:'status',  // 状态
   letter:'plan_file', //评估预算函
-  budgetAmount:'plan_total_price', //评估预算金额
+  budgetAmount:'pay_total_price', //评估预算金额
   supplierStoreName:'store_name', //供应商店铺名称
   supplierCompanyName:'supplierName', //供应商公司名称
   creator:'nickname', //创建人
@@ -29,7 +29,7 @@ export const budget = [
   {
       prop: mapFields.letter,
       label: '评估预算函',
-      width: '156px',
+      width: '126px',
       _slot_:'letter'
   },
   {
@@ -79,7 +79,7 @@ export const activity = [
     {
         prop: mapFields.letter,
         label: '活动方案预览',
-        width: '156px',
+        width: '126px',
         _slot_:'letter'
     },
     // {
@@ -129,7 +129,7 @@ export const project = [
     {
         prop: mapFields.letter,
         label: '计划预算函预览',
-        width: '156px',
+        width: '126px',
         _slot_:'letter'
     },
     {
@@ -173,7 +173,8 @@ export const settlement = [
     {
         prop: mapFields.letter,
         label: '评估预算函',
-        width: '156px',
+        width: '126px',
+        _slot_:'letter'
     },
     {
         prop: mapFields.budgetAmount,
@@ -216,13 +217,17 @@ const mapCheck = {
       no:0
     },
     activity:{
-      ok:2,
-      no:1
+      ok:1,
+      no:0
     },
     project:{
-      ok:3,
-      no:2
-    }
+      ok:1,
+      no:0
+    },
+    settlement:{
+        ok:1,
+        no:0
+      }
 }
 
 const mapTitle = {

+ 7 - 1
src/components/manage/src/letter/_template.js

@@ -131,4 +131,10 @@ const mapFields = {
     // mapFields.nonTaxQuotes,
     // mapFields.taxIncludedQuote
   ]
-  
+  
+
+  export const mapLetterToType = {
+    budget:1,
+    activity:2,
+    project:3
+  }

+ 72 - 23
src/components/manage/src/letter/index.vue

@@ -1,9 +1,11 @@
 <template>
   <div>
     <div style="display:flex;justify-content:flex-end" v-if="!readonly">
-      <el-button size="mini" @click="onDownloadTemplate">下载{{mapTitle[type]}}模板</el-button>
+      <el-button size="mini" @click="onUpdateLetter(false)" v-if="type === 'project'">编辑预算函</el-button>
+      <el-button size="mini" @click="onDownloadTemplate" v-if="type !== 'activity'">下载{{mapTitle[type]}}模板</el-button>
       <el-button size="mini" type="primary" @click="handleUploadModalVisible">上传{{mapTitle[type]}}</el-button>
     </div>
+
     <ex-table
       :columns="[
         ...(isSelection ? [{ type: 'selection' }] : []),
@@ -27,14 +29,22 @@
       :data="tableData"
       style="margin: 15px 0 0 0"
     >
+
+      <template #letter="{scope}">
+        <a v-if="scope.row.plan_file" :href="scope.row.plan_file">{{getFileNameWithUrl(scope.row.plan_file)}}</a>
+        <p v-else>--</p>
+      </template>
+      
       <template #is_check="{scope}">
         <el-tag size="mini" :type="Number(scope.row.is_check) === mapCheck[type || 'budget'].ok ? '' :'info'">
          {{ Number(scope.row.is_check) === mapCheck[type || 'budget'].ok  ?  "已选择" : "未选择" }}
         </el-tag>
       </template>
+
       <template #action="{ scope }">
+        <!-- type === 'budget' && -->
         <el-button 
-          v-if="type === 'budget' && Number(scope.row.is_check) !== mapCheck[type].ok" type="text" 
+          v-if="(Number(scope.row.is_check) !== mapCheck[type].ok)" type="text" 
           size="mini" 
           @click="linkToLetterUpdate(scope.row)"
         >编辑</el-button>
@@ -52,6 +62,7 @@
       :visible.sync="xlsxVisible"
       @submit="handleSubmit"
       @refresh="refresh"
+      @activitySubmit="file => onUpdateLetter(file)"
       :isFile="isFile"
       :title="title" 
       :type="type"
@@ -71,14 +82,14 @@ import ExcelUploadModal from "./xlsxUploadModal.vue"
 import asyncRequest from "@/apis/components/letter"
 import PreviewModal from "./previewModal.vue"
 import { writeFile, utils } from "xlsx";
-import { template } from "./_template"
+import { template ,mapLetterToType } from "./_template"
 import mixinPage from "@/mixins/elPaginationHandle";
 
 export default {
   name:'Letter',
   mixins:[mixinPage],
-  /* type:budget预算函 activity活动方案 project计划 **/
-  props:['title', 'requsetMethod', 'status', 'id', 'isSelection', 'readonly','type', 'beforeModalVisible', 'isFile'],
+  /* type:budget预算函  activity活动方案  project计划 **/
+  props:['title', 'requsetMethod', 'status', 'id', 'isSelection', 'readonly','type', 'beforeModalVisible', 'isFile', 'updateLoading'],
   components:{ ExcelUploadModal, PreviewModal },
   data(){
     return {
@@ -106,15 +117,57 @@ export default {
     }
   },
   watch:{
-    id(val){
-      if(!val) return
-      this.searchList()
+    id:{
+      handler(val){
+        if(!val) return
+        this.searchList()
+      },
+      immediate:true
     }
   },
-  // mounted(){
-    // this.searchList()
-  // },
   methods:{
+    async onUpdateLetter(fileUrl){
+      if(this.beforeModalVisible && !this.beforeModalVisible()){
+        return
+      }
+
+      this.updateLoading(true)
+      const { form, id } = this.beforeModalVisible()
+      const { code, data } = await asyncRequest.detail({id})
+      
+      if(code !== 1) {
+        this.updateLoading(false)
+        return
+      }
+
+      const { planinfo = [], req_id, store_id, plan_file } = data;
+
+      console.log(fileUrl, plan_file)
+
+      const plan_info =  planinfo.map(
+        ({ name, service_cat, price, unit, num, tax}) =>
+        ({ name, service_cat, price, unit, num, tax })
+      )
+
+      const letter = await asyncRequest.create({
+        plan_type: mapLetterToType[form],
+        file: fileUrl ? fileUrl : plan_file,
+        plan_info,
+        store_id,
+        req_id
+      })
+
+      this.updateLoading(false)
+
+      if(fileUrl){
+        this.searchList()
+        return
+      }
+
+      if(letter.code !== 1) return
+      //创建获取获取新id进入编辑页...
+      this.$router.push(`/customerService/letterEditing?id=${letter.data.id}&from=${form}&type=create`)
+    },
     refresh(){
       this.searchList()
       this.$emit('refresh')
@@ -155,28 +208,24 @@ export default {
       return (fileName.length > 10 ? fileName[0] + fileName[1]  + '...' + fileName[fileName.length -1] : fileName) + '.' + suffix
     },
     handleUploadModalVisible(){
-      if(this.beforeModalVisible && !this.beforeModalVisible()){
+      if((this.beforeModalVisible && !this.beforeModalVisible()) && this.type !== 'project'){
         return
       }
-
       this.xlsxVisible = true
     },
-    // linkToLetterUpdate(){
-    //   // if(this.beforeModalVisible && !this.beforeModalVisible()){
-    //   //   return
-    //   // }
-    //   this.$emit('updateLetter')
-    // },
+
     async searchList(){
-      if(this.type === 'settlement') return
+      // if(this.type === 'settlement') return
       this.loading = true
-      const { code, data } = await asyncRequest.list({ status:this.status, req_id: this.id ,...this.parmValue})
+      const { code, data } = await asyncRequest.list({ 
+          plan_type :this.status,          
+          req_id: this.id ,
+          ...this.parmValue
+        })
       this.loading = false
       if(code !== 1) return
       this.tableData = data.list
       this.pageInfo.total = Number(data.count)
-
-      console.log(this.pageInfo)
     }
   }
 }

+ 32 - 15
src/components/manage/src/letter/xlsxUploadModal.vue

@@ -1,18 +1,25 @@
 <template>
   <el-dialog :title="`上传${mapTitle[type]}方案`" :close-on-click-modal="false" :visible="innerVisible" width="1024px" @close="handleClose" center>
 
+
+   <div style="display:flex;">
+    <div style="display:flex;align-items:center;margin-right:10px" v-if="type === 'budget' || type === 'project'">
+      <p style="margin-right:10px">店铺:</p>
+      <search-store size="mini" :value.sync="storeId" />
+    </div>
+
     <div v-if="file_url && isFile" style="margin-left:20px">
-      <a :href="file_url">点击下载</a>
-      <el-link
-        :underline="false"
-        @click="deleteUrl('3')"
-        type="warning"
-        style="margin: 0 0 0 16px"
-        >删除</el-link
-      >
+       <a :href="file_url">点击下载</a>
+       <el-link
+         :underline="false"
+         @click="deleteUrl('3')"
+         type="warning"
+         style="margin: 0 0 0 16px"
+         >删除</el-link
+       >
     </div>
 
-    <div class="activity-upload" v-if="!file_url && isFile">
+    <div class="activity-upload" v-if="!file_url && isFile" style="margin:0">
       <div class="btnupload" style="position: relative">
         <i class="el-icon-plus avatar-uploader-icon"></i>
         <file-upload-pdf
@@ -29,20 +36,17 @@
         <p>文件格式:.xlsx,.xls,.pdf,.zip,.rar,.7z</p>
       </div>
     </div>
-
-    <div style="display:flex;align-items:center;margin:10px 0px" v-if="type === 'budget'">
-      <p style="margin-right:10px">店铺:</p>
-      <search-store size="mini" :value.sync="storeId" />
-    </div>
+   </div>
          
 
-    <div style="padding:10px" v-loading="loading">
+    <div style="padding:10px" v-loading="loading"  v-if="type !== 'activity'">
      <div v-if="tableData && tableData.length > 0" class="tr" style="padding: 10px 0 0 0">
       <el-button :size="'mini'" @click="() => tableData = []">取消</el-button>
       <el-button type="primary" :size="'mini'" @click="onSubmit">{{
         type === 'settlement' ? '保存' : '提交'  
       }}</el-button>
       </div>
+
       <div v-else>
         <upload-excel :on-success="onSuccess" :before-upload="beforeUpload" />
       </div>
@@ -55,6 +59,10 @@
         style="margin: 15px 0 0 0"
       />
     </div>
+
+    <div class="flex-end" v-else>
+      <el-button  type="primary" :size="'mini'" @click="onActivitySubmit">提交</el-button>
+    </div>
   </el-dialog>
 </template>
 
@@ -219,6 +227,15 @@ export default {
       })
       this.validateFields(this.tableData)
     },
+    onActivitySubmit(){
+      if(this.isFile && !this.file_url){
+        this.$message.warning('请上传文件!')
+        return
+      }
+
+      this.$emit("activitySubmit", this.file_url)
+      this.visible = false
+    },
     async onSubmit() {
       if(!this.validateFields(this.tableData)){
         return

+ 3 - 1
src/components/search/index.js

@@ -5,6 +5,7 @@ import SearchTitle from "./src/title.vue"
 import SearchActivityType from "./src/activity-type"
 import SearchPeopleNumber from "./src/people-number"
 import SearchAddr from "./src/addr"
+import SearchCategory from "./src/category"
 
 const searchComponents = [
   SearchStore,
@@ -13,7 +14,8 @@ const searchComponents = [
   SearchTitle,
   SearchActivityType,
   SearchAddr,
-  SearchPeopleNumber
+  SearchPeopleNumber,
+  SearchCategory
 ]
 
 export default searchComponents

+ 60 - 0
src/components/search/src/category.vue

@@ -0,0 +1,60 @@
+<template>
+  <el-select
+    v-model="_value"
+    :size="size" 
+    remote
+    :remote-method="onFetch"
+    :placeholder="placeholder || '请选择服务分类'"
+    :loading="loading"
+    reserve-keyword
+    filterable
+    clearable
+  >
+    <el-option 
+      v-for="item in list" 
+      :key="item.id" 
+      :value="item.id" 
+      :label="item.cat_name"
+    />
+  </el-select>
+</template>
+
+
+<script>
+import asyncRequest from "@/apis/components/search"
+export default {
+  name:'SearchCategory',
+  props:['size', 'value', 'placeholder', 'level'],
+  data(){
+    return {
+      loading: false,
+      list: []
+    }
+  },
+  computed:{
+    _value:{
+        get(){
+          return this.value
+        },
+        set(newVal){
+          const current = this.list.find(({id}) => id === newVal)
+          this.$emit('change', current)
+          this.$emit('update:value', newVal)
+        }
+    }
+  },
+  methods:{
+    async onFetch(cat_name = ""){
+      const { code, data } = await asyncRequest.category({ cat_name })
+      if(code !== 1) return
+      this.list = data
+    },
+    async init(id){
+      const { code, data } = await asyncRequest.category({})
+      if(code !== 1) return
+      this.list = data || []
+      this._value = id
+    }
+  }
+}
+</script>

+ 1 - 1
src/views/customerService/demandOrder/components/demandDetail/requsetPerpaymentModal.vue

@@ -93,7 +93,7 @@ export default {
           ...this.ruleForm
         })
         if(code !== 1) return
-        this._visible = false
+        this.innerVisible = false
         this.$emit("refresh")
       }catch(err){
         console.log(err)

+ 1 - 1
src/views/customerService/demandOrder/components/demandDetail/uploadCertificateModal.vue

@@ -104,7 +104,7 @@ export default {
         },
         async onSubmit({amount:prepay_amount,credentials:prepay_image}){
           this.loading = true
-          const { code } = await asyncRequest.prepayOrder({ id: this.sitem.id, prepay_amount, prepay_image })
+          const { code } = await asyncRequest.prepayOrder({ id: this.sitem.id, prepay_amount, prepay_image:prepay_image.join(',') })
           this.loading = false
           if(code !== 1) return
           this.innerVisible = false

+ 20 - 8
src/views/customerService/demandOrder/components/manageActivityScheme.vue

@@ -10,14 +10,19 @@
       @page-size-change="handleSizeChange"
     >
       <template #is_check="{scope}">
-        <el-tag size="mini" :type="String(scope.row.is_check) === '2' ? '' :'info'">
-         {{String(scope.row.is_check) === "2" ?  "已选择" : "未选择"}}
+        <el-tag size="mini" :type="String(scope.row.is_check) === '1' ? '' :'info'">
+         {{String(scope.row.is_check) === "1" ?  "已选择" : "未选择"}}
         </el-tag>
       </template>
 
+      <template #letter="{scope}">
+        <a style="color:#409EFF" :href="scope.row.plan_file">{{getFileNameWithUrl(scope.row.plan_file)}}</a>
+      </template>
+      
+
       <template #action="{scope}">
         <el-button size="mini" type="text" @click="handleCheck(scope.row)">{{
-          String(scope.row.is_check) === "2" ?  "取消选择" : "选择"
+          String(scope.row.is_check) === "1" ?  "取消选择" : "选择"
           }}</el-button>
       </template>
     </ex-table>
@@ -64,10 +69,11 @@ export default {
        {
            prop: "plan_file",
            label: '活动方案预览',
-           minWidth: '156px',
+           minWidth: '126px',
+           _slot_:'letter'
        },
        {
-           prop: "plan_total_price",
+           prop: "pay_total_price",
            label: '评估预算金额',
            minWidth: '180px',
        },
@@ -108,21 +114,27 @@ export default {
   methods:{
     async handleCheck(row){
       const { id, is_check } = row
-      const status = String(is_check) === "2" ? "1" : "2"
+      const status = String(is_check) === "1" ? "0" : "1"
       const result = await asyncRequest.planCheck({ id:[id], req_id: this.sitem.id, status})
       if(result.code === 1){
         this.searchList()
       }
     },
+    getFileNameWithUrl(url){
+      const chunks = url.split('/')
+      const fullFileName = chunks[chunks.length - 1]
+      const [ fileName, suffix ] = fullFileName.split('.')
+      return (fileName.length > 10 ? fileName[0] + fileName[1]  + '...' + fileName[fileName.length -1] : fileName) + '.' + suffix
+    },
     async searchList(id){
       this.loading = true
-      const { code, data }  = await asyncRequest.planList({ req_id: id ? id :this.sitem.id, status: 2 })
+      const { code, data }  = await asyncRequest.planList({ req_id: id ? id :this.sitem.id, plan_type: 2 })
       this.loading = false
 
       if(code === 1){
         const { list = [], count = 0 } = data
         this.planList = list;
-        this.$emit('selectedChange',list.filter(({is_check}) => String(is_check) === "2").length)
+        this.$emit('selectedChange',list.filter(({is_check}) => String(is_check) === "1").length)
         this.pageInfo.total = count
       }
     }

+ 14 - 2
src/views/customerService/demandOrder/components/manageBudgetLetter.vue

@@ -15,6 +15,11 @@
         </el-tag>
       </template>
 
+      <template #letter="{scope}">
+        <a style="color:#409EFF" :href="scope.row.plan_file">{{getFileNameWithUrl(scope.row.plan_file)}}</a>
+      </template>
+      
+
       <template #action="{scope}">
         <el-button size="mini" type="text" @click="handleCheck(scope.row)">{{
           String(scope.row.is_check) === "1" ?  "取消选择" : "选择"
@@ -64,10 +69,11 @@ export default {
        {
            prop: "plan_file",
            label: '评估预算函',
-           minWidth: '156px',
+           minWidth: '126px',
+           _slot_:'letter'
        },
        {
-           prop: "plan_total_price",
+           prop: "pay_total_price",
            label: '评估预算金额',
            minWidth: '180px',
        },
@@ -118,6 +124,12 @@ export default {
       if(result.code !== 1) return
       this.searchList()
     },
+    getFileNameWithUrl(url){
+      const chunks = url.split('/')
+      const fullFileName = chunks[chunks.length - 1]
+      const [ fileName, suffix ] = fullFileName.split('.')
+      return (fileName.length > 10 ? fileName[0] + fileName[1]  + '...' + fileName[fileName.length -1] : fileName) + '.' + suffix
+    },
     async searchList(id){
       this.loading = true
       const { code, data }  = await asyncRequest.planList({ req_id: id ? id : this.sitem.id })

+ 19 - 8
src/views/customerService/demandOrder/components/manageProjectLetter.vue

@@ -10,14 +10,18 @@
       @page-size-change="handleSizeChange"
     >
       <template #is_check="{scope}">
-        <el-tag size="mini" :type="String(scope.row.is_check) === '3' ? '' :'info'">
-         {{String(scope.row.is_check) === "3" ?  "已选择" : "未选择"}}
+        <el-tag size="mini" :type="String(scope.row.is_check) === '1' ? '' :'info'">
+         {{String(scope.row.is_check) === "1" ?  "已选择" : "未选择"}}
         </el-tag>
       </template>
 
+      <template #letter="{scope}">
+        <a style="color:#409EFF" :href="scope.row.plan_file">{{getFileNameWithUrl(scope.row.plan_file)}}</a>
+      </template>
+
       <template #action="{scope}">
         <el-button size="mini" type="text" @click="handleCheck(scope.row)">{{
-          String(scope.row.is_check) === "3" ?  "取消选择" : "选择"
+          String(scope.row.is_check) === "1" ?  "取消选择" : "选择"
           }}</el-button>
       </template>
     </ex-table>
@@ -64,10 +68,11 @@ export default {
        {
            prop: "plan_file",
            label: '计划预算函预览',
-           minWidth: '156px',
+           minWidth: '126px',
+           _slot_:'letter'
        },
        {
-           prop: "plan_total_price",
+           prop: "pay_total_price",
            label: '计划预算函金额',
            minWidth: '180px',
        },
@@ -113,21 +118,27 @@ export default {
   methods:{
     async handleCheck(row){
       const { id, is_check } = row
-      const status = String(is_check) === "3" ? "2" : "3"
+      const status = String(is_check) === "1" ? "0" : "1"
       const result = await asyncRequest.planCheck({ id:[id], req_id: this.sitem.id, status})
       if(result.code === 1){
         this.searchList()
       }
     },
+    getFileNameWithUrl(url){
+      const chunks = url.split('/')
+      const fullFileName = chunks[chunks.length - 1]
+      const [ fileName, suffix ] = fullFileName.split('.')
+      return (fileName.length > 10 ? fileName[0] + fileName[1]  + '...' + fileName[fileName.length -1] : fileName) + '.' + suffix
+    },
     async searchList(id){
       this.loading = true
-      const { code, data }  = await asyncRequest.planList({ req_id: id ? id :this.sitem.id, status: 3 })
+      const { code, data }  = await asyncRequest.planList({ req_id: id ? id :this.sitem.id, plan_type: 3 })
       this.loading = false
 
       if(code !== 1) return
       const { list = [], count = 0 } = data
       this.planList = list;
-      this.$emit('selectedChange',list.filter(({is_check}) => String(is_check) === "3").length)
+      this.$emit('selectedChange',list.filter(({is_check}) => String(is_check) === "1").length)
       this.pageInfo.total = count
     }
   }

+ 5 - 0
src/views/customerService/demandOrder/detail.vue

@@ -30,7 +30,12 @@
            </el-collapse-item> 
            <el-collapse-item title="待供应商上传结算函" name="8" v-if="Number(sitem.status) === 9">
              <letter type="settlement" :requsetMethod="handleUploadLetter" :isFile="true" />
+           </el-collapse-item>
+
+          <el-collapse-item title="结算函" name="8" v-if="Number(sitem.status) > 9">
+             <letter :id="sitem.id" type="settlement" status="4" :requsetMethod="handleUploadLetter" :isFile="true" :readonly="true" />
            </el-collapse-item> 
+
            <el-collapse-item title="待客户确认结算函" name="9" v-if="Number(sitem.status) === 10">
              <normal-node @confirm="handleConfirmSettlement" />
            </el-collapse-item>

+ 19 - 24
src/views/customerService/demandOrder/index.vue

@@ -38,12 +38,21 @@
               </el-col>
 
               <el-col :span="4">
-                <search-people-number style="width:100%" size="mini" :data.sync="parmValue.activityPerson" placeholder="活动人数"  @change="
+                <search-people-number style="width:100%" size="mini" :value.sync="parmValue.activityPerson" placeholder="活动人数"  @change="
                   pageInfo.curr = 1;
                   parmValue.page = 1;
                   searchList();
                 " />
               </el-col>
+
+              <el-col :span="4" style="margin-left:10px">
+                <search-customer style="width:100%" size="mini" placeholder="需求公司" :value.sync="parmValue.demandEnterprises" @change="
+                  pageInfo.curr = 1;
+                  parmValue.page = 1;
+                  searchList();
+                  " 
+                />
+              </el-col>
                             
               <el-col :span="3" style="width: 66px; float: right">
                 <el-button
@@ -103,7 +112,7 @@
             </el-row>
 
             <el-row style="margin-top:10px">
-              <el-col :span="4" style="width: 341px;">
+              <!-- <el-col :span="4" style="width: 341px;">
                 <period-date-picker
                   :start="parmValue.req_start"
                   :end="parmValue.req_end"
@@ -112,10 +121,11 @@
                   @timeReturned="evt => handleTime(evt,'consultation')"
                   placeholder="咨询截止"
                 />
-              </el-col>
+              </el-col> -->
+
 
               <el-col :span="4" style="margin-right:10px">
-                <el-input v-model="parmValue.req_tel" size="mini" placeholder="联系电话" @change="
+                <el-input size="mini" placeholder="需求编号" v-model="parmValue.reqCode" @change="
                 pageInfo.curr = 1;
                 parmValue.page = 1;
                 searchList();
@@ -123,15 +133,13 @@
               </el-col>
 
               <el-col :span="4" style="margin-right:10px">
-                <el-input size="mini" placeholder="需求编号" v-model="parmValue.reqCode" @change="
+                <el-input v-model="parmValue.req_tel" size="mini" placeholder="联系电话" @change="
                 pageInfo.curr = 1;
                 parmValue.page = 1;
                 searchList();
                "/>
               </el-col>
-            </el-row>
 
-            <el-row style="margin-top:10px">
               <el-col :span="4">
                 <search-activity-type style="width:100%" size="mini" :value.sync="parmValue.demandProject" placeholder="需求项目" @change="
                    pageInfo.curr = 1;
@@ -139,30 +147,17 @@
                    searchList();
                   " />
               </el-col>
+            </el-row>
 
-              <el-col :span="4" style="margin-left:10px">
+            <el-row style="margin-top:10px">
+
+              <el-col :span="4">
                 <el-input size="mini" placeholder="需求创建人" v-model="parmValue.demandCreator" @change="
                 pageInfo.curr = 1;
                 parmValue.page = 1;
                 searchList();
                "/>
               </el-col>
-
-              <el-col :span="4" style="margin-left:10px">
-                <!-- <el-select size="mini" placeholder="需求企业" v-model="parmValue.demandEnterprise" @change="
-                pageInfo.curr = 1;
-                parmValue.page = 1;
-                searchList();
-               ">
-                  <el-option />
-                </el-select> -->
-                <search-customer style="width:100%" size="mini" placeholder="需求公司" :value.sync="parmValue.demandEnterprises" @change="
-                  pageInfo.curr = 1;
-                  parmValue.page = 1;
-                  searchList();
-                  " 
-                />
-              </el-col>
             </el-row>
 
           </div>

+ 7 - 7
src/views/customerService/invoiceApply/columns.js

@@ -9,27 +9,27 @@ const statusList = [
 ]
 const demandColumns = [
   {
-    prop: 'todo',
-    label: 'todo',
+    prop: 'TODO',
+    label: 'TODO',
     span: 24
   },
 ]
 
 const listCol = [
   {
-    prop: 'todo',
+    prop: 'TODO',
     label: '开票申请编号',
     width: '155'
   },
 
   {
-    prop: 'todo',
+    prop: 'TODO',
     label: '需求订单编号',
     width: '155'
   },
 
   {
-    prop: 'todo',
+    prop: 'TODO',
     label: '需求公司',
     width: '120px'
   },
@@ -61,13 +61,13 @@ const listCol = [
     'min-width': '125'
   },
   {
-    prop: 'todo',
+    prop: 'TODO',
     label: '已开票金额',
     minWidth: '150px'
   },
 
   {
-    prop: 'todo',
+    prop: 'TODO',
     label: '未开票金额',
     'width': '120px'
   },

+ 21 - 18
src/views/customerService/invoiceApply/components/createInvoiceApply.vue

@@ -1,10 +1,9 @@
 <template>
-  <el-form ref="ruleForm" :rules="rules" :model="ruleForm" label-position="left" label-width="80px" size="mini">
+  <el-form ref="ruleForm" :rules="rules" :model="ruleForm" label-position="left" label-width="95px" size="mini">
       <el-row>
         <el-col :span="24">
           <el-form-item label="需求订单" prop="demandOrder">
             <el-input placeholder="请选择需求订单" @focus="demandVisible = true" v-if="!demandInfo"/>
-
             <div style="display:flex" v-else>
               <show-data-table
                 style="margin-bottom:10px"
@@ -35,22 +34,7 @@
 
       <el-row gutter="20">
         <el-col :span="12">
-          <el-form-item label="发票抬头" prop="invoiceTitle">
-            <!-- <el-input v-model="ruleForm.invoiceTitle" placeholder="客户公司抬头" /> -->
-            <search-invoice-title :value.sync="ruleForm.invoiceTitle" style="width:100%" @change="_invoiceInfo => invoiceInfo = _invoiceInfo" />
-          </el-form-item>
-
-          <show-data-table 
-            v-if="invoiceInfo"
-            :sitem="invoiceInfo"
-            style="padding: -5px 0 10px 0"
-            :newTime="newTime"
-            :columns="invoiceColumns"
-          />
-        </el-col>
-
-        <el-col :span="12">
-          <el-form-item label="申请总金额" label-width="95px" prop="applyAmount">
+          <el-form-item label="申请总金额"  prop="applyAmount">
             <digital-input
               :values="ruleForm.applyAmount"
               :placeholder="'采购毛利率'"
@@ -74,6 +58,25 @@
             <el-input placeholder="备注" v-model="ruleForm.remark" style="width:100%" type="textarea" />
           </el-form-item>
         </el-col>
+
+        <el-col :span="12">
+          <el-form-item label="发票抬头" prop="invoiceTitle">
+            <search-invoice-title 
+              :value.sync="ruleForm.invoiceTitle" 
+              @change="_invoiceInfo => invoiceInfo = _invoiceInfo" 
+              style="width:100%"
+              placeholder="请选择发票抬头" 
+            />
+          </el-form-item>
+
+          <show-data-table 
+            v-if="invoiceInfo"
+            :sitem="invoiceInfo"
+            style="padding: -5px 0 10px 0"
+            :newTime="newTime"
+            :columns="invoiceColumns"
+          />
+        </el-col>
       </el-row>
 
     <div style="display:flex;justify-content:flex-end;margin-bottom:10px">

+ 31 - 5
src/views/customerService/invoiceApply/components/demandModal.vue

@@ -22,6 +22,19 @@
           searchList();
         "
       >
+        <template #table-header>
+          <el-row style="width:100%">
+            <el-col :span="5">
+              <el-input v-model="parmValue.reqCode" size="mini" placeholder="需求订单编号" />
+            </el-col>
+
+            <el-col :span="3" style="width:125px" class="fr">
+              <el-button size="mini" type="warning" @click="reset">重置</el-button>
+              <el-button size="mini" type="primary" @click="searchList">搜索</el-button>
+            </el-col>
+          </el-row>
+        </template>
+        
         <template #status="{ scope }">
           <el-tag size="mini"
             :type="(demandStatusOptions.find((item) => item.value == scope.row.status) || {}) .type || ''"
@@ -66,15 +79,16 @@ export default {
       demandStatusOptions,
       columns,
       size: 'mini',
+      parmValue: {
+        reqCode: "",
+        page:1
+      },
       loading: false,
       tableData: [],
       selected: [],
       table: {},
-      parmValue: {
-        page: 1
-      },
       pageInfo: {
-        size:15,
+        size:10,
         curr:1,
         total:0
       },
@@ -88,20 +102,32 @@ export default {
     handleClose(){
       this.pageInfo = {
         curr: 1,
-        size: 15,
+        size: 10,
         total: 0
       }
 
       this.parmValue = {
+        reqCode: "",
         page: 1
       }
+
       this._visible = false
     },
+    reset(){
+      this.parmValue = {
+        reqCode:""
+      }
+
+      this.searchList()
+    },
     async searchList() {
       this.loading = true;
+      
       const res = await asyncRequest.list({
         ...this.parmValue,
+        ...this.pageInfo
       });
+
       if (res && res.code === 1 && res.data) {
         this.tableData = res.data.list;
         this.pageInfo.total = Number(res.data.count);

+ 8 - 18
src/views/customerService/invoiceApply/detail.vue

@@ -2,25 +2,17 @@
   <div class="bargainListDetail">
     <div class="bargainListDetail-main">
       <el-tabs v-model="projectTabs" v-loading="loading">
-        <el-tab-pane label="需求订单详情" name="1">
+        <el-tab-pane label="开票申请详情" name="1">
           <el-collapse v-model="activeNames" style="margin: -18px 0 0 0">
-            <el-collapse-item :title="'需求订单详情'" name="1" v-if="id !== 'add'">
-              <!-- <show-data-table
-                style="padding: -5px 0 10px 0"
-                :newTime="newTime"
-                v-if="newTime !== ''"
-                :sitem="sitem"
-                :columns="demandColumns"
-              /> -->
-            </el-collapse-item>
-
-            <el-collapse-item title="创建开票申请" name="2" v-else>
+            <el-collapse-item title="创建开票申请" name="2" v-if="id === 'add'">
               <create-invoice-apply />
             </el-collapse-item>
 
-            <!-- <el-collapse-item title="发票申请管理" name="3">
-              <upload-invoice-node />
-            </el-collapse-item> -->
+            <template v-else>
+              <el-collapse-item title="发票申请管理" name="3">
+                <upload-invoice-node />
+              </el-collapse-item>
+            </template>
           </el-collapse>
         </el-tab-pane>
       </el-tabs>
@@ -39,7 +31,7 @@ import privateField from '@/mixins/privateField';
 
 export default {
   name: "invoiceApplyDetail",
-  mixins: [resToken,privateField],
+  mixins: [resToken, privateField],
   components:{ CreateInvoiceApply },
   computed: {
     ...mapGetters(["tablebtnSize", "searchSize", "size", "private_field", "isSupertube"]),
@@ -74,7 +66,6 @@ export default {
       queryId: "",
       status: "",
       sitem: null,
-
       orderItem: {},
       moneyDirItem: {},
       moneyItem: {},
@@ -132,7 +123,6 @@ export default {
               await this.$confirm(
                 `当前商品同意议价后,售价已低于系统最低售价${this.sitem.lower_price}元!`,
                 `最终售价已低于系统最低售价!是否继续?`,
-
                 {
                   confirmButtonText: "确定",
                   cancelButtonText: "取消",

+ 20 - 25
src/views/customerService/invoiceApply/index.vue

@@ -1,7 +1,6 @@
 <template>
   <div class="bargainList pagePadding">
-    <div>
-      <ex-table
+     <ex-table
         v-loading="loading"
         :table="table"
         :data="tableData"
@@ -9,7 +8,7 @@
         :page="pageInfo"
         :size="size"
         @page-curr-change="handlePageChange"
-        @page-size-change="handleSizeChange"
+        @page-size-change="handlePageChange"
         @screen-reset="
           pageInfo.curr = 1;
           parmValue.page = 1;
@@ -20,8 +19,8 @@
           parmValue.page = 1;
           searchList();
         "
-      >
-        <template #table-header="{}">
+     >
+       <template #table-header="{}">
           <div style="width: 100%">
             <el-row style="padding: 0 0 0 80px">
               <el-col :span="4" style="width: 301px; padding: 0 0 0px 0px">
@@ -49,11 +48,10 @@
                 >
                   <el-option
                     v-for="item in statusList"
-                    :key="item.id"
                     :label="item.label"
                     :value="item.id"
-                  >
-                  </el-option>
+                    :key="item.id"
+                  />
                 </el-select>
               </el-col>
 
@@ -64,11 +62,7 @@
                   v-model="parmValue.demandCompany"
                   clearable
                   placeholder="需求企业"
-                  @change="
-                    pageInfo.curr = 1;
-                    parmValue.page = 1;
-                    searchList();
-                  "
+                  @change="pageInfo.curr = 1;parmValue.page = 1;searchList();"
                 >
                   <el-option />
                 </el-select>
@@ -84,6 +78,7 @@
                   刷新
                 </el-button>
               </el-col>
+
               <el-col :span="4" class="fr" style="width: 66px">
                 <el-button
                   type="warning"
@@ -147,6 +142,7 @@
             <el-row style="margin-top:10px">
               <el-col :span="4">
                 <el-select
+                  style="width:100%"
                   :size="searchSize"
                   v-model="parmValue.invoiceType"
                   clearable
@@ -162,15 +158,15 @@
               </el-col>
             </el-row>
           </div>
-        </template>
-        <template #status="{ scope }">
+       </template>
+       <template #status="{ scope }">
           <el-tag
             :size="tablebtnSize"
             :type="(statusList.find((item) => item.id == scope.row.status) || {}).type || ''"
             v-text="(statusList.find((item) => item.id == scope.row.status) || {}).label || '--'"
           ></el-tag>
-        </template>
-        <template #good_name="{ scope }">
+       </template>
+       <template #good_name="{ scope }">
           <span>{{ scope.row.good_name }}</span>
           <span
             v-for="(si, sii) in scope.row.specinfo"
@@ -180,13 +176,13 @@
               si.spec_value_name
             }}]</span
           >
-        </template>
-        <template #can="{ scope }">
+       </template>
+       <template #can="{ scope }">
           <span v-for="(si, sii) in scope.row.can" :key="si.id + sii">
             <span v-if="sii !== 0">_</span>{{ si.name }}</span
           >
-        </template>
-        <template #operation="{ scope }">
+       </template>
+       <template #operation="{ scope }">
           <el-tooltip
             v-if="powers.some((i) => i == '007')"
             effect="dark"
@@ -199,9 +195,8 @@
                @click="getRouter('invoiceApplyDetail', scope.row.bargainNo )"
             ></i>
           </el-tooltip>
-        </template>
-      </ex-table>
-    </div>
+       </template>
+     </ex-table>
   </div>
 </template>
 <script>
@@ -213,7 +208,7 @@ import { listCol, statusList } from "./columns";
 import { mapGetters } from "vuex";
 
 /**
- * @props
+ *@props
  createStart//创建开始时间
  createEnd //创建结束时间
  demandCompany //需求企业

+ 8 - 1
src/views/customerService/workbench/_template.js

@@ -2,7 +2,7 @@ const mapFields = {
     name:"name",
     primaryClassification:'primaryClassification', // 一级分类
     secondaryClassification:'secondaryClassification',  // 二级分类
-    threeLevelClassification:'service_cat', // 三级分类
+    threeLevelClassification:'cat_name', // 三级分类
     price:'price', // 单价
     unit:'unit', // 单位
     nonTaxQuotes:'assess_price', // 非税报价
@@ -131,4 +131,11 @@ const mapFields = {
     // mapFields.nonTaxQuotes,
     // mapFields.taxIncludedQuote
   ]
+  
+
+  export const ModalTypes = {
+    create:'create',
+    update:'update',
+    copy: 'copy'
+  }
   

+ 52 - 20
src/views/customerService/workbench/detail.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="workbenchdetail">
+  <div class="workbenchdetail" v-loading="fullLoading">
     <div class="page-main clear">
       <div>
         <div class="left">
@@ -13,6 +13,10 @@
                 <li>{{ sitem.req_endtime }}</li>
                 <li>任务剩余时间:</li>
                 <li>{{ countdown }}</li>
+                <li>当前阶段:</li>
+                <li>{{ sitem.flow_stage }}</li>
+                <li>当前状态:</li>
+                <li>{{ (demandStatusOptions.find(item => item.value === String(sitem.status)) || {}).label || '--'  }}</li>
                 <li>需求公司:</li>
                 <li>{{ sitem.companyName || '--' }}</li>
                 <li>需求创建人:</li>
@@ -49,12 +53,16 @@
          
          <!-- v-if="storeId" -->
           <el-collapse v-model="actives">
-            <el-collapse-item title="评估预算函" name="1">
+            <el-collapse-item 
+              name="1" 
+              title="评估预算函" 
+              v-if="String(sitem.status) === '1' || String(sitem.status) === '2'">
               <letter
                 ref="evaLetter"
                 :status="1"
                 type="budget"
                 :id="sitem.id"
+                :isFile="true"
                 :isSelection="true"
                 :readonly="Number(sitem.status) !== 1"
                 @selection="handleSelection($event, 'evalute')"
@@ -63,7 +71,11 @@
                 @refresh="refresh('eva')"
               />
             </el-collapse-item>
-            <el-collapse-item title="活动方案管理" name="2">
+
+            <el-collapse-item 
+              name="2"
+              title="活动方案管理" 
+              v-if="String(sitem.status) === '2' || String(sitem.status) === '3'">
               <letter 
                 :status="2"
                 ref="actLetter"
@@ -75,10 +87,15 @@
                 :beforeModalVisible="beforeActivityModalVisible"
                 @selection="handleSelection($event, 'activity')"
                 :requsetMethod="reqsetActivityLetter"
+                :updateLoading="updateLoading"
                 @refresh="refresh('act')"
               />
             </el-collapse-item>
-            <el-collapse-item title="计划预算函管理" name="3">
+
+            <el-collapse-item 
+             name="3"
+             title="计划预算函管理" 
+             v-if="String(sitem.status) === '3'">
               <letter
                 ref="proLetter"
                 :status="3"
@@ -86,9 +103,10 @@
                 :id="sitem.id"
                 :isFile="true"
                 :readonly="Number(sitem.status) !== 3"
-                :beforeModalVisible="beforeProjectModalVisible"
                 @selection="handleSelection($event, 'project')"
                 :requsetMethod="requsetProjectLetter"
+                :beforeModalVisible="beforeProjectModalVisible"
+                :updateLoading="updateLoading"
                 @refresh="refresh('pro')"
               />
             </el-collapse-item>
@@ -106,6 +124,7 @@
 <script>
 import asyncRequest from "@/apis/service/customerService/workbench";
 import baseForm from "./components/baseForm";
+import { demandStatusOptions } from '@/assets/js/statusList';
 import EvaluteBudgetLetter from "./components/evaluateBudgetLetter/index.vue"
 import PlanBudgetLetter from "./components/planBudgetLetter/index.vue"
 import ActivityLetter from "./components/activityLetter/index.vue"
@@ -132,7 +151,9 @@ export default {
   },
   data() {
     return {
+      fullLoading:false,
       storeId: "",
+      demandStatusOptions,
       countdown:'00:00:00',
       timer:null,
       actives:["1","2","3"],
@@ -221,8 +242,6 @@ export default {
       return result;
     },
     async initData() {
-      console.log(asyncRequest)
-
       const { code, message, data } = await asyncRequest.detail({
         id: this.queryId,
       });
@@ -239,14 +258,13 @@ export default {
         this.$message.warning(message);
       }
     },
-    clearTime() {
+    clearTimer() {
       if (this.timer) {
         clearInterval(this.timer);
         this.num = 0;
       }
     },
     handleSelection(val, key){
-      console.log(val)
       this.selected[key] = val
     },
     async repeat_initData() {
@@ -260,6 +278,9 @@ export default {
     getNewTime() {
       this.newTime = new Date().valueOf();
     },
+    updateLoading(value){
+      this.fullLoading = value
+    },
     openModal(bidNo, type) {
       const { id } = this.$route.query;
       this.queryId = id;
@@ -278,7 +299,11 @@ export default {
         return false
       }
 
-      return true
+      return {
+         req_id: this.$route.query.id,
+        id: this.selected.evalute[0],
+        form: 'activity'
+      }
     },
     beforeProjectModalVisible(){
       if(this.selected.activity.length === 0){
@@ -291,7 +316,11 @@ export default {
         return false
       }
 
-      return true
+      return {
+        req_id:this.$route.query.id,
+        id: this.selected.activity[0],
+        form: 'project'
+      }
     },
     async refresh(refPrefix){
       const currentRef = refPrefix + 'Letter'
@@ -300,29 +329,32 @@ export default {
         if(letter !== currentRef) this.$refs[letter].searchList()
       })
     },
-    async requsetProjectLetter(planinfo, file_url){
+    async requsetProjectLetter(plan_info, file, store_id){
+        // id: this.selected.activity[0],
       const params = {
-        status: 3,
-        id: this.selected.activity[0],
-        planinfo,
-        file_url
+        store_id,
+        req_id:this.sitem.id,
+        plan_type: 3,
+        plan_info,
+        file
       }
 
-      return asyncRequest.planStatus(params)
+      return asyncRequest.planCreate(params)
     },
     async reqsetActivityLetter(planinfo, file_activty_url){
       const params = {
         status: 2,
         id: this.selected.evalute[0],
-        planinfo,
         file_activty_url
       }
 
       return asyncRequest.planStatus(params)
     },
-    async requestBudgetLetter(plan_info,_,store_id){
+    async requestBudgetLetter(plan_info,file, store_id){
       const params = {
-        req_id:this.sitem.id,
+        file,
+        req_id : this.sitem.id,
+        plan_type: 1,
         store_id,
         plan_info
       }

+ 36 - 34
src/views/customerService/workbench/index.vue

@@ -22,11 +22,20 @@
                   searchList();
                 " />
               </el-col>
+
+              <el-col :span="4" style="margin-left:10px">
+                <search-customer style="width:100%" size="mini" placeholder="需求公司" :value.sync="parmValue.demandEnterprises" @change="
+                  pageInfo.curr = 1;
+                  parmValue.page = 1;
+                  searchList();
+                  " 
+                />
+              </el-col>
                             
               <el-col :span="3" style="width: 66px; float: right">
                 <el-button
-                  :size="searchSize"
                   type="primary"
+                  :size="searchSize"
                   style="float: right; margin-left: 5px"
                   @click="searchList"
                 >
@@ -59,10 +68,10 @@
 
               <el-col :span="4" style="margin-right:10px">
                 <el-select v-model="parmValue.status" style="width:100%" size="mini" placeholder="当前状态" @change="
-                pageInfo.curr = 1;
-                parmValue.page = 1;
-                searchList();
-               ">
+                  pageInfo.curr = 1;
+                  parmValue.page = 1;
+                  searchList();
+                ">
                   <el-option v-for="status in demandStatusOptions" 
                     :key="status.value" 
                     :value="status.value" 
@@ -81,7 +90,7 @@
             </el-row>
 
             <el-row style="margin-top:10px">
-              <el-col :span="4" style="width: 341px;">
+              <!-- <el-col :span="4" style="width: 341px;">
                 <period-date-picker
                   :start="parmValue.req_start"
                   :end="parmValue.req_end"
@@ -90,10 +99,9 @@
                   @timeReturned="evt => handleTime(evt,'consultation')"
                   placeholder="咨询截止"
                 />
-              </el-col>
-
+              </el-col> -->
               <el-col :span="4" style="margin-right:10px">
-                <el-input v-model="parmValue.req_tel" size="mini" placeholder="联系电话" @change="
+                <el-input size="mini" placeholder="需求编号" v-model="parmValue.reqCode" @change="
                 pageInfo.curr = 1;
                 parmValue.page = 1;
                 searchList();
@@ -101,15 +109,13 @@
               </el-col>
 
               <el-col :span="4" style="margin-right:10px">
-                <el-input size="mini" placeholder="需求编号" v-model="parmValue.reqCode" @change="
+                <el-input v-model="parmValue.req_tel" size="mini" placeholder="联系电话" @change="
                 pageInfo.curr = 1;
                 parmValue.page = 1;
                 searchList();
                "/>
               </el-col>
-            </el-row>
 
-            <el-row style="margin-top:10px">
               <el-col :span="4">
                 <search-activity-type style="width:100%" size="mini" :value.sync="parmValue.demandProject" placeholder="需求项目" @change="
                    pageInfo.curr = 1;
@@ -117,32 +123,17 @@
                    searchList();
                   " />
               </el-col>
+            </el-row>
 
-              <el-col :span="4" style="margin-left:10px">
+            <el-row style="margin-top:10px">
+              <el-col :span="4">
                 <el-input size="mini" placeholder="需求创建人" v-model="parmValue.demandCreator" @change="
                 pageInfo.curr = 1;
                 parmValue.page = 1;
                 searchList();
                "/>
               </el-col>
-
-              <el-col :span="4" style="margin-left:10px">
-                <!-- <el-select size="mini" placeholder="需求企业" v-model="parmValue.demandEnterprise" @change="
-                pageInfo.curr = 1;
-                parmValue.page = 1;
-                searchList();
-               ">
-                  <el-option />
-                </el-select> -->
-                <search-customer style="width:100%" size="mini" placeholder="需求公司" :value.sync="parmValue.demandEnterprises" @change="
-                  pageInfo.curr = 1;
-                  parmValue.page = 1;
-                  searchList();
-                  " 
-                />
-              </el-col>
             </el-row>
-
           </div>
         </div>
 
@@ -164,6 +155,14 @@
                 {{item.participant}},{{item.req_demand}}
               </div>
 
+              <div class="task-card__content">
+                当前阶段 : {{item.flow_stage}}
+              </div>
+
+              <div class="task-card__content">
+                状态 : {{ demandStatusOptions.find(_item => _item.value === String(item.status)).label }}
+              </div>
+
               <div class="task-card__footer">
                 <ul>
                   <li>
@@ -197,6 +196,7 @@
 import asyncRequest from "@/apis/service/customerService/workbench";
 import roleLevel from "@/assets/js/roleLevel";
 import mixinPage from "@/mixins/elPaginationHandle";
+import { demandStatusOptions } from '@/assets/js/statusList';
 import { mapGetters } from "vuex";
 import resToken from "@/mixins/resToken";
 import dayjs from "dayjs"
@@ -256,6 +256,7 @@ export default {
     return {
       num: 60,
       timer: null,
+      demandStatusOptions,
       roleLevel: roleLevel,
       loading: false,
       showModel: false,
@@ -398,7 +399,7 @@ export default {
       };
       this.parmValue = {
         page: 1, // 页码
-        size: 15, // 每页显示条数
+        size: 1000, // 每页显示条数
         status: "1",
       };
       this.searchList();
@@ -544,12 +545,13 @@ export default {
         this.loading = true;
         const { code, data } = await asyncRequest.list({
           ...this.parmValue,
-          size: 15
+          flow_stage:"磋商阶段",
+          size: 1000
         });
 
         if (code === 1) {
-          const { list, count } = data;
-          
+          let { list, count } = data;
+          list = Object.values(list)
           this.countdownMaps = list.reduce((prev,current) => {
             return {
               ...prev,

+ 44 - 44
src/views/customerService/workbench/letterEditing.vue

@@ -1,41 +1,43 @@
 <template>
   <div style="padding:10px" v-loading="loading">
-    <ul style="width:100%;margin-bottom:10px;display:flex;justify-content:flex-end;margin-top:10px;align-items:center;">
-      <li style="line-height:30px;margin-right:20px">
-       <span>非税总报价 : </span>
-       <span>{{Number(total.notTaxTotal).toFixed(2)}}</span>
-      </li>
-
-      <li style="line-height:30px;margin-right:20px">
-       <span>含税总报价 : </span>
-       <span>{{Number(total.includeTaxTotal).toFixed(2)}}</span>
-      </li>
-
-      <li style="line-height:30px;margin-right:20px">
-       <span>总税额 : </span>
-       <span>{{Number(total.total).toFixed(2)}}</span>
-      </li>
-
-      <li>
-        <el-button size="mini" type="primary" @click="onSubmit">保存</el-button>
-      </li>
-    </ul>
+    <div style="display:flex;">
+      <el-tooltip content="返回">
+        <el-button size="mini" icon="el-icon-d-arrow-left" @click="back" />
+      </el-tooltip>
+
+      <ul style="width:100%;margin-bottom:10px;display:flex;justify-content:flex-end;margin-top:10px;align-items:center;">
+        <li style="line-height:30px;margin-right:20px">
+         <span>非税总报价 : </span>
+         <span>{{Number(total.notTaxTotal).toFixed(2)}}</span>
+        </li>
+
+        <li style="line-height:30px;margin-right:20px">
+         <span>含税总报价 : </span>
+         <span>{{Number(total.includeTaxTotal).toFixed(2)}}</span>
+        </li>
+
+        <li style="line-height:30px;margin-right:20px">
+         <span>总税额 : </span>
+         <span>{{Number(total.total).toFixed(2)}}</span>
+        </li>
+      </ul>
+    </div>
 
     <ex-table
       :columns="[ ...columns,{ _slot_: 'action', label: '操作', width: '160px' } ]"
       :table="table"
-      :data="tableData.assessinfo"
+      :data="tableData.planinfo"
       style="margin: 15px 0 0 0"
       :noPagination="true"
     >
       <template #action={scope}>
-        <el-button size="mini" type="text" @click="copyItem(scope.row)">复制</el-button>
-        <el-button size="mini" type="text" @click="updateItem(scope.$index)">编辑</el-button>
+        <el-button size="mini" type="text" @click="handleItem(scope.$index, ModalTypes.copy)">复制</el-button>
+        <el-button size="mini" type="text" @click="handleItem(scope.$index, ModalTypes.update)">编辑</el-button>
         <el-button size="mini" type="text" @click="deleteItem(scope.$index)">删除</el-button>
       </template>
     </ex-table>
 
-    <update-modal :sitem="sitem" :visible.sync="visible" @save="handleSave" />
+    <update-modal @refresh="onSearch" :storeId="tableData.store_id" :type="modalType" :sitem="sitem" :visible.sync="visible" @save="handleSave" />
   </div>
 </template>
 
@@ -46,6 +48,7 @@ import UpdateModal from "./modal.vue"
 
 import {
   columns,
+  ModalTypes
 } from './_template'
 
 export default {
@@ -54,6 +57,8 @@ export default {
   components:{ UpdateModal },
   data() {
     return {
+      ModalTypes,
+      modalType: ModalTypes.create,
       columns,
       visible: false,
       loading: false,
@@ -69,8 +74,7 @@ export default {
   },
   computed: {
     total(){
-      console.log(this.tableData.assessinfo)
-      const list = this.tableData.assessinfo || []
+      const list = this.tableData.planinfo || []
 
       return list.reduce((prev,current) => ({
           notTaxTotal:Number(prev.notTaxTotal) + Number( current.pay_fee),
@@ -95,14 +99,17 @@ export default {
     this.onSearch()
   },
   methods: {
+    back(){
+      this.$router.back()
+    },
     async deleteItem(index){
-      const item = this.tableData.assessinfo[index]
+      const item = this.tableData.planinfo[index]
 
       this.$confirm(`是否确认删除预算函 ${item.name}?`, {
         type:'warning'
       }).then(async () => {
         if(!item.id) {
-          this.tableData.assessinfo.splice(index, 1)
+          this.tableData.planinfo.splice(index, 1)
           return
         }
 
@@ -111,14 +118,9 @@ export default {
         this.loading = false
         if(code !== 1) return
 
-        this.tableData.assessinfo.splice(index, 1)
+        this.tableData.planinfo.splice(index, 1)
       })
     },
-    updateItem(index){
-      this.sitem = this.tableData.assessinfo[index]
-      this.index = index
-      this.visible = true
-    },
     async onSearch(){
       this.loading = true
       
@@ -131,29 +133,27 @@ export default {
 
       this.tableData = data
     },
-    async copyItem(row){
-      const item = JSON.parse(JSON.stringify(row))
-      delete item.id
-      this.tableData.assessinfo.push(item)
+    handleItem(index, type = ModalTypes.copy ){
+      this.sitem = this.tableData.planinfo[index]
+      this.index = index
+      this.visible = true
+      this.modalType = type
     },
     async onSubmit() {
       this.loading = true
       const param = {
-        plan_info:this.tableData.assessinfo.map(({
-          name,  service_cat, price,unit,  num, tax,  id
-        }) => ({
-          name, service_cat, price, unit, num, tax, id
-        })),
+        plan_info: this.tableData.planinfo.map(({name, service_cat, price,unit,  num, tax,  id   }) =>  ({ name, service_cat, price, unit, num, tax, id })),
         plan_id:this.$route.query.id,
         store_id:this.tableData.store_id
       }
+
       this.loading = false
       const { code } = await asyncRequest.planUpdate(param)
       if(code !== 1) return
       this.$router.back()
     },
     handleSave(data){
-      this.$set(this.tableData.assessinfo, this.index, data)
+      this.$set(this.tableData.planinfo, this.index, data)
     }
   }
 }

+ 57 - 20
src/views/customerService/workbench/modal.vue

@@ -1,11 +1,12 @@
 <template>
-  <el-dialog :visible="innerVisible" title="编辑预算函" center :close-on-click-modal="false" @close="handleClose">
+  <el-dialog :visible="innerVisible" :title="title" center :close-on-click-modal="false" @close="handleClose">
     <el-form ref="ruleForm" label-width="110px" size="mini" :rules="rules" :model="ruleForm">
       <el-form-item label="服务名称" prop="name">
         <el-input placeholder="服务名称" v-model="ruleForm.name" />
       </el-form-item>
+
       <el-form-item label="服务分类" prop="service_cat">
-        <el-input placeholder="服务分类" v-model="ruleForm.service_cat" />
+        <search-category :value.sync="ruleForm.service_cat" style="width:100%" ref="category" />
       </el-form-item>
 
       <el-form-item label="单价" prop="price">
@@ -58,23 +59,32 @@
       </el-form-item>
 
       <el-form-item class="flex-end">
-        <el-button type="primary" size="mini" @click="onSave">保存</el-button>
+        <el-button :loading="loading" type="primary" size="mini" @click="onSave">保存</el-button>
       </el-form-item>
     </el-form>
   </el-dialog>
 </template>
 
 <script>
+import { ModalTypes } from "./_template"
+import asyncRequest from "@/apis/service/customerService/workbench";
+
 export default {
-  props:['visible','sitem', 'type'],
+  props:['visible','sitem', 'type', "storeId"],
   computed:{
     innerVisible:{
       get(){
         return this.visible
       },
       set(newVal){
-        this.$emit('update:visible',newVal)
+        this.$emit('update:visible', newVal)
       }
+    },
+    title(){
+      console.log(this.type)
+      const baseTitle = '预算函'
+      const prefix = this.type === ModalTypes.copy ? '复制' : '编辑'
+      return `${prefix}${baseTitle}`
     }
   },
   watch:{
@@ -83,50 +93,52 @@ export default {
       this.$nextTick(() => this.initForm())
     }
   },
+
   data(){
     return {
       ruleForm:{},
+      loading:false,
       rules:{
         name:[
           {
-            required:true,
+            required: true,
             message:'请输入服务名称',
             trigger:'change'
           }
         ],
         service_cat:[
           {
-            required:true,
-            message:'请输入服务分类ID',
+            required: true,
+            message:'请选择服务分类',
             trigger:'change'
           }
         ],
         price:[
           {
-            required:true,
+            required: true,
             message:'请输入单价',
             trigger:'change'
           }
         ],
         unit:[
           {
-            required:true,
-            message:'请输入单位ID',
-            trigger:'change'
+            required: true,
+            message: '请输入单位',
+            trigger: 'change'
           }
         ],
         num:[
           {
-            required:true,
-            message:'请输入数量',
-            trigger:'change'
+            required: true,
+            message: '请输入数量',
+            trigger: 'change'
           }
         ],
        tax:[
           {
-            required:true,
-            message:'请输入税率',
-            trigger:'change'
+            required: true,
+            message: '请输入税率',
+            trigger: 'change'
           }
         ]
       }
@@ -135,9 +147,9 @@ export default {
   methods:{
     initForm(){
       this.ruleForm = {...this.sitem}
+      this.$refs.category.init(this.sitem.service_cat)
     },
     number_change(num,prop){
-      console.log(num)
       this.ruleForm[prop] = num
     },
     handleClose(){
@@ -146,8 +158,33 @@ export default {
     onSave(){
       this.$refs.ruleForm.validate(async isValid => {
         if(!isValid) return
-        this.$emit('save', this.ruleForm)
+
+        const { id,name,service_cat,unit,price,num,remark,store_id,tax } = this.ruleForm;
+
+        const params = {
+          id,
+          name,
+          service_cat,
+          unit,
+          price,
+          num,
+          remark,
+          planId: this.$route.query.id,
+          store_id: this.storeId,
+          tax
+        }
+
+        if(this.type === ModalTypes.copy){
+          delete params.id
+        }
+
+        this.loading = true
+        const { code } = await asyncRequest.planUpdateInfo(params)
+        this.loading = false 
+        
+        if(code !== 1) return
         this.innerVisible = false
+        this.$emit('refresh')
       })
     }
   }