Преглед на файлове

feature(订单管理系统):
1、跟进记录增加日期及跟进类型的筛选。

2、当月签约金额的抓取合同签约时间和合同金额的数据

3、销售区域授权没有香港地区问题修复。

4、打卡跳转客户/经销商的列表,打卡可以关联到具体客户或者经销商名单。

5、公海客户查询条件调整:客户名称、省份、市、跟进时间(改为时间段)。

6、储备客户查询条件调整:所属销售、跟进时间(改为时间段)。

7、跟进记录查询条件优化:跟进时间、跟进类型(电话、拜访、邮件)、跟进对象、跟进人

销售功能是客户查看自己所负责的项目历史全部跟进记录。增加跟进时间、跟进方式的筛选方式。

3】公海客户按照所在省、所在市查询
4】储备客户增加所属销售、所在省、所在市查询类型
5.新增数据指标

niezch преди 2 години
родител
ревизия
a58dbf42e3
променени са 5 файла, в които са добавени 791 реда и са изтрити 45 реда
  1. 92 18
      src/views/customer/follow.vue
  2. 528 0
      src/views/customer/followsell.vue
  3. 73 18
      src/views/customer/list.vue
  4. 72 8
      src/views/customer/openSea.vue
  5. 26 1
      src/views/plat/punchRecords/index.vue

+ 92 - 18
src/views/customer/follow.vue

@@ -1,8 +1,9 @@
 <!--
  * @Author: wanglj 471442253@qq.com
  * @Date: 2022-12-15 15:38:21
- * @LastEditors: wanglj
- * @LastEditTime: 2023-03-22 14:43:27
+
+ * @LastEditors: niezch@dashoo.cn
+ * @LastEditTime: 2023-03-27 11:30:37
  * @Description: file content
  * @FilePath: \opms_frontend\src\views\customer\follow.vue
 -->
@@ -13,30 +14,49 @@
         <el-input v-model="queryForm.custName" placeholder="客户" @keyup.enter.native="search" />
       </el-col>
       <!-- <el-col :span="4">
-        <el-date-picker
-          v-model="queryForm.date"
-          end-placeholder="结束日期"
-          placeholder="时间范围"
-          start-placeholder="开始日期"
-          style="width: 100%"
-          type="daterange" />
+        <el-input v-model="queryForm.custName" placeholder="客户" />
       </el-col> -->
-      <el-col :span="4">
-        <el-input v-model.number="queryForm.daysBeforeToday" placeholder="查询天数" @keyup.enter.native="search">
+      <!-- <el-col :span="4">
+        <el-input v-model.number="queryForm.daysBeforeToday" placeholder="查询天数">
           <template slot="append">天</template>
         </el-input>
-      </el-col>
+      </el-col> -->
       <el-col :span="4">
-        <el-select v-model="queryForm.targetType" clearable placeholder="跟进类型" style="width: 100%">
-          <el-option v-for="item in targetTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+        <el-select v-model="queryForm.followType" clearable placeholder="跟进类型" style="width: 100%">
+          <el-option v-for="item in FollowTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
         </el-select>
       </el-col>
-      <el-col :span="4">
-        <el-input v-model.number="queryForm.targetName" placeholder="跟进对象" @keyup.enter.native="search" />
+
+      <el-col :span="6">
+        <!-- <el-select v-model="queryForm.targetType" clearable placeholder="跟进对象类型" style="width: 100%">
+          <el-option v-for="item in targetTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+        </el-select> -->
+        <el-input
+          v-model="queryForm.targetName"
+          class="input-with-select"
+          clearable
+          placeholder="跟进对象"
+          @keyup.enter.native="search">
+          <el-select v-model="queryForm.targetType" clearable placeholder="跟进对象类型" slot="prepend">
+            <el-option v-for="item in targetTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+          </el-select>
+        </el-input>
       </el-col>
+      <!-- <el-col :span="4">
+        <el-input v-model.number="queryForm.targetName" placeholder="跟进对象" />
+      </el-col> -->
       <el-col :span="4">
         <el-input v-model="queryForm.createdName" placeholder="跟进人" @keyup.enter.native="search" />
       </el-col>
+      <el-col :span="6">
+        <el-date-picker
+          v-model="queryForm.date"
+          end-placeholder="跟进结束时间"
+          range-separator="至"
+          start-placeholder="跟进开始时间"
+          style="width: 100%"
+          type="daterange" />
+      </el-col>
       <el-col :span="4">
         <el-button icon="el-icon-plus" type="primary" @click="search">查询</el-button>
         <!-- <el-button @click="addFollowUp">添加</el-button> -->
@@ -135,7 +155,8 @@
           targetId: '',
           managerId: '',
           daysBeforeToday: 20,
-          date: [],
+          date: [new Date(this.getLastMonth(new Date())), new Date()],
+          followType: '',
         },
         loadFlag: true,
         records: [],
@@ -167,13 +188,27 @@
           deletedTime: '',
         },
         targetTypeOptions: [],
+        FollowTypeOptions: [],
       }
     },
     mounted() {
       this.fetchData()
       this.getOptions()
+      this.getFollowOptions()
     },
     methods: {
+      getLastMonth(date) {
+        const now = new Date(date)
+        const year = now.getFullYear()
+        const month = now.getMonth() + 1
+        const day = now.getDate()
+        const nowMonthDay = new Date(year, month, 0).getDate() // 当前月的总天数
+        if (month - 1 <= 0) return year - 1 + '-' + 12 + '-' + day // 如果是1月,年数往前推一年
+        const lastMonthDay = new Date(year, parseInt(month) - 1, 0).getDate()
+        if (lastMonthDay >= day) return year + '-' + (month - 1) + '-' + day
+        if (day < nowMonthDay) return year + '-' + (month - 1) + '-' + (lastMonthDay - (nowMonthDay - day)) // 1个月前所在月的总天数小于现在的天日期
+        return year + '-' + (month - 1) + '-' + lastMonthDay // 当前天日期小于当前月总天数
+      },
       getOptions() {
         Promise.all([this.getDicts('follow_target_type')])
           .then(([targetType]) => {
@@ -181,12 +216,36 @@
           })
           .catch((err) => console.log(err))
       },
+      //跟进类型
+      getFollowOptions() {
+        Promise.all([this.getDicts('follow_type')])
+          .then(([targetType]) => {
+            this.FollowTypeOptions = targetType.data.values || []
+          })
+          .catch((err) => console.log(err))
+      },
       search() {
         // this.queryForm.daysBeforeToday = 20
         this.fetchData()
       },
       async fetchData() {
         let params = { ...this.queryForm }
+        let _this = this
+
+        let CreateOn = []
+        if (!_this.queryForm.date) {
+          _this.queryForm.date = []
+        }
+        // 解析时间
+        if (_this.queryForm.date.length === 2) {
+          _this.queryForm.date[1].setHours(23)
+          _this.queryForm.date[1].setMinutes(59)
+          _this.queryForm.date[1].setSeconds(59)
+          CreateOn.push(_this.formatDateTime(_this.queryForm.date[0]))
+          CreateOn.push(_this.formatDateTime(_this.queryForm.date[1]))
+        }
+        params['CreateOn'] = CreateOn.join(',')
+
         const [err, res] = await to(api.getListByDay(params))
         if (err) return console.log(err, 'err')
         this.records = res.data.list || []
@@ -213,7 +272,8 @@
           targetId: '',
           managerId: '',
           daysBeforeToday: 20,
-          date: [],
+          date: [new Date(this.getLastMonth(new Date())), new Date()],
+          followType: '',
         }
         this.fetchData()
       },
@@ -245,6 +305,17 @@
           })
         }
       },
+      formatDateTime(date) {
+        var y = date.getFullYear()
+        var m = date.getMonth() + 1
+        m = m < 10 ? '0' + m : m
+        var d = date.getDate()
+        d = d < 10 ? '0' + d : d
+        var h = date.getHours()
+        var minute = date.getMinutes()
+        minute = minute < 10 ? '0' + minute : minute
+        return y + '-' + m + '-' + d + ' ' + h + ':' + minute
+      },
       // 详情
       showDetail(row) {
         this.$refs.followDetail.init({ ...row })
@@ -304,6 +375,9 @@
 
 <style lang="scss" scoped>
   $base: '.follow';
+  ::v-deep .el-input-group__prepend {
+    width: 35%;
+  }
   .follow {
     display: flex;
 

+ 528 - 0
src/views/customer/followsell.vue

@@ -0,0 +1,528 @@
+<!--
+ * @Author: wanglj 471442253@qq.com
+ * @Date: 2022-12-15 15:38:21
+ * @LastEditors: niezch@dashoo.cn
+ * @LastEditTime: 2023-03-24 17:52:18
+ * @Description: file content
+ * @FilePath: \opms_frontend\src\views\customer\followsell.vue
+-->
+<template>
+  <div class="follow-container">
+    <el-row :gutter="10" style="margin-bottom: 10px">
+      <!-- <el-col :span="4">
+        <el-input v-model="queryForm.custName" placeholder="客户" />
+      </el-col> -->
+
+      <!-- <el-col :span="4">
+        <el-input v-model.number="queryForm.daysBeforeToday" placeholder="查询天数">
+          <template slot="append">天</template>
+        </el-input>
+      </el-col> -->
+      <el-col :span="4">
+        <el-select v-model="queryForm.followType" clearable placeholder="跟进类型" style="width: 100%">
+          <el-option v-for="item in FollowTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+        </el-select>
+      </el-col>
+      <el-col :span="6">
+        <!-- <el-select v-model="queryForm.targetType" clearable placeholder="跟进对象类型" style="width: 100%">
+          <el-option v-for="item in targetTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+        </el-select> -->
+        <el-input v-model="queryForm.targetName" class="input-with-select" clearable placeholder="跟进对象">
+          <el-select v-model="queryForm.targetType" clearable placeholder="跟进对象类型" slot="prepend">
+            <el-option v-for="item in targetTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+          </el-select>
+        </el-input>
+      </el-col>
+      <!-- <el-col :span="4">
+        <el-input v-model.number="queryForm.targetName" placeholder="跟进对象" />
+      </el-col> -->
+      <el-col :span="4">
+        <el-input v-model="queryForm.createdName" clearable placeholder="跟进人" />
+      </el-col>
+      <el-col :span="6">
+        <el-date-picker
+          v-model="queryForm.date"
+          end-placeholder="跟进结束时间"
+          range-separator="至"
+          start-placeholder="跟进开始时间"
+          style="width: 100%"
+          type="daterange" />
+      </el-col>
+      <el-col :span="4">
+        <el-button icon="el-icon-plus" type="primary" @click="search">查询</el-button>
+        <!-- <el-button @click="addFollowUp">添加</el-button> -->
+        <el-button icon="el-icon-refresh-right" @click="reset">重置</el-button>
+      </el-col>
+    </el-row>
+    <div class="follow">
+      <ul
+        v-infinite-scroll="load"
+        class="records infinite-list"
+        :infinite-scroll-disabled="loadFlag"
+        :infinite-scroll-immediate-check="false">
+        <li v-for="(date, index) in records" :key="index">
+          <div class="date">
+            <h2>{{ date.followDay.split('-')[2] }}</h2>
+            <h3>{{ date.followDay.split('-').splice(0, 2).join('.') }}</h3>
+          </div>
+          <ul class="content">
+            <li v-for="(item, idx) in date.followupList" :key="idx" @click="showComment(item.id)">
+              <!-- <el-avatar class="user-avatar"
+              :src="avatar" />-->
+              <vab-icon class="user-avatar" icon="account-circle-fill" />
+              <div class="text">
+                <p class="action">
+                  <span>{{ item.createdName }} 跟进({{ formatType(item.followType) }})</span>
+                  <span>
+                    <vab-icon icon="time-line" />
+                    {{ item.followDate }}
+                  </span>
+                </p>
+                <p class="content">
+                  <span>{{ item.followContent }}</span>
+                </p>
+                <div class="footer">
+                  <p>
+                    来自{{ selectDictLabel(targetTypeOptions, item.targetType) }}:
+                    <span @click="jumpTo(item)">{{ item.targetName }}</span>
+                  </p>
+                  <div>
+                    <el-button size="mini" @click="showDetail(item)">
+                      <vab-icon icon="arrow-right-circle-fill" />
+                      详情
+                    </el-button>
+                    <el-button size="mini" @click="showComment(item.id)">
+                      <!-- <vab-icon icon="chat-3-fill" /> -->
+                      评论({{ item.commentNumber }})
+                    </el-button>
+                  </div>
+                </div>
+              </div>
+            </li>
+          </ul>
+        </li>
+      </ul>
+      <div class="comment">
+        <ul>
+          <li v-for="item in comments" :key="item.id">
+            <vab-icon class="user-avatar" icon="account-circle-fill" />
+            <div class="text">
+              <p>{{ item.createdName }}</p>
+              <p>{{ item.content }}</p>
+              <p>{{ item.createdTime }}</p>
+            </div>
+          </li>
+        </ul>
+        <div class="form">
+          <el-input v-model="comment" maxlength="300" resize="none" :rows="5" show-word-limit type="textarea" />
+          <el-button size="mini" type="primary" @click="handleComment">评论</el-button>
+        </div>
+      </div>
+    </div>
+    <!-- 跟进详情 -->
+    <FollowDetail ref="followDetail" />
+  </div>
+</template>
+
+<script>
+  import to from 'await-to-js'
+  import api from '@/api/customer/follow'
+  import FollowDetail from './components/FollowDetail.vue'
+
+  export default {
+    name: 'FollowSell',
+    components: {
+      FollowDetail,
+    },
+    data() {
+      return {
+        listLoading: false,
+        queryForm: {
+          custId: '',
+          custName: '',
+          targetType: '',
+          targetName: '',
+          createdName: '',
+          targetId: '',
+          managerId: '',
+          daysBeforeToday: 20,
+          date: [new Date(this.getLastMonth(new Date())), new Date()],
+          followType: '',
+        },
+        loadFlag: true,
+        records: [],
+        followId: '',
+        comment: '',
+        comments: [],
+        visible: false,
+        form: {
+          id: '',
+          followType: '',
+          followDate: '',
+          followContent: '',
+          targetId: '',
+          targetType: '',
+          targetName: '',
+          custId: '',
+          custName: '',
+          contactsId: 0,
+          contactsName: '',
+          reminders: '',
+          nextTime: '',
+          remark: '',
+          createdBy: '',
+          createdName: '',
+          createdTime: '',
+          updatedBy: '',
+          updatedName: '',
+          updatedTime: '',
+          deletedTime: '',
+        },
+        targetTypeOptions: [],
+        FollowTypeOptions: [],
+      }
+    },
+    mounted() {
+      this.fetchData()
+      this.getOptions()
+      this.getFollowOptions()
+    },
+    methods: {
+      getLastMonth(date) {
+        const now = new Date(date)
+        const year = now.getFullYear()
+        const month = now.getMonth() + 1
+        const day = now.getDate()
+        const nowMonthDay = new Date(year, month, 0).getDate() // 当前月的总天数
+        if (month - 1 <= 0) return year - 1 + '-' + 12 + '-' + day // 如果是1月,年数往前推一年
+        const lastMonthDay = new Date(year, parseInt(month) - 1, 0).getDate()
+        if (lastMonthDay >= day) return year + '-' + (month - 1) + '-' + day
+        if (day < nowMonthDay) return year + '-' + (month - 1) + '-' + (lastMonthDay - (nowMonthDay - day)) // 1个月前所在月的总天数小于现在的天日期
+        return year + '-' + (month - 1) + '-' + lastMonthDay // 当前天日期小于当前月总天数
+      },
+      getOptions() {
+        Promise.all([this.getDicts('follow_target_type')])
+          .then(([targetType]) => {
+            this.targetTypeOptions = targetType.data.values || []
+          })
+          .catch((err) => console.log(err))
+      },
+      //跟进类型
+      getFollowOptions() {
+        Promise.all([this.getDicts('follow_type')])
+          .then(([targetType]) => {
+            this.FollowTypeOptions = targetType.data.values || []
+          })
+          .catch((err) => console.log(err))
+      },
+      search() {
+        // this.queryForm.daysBeforeToday = 20
+        this.fetchData()
+      },
+      async fetchData() {
+        let params = { ...this.queryForm }
+        let _this = this
+
+        let CreateOn = []
+        if (!_this.queryForm.date) {
+          _this.queryForm.date = []
+        }
+        // 解析时间
+        if (_this.queryForm.date.length === 2) {
+          _this.queryForm.date[1].setHours(23)
+          _this.queryForm.date[1].setMinutes(59)
+          _this.queryForm.date[1].setSeconds(59)
+          CreateOn.push(_this.formatDateTime(_this.queryForm.date[0]))
+          CreateOn.push(_this.formatDateTime(_this.queryForm.date[1]))
+        }
+        params['CreateOn'] = CreateOn.join(',')
+        params['Sell'] = '1'
+        const [err, res] = await to(api.getListByDay(params))
+        if (err) return console.log(err, 'err')
+        this.records = res.data.list || []
+        await this.$nextTick()
+        this.loadFlag = false
+        if (this.records.length) {
+          if (!this.followId) this.showComment(this.records[0].followupList[0].id)
+        } else {
+          this.comments = []
+          this.followId = ''
+        }
+      },
+      load() {
+        this.queryForm.daysBeforeToday += 20
+        this.fetchData()
+      },
+      reset() {
+        this.queryForm = {
+          custId: '',
+          custName: '',
+          targetType: '',
+          targetName: '',
+          createdName: '',
+          targetId: '',
+          managerId: '',
+          daysBeforeToday: 20,
+          date: [new Date(this.getLastMonth(new Date())), new Date()],
+          followType: '',
+        }
+        this.fetchData()
+      },
+      jumpTo(row) {
+        let pageName = ''
+        switch (row.targetType) {
+          case '10':
+            pageName = 'CustomerDetail'
+            break
+          case '20':
+            pageName = 'BusinessDetail'
+            break
+          case '30':
+            pageName = 'ContractDetail'
+            break
+          case '40':
+            pageName = ''
+            break
+          case '50':
+            pageName = 'DistributorDetail'
+            break
+        }
+        if (pageName) {
+          this.$router.push({
+            name: pageName,
+            query: {
+              id: row.targetId,
+            },
+          })
+        }
+      },
+      formatDateTime(date) {
+        var y = date.getFullYear()
+        var m = date.getMonth() + 1
+        m = m < 10 ? '0' + m : m
+        var d = date.getDate()
+        d = d < 10 ? '0' + d : d
+        var h = date.getHours()
+        var minute = date.getMinutes()
+        minute = minute < 10 ? '0' + minute : minute
+        return y + '-' + m + '-' + d + ' ' + h + ':' + minute
+      },
+      // 详情
+      showDetail(row) {
+        this.$refs.followDetail.init({ ...row })
+      },
+      async showComment(id) {
+        this.followId = id
+        const [err, res] = await to(api.getComment({ followId: id + '' }))
+        if (err) return
+        this.comments = res.data.list || []
+      },
+      formatType(val) {
+        let str = ''
+        if (val == 10) str = '电话'
+        else if (val == 20) str = '邮件'
+        else if (val == 30) str = '拜访'
+        return str
+      },
+      // 评论
+      async handleComment() {
+        let str = ''
+        if (!this.followId) str = '请选择跟进记录'
+        else if (!this.comment) str = '请输入评论'
+        if (str) return this.$message.warning(str)
+        let params = {
+          followId: this.followId + '',
+          content: this.comment,
+          remark: '',
+        }
+        const [err, res] = await to(api.addComment(params))
+        if (err) return
+        this.$message.success(res.msg)
+        this.showComment(this.followId)
+        this.comment = ''
+        this.fetchData()
+      },
+      addFollowUp() {
+        let params = {
+          followType: '20',
+          followDate: '2022-10-29',
+          followContent: '跟进内容',
+          targetId: 1,
+          targetType: '20',
+          targetName: 'dashoo',
+          custId: 26,
+          custName: '测试客户1348',
+          contactsId: 55,
+          contactsName: 'wanglj',
+          reminders: '',
+          nextTime: this.parseTime(new Date()),
+          remark: '',
+        }
+        api.addFollowUp(params)
+      },
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+  $base: '.follow';
+  ::v-deep .el-input-group__prepend {
+    width: 35%;
+  }
+  .follow {
+    height: calc(100vh - 240px);
+    display: flex;
+
+    .comment {
+      width: 300px;
+      display: flex;
+      flex-direction: column;
+      border-radius: 4px;
+      border: 1px solid rgb(215, 232, 244);
+
+      ul {
+        flex: 1;
+        overflow-y: auto;
+        padding: 10px;
+
+        li {
+          display: flex;
+          border-bottom: 1px solid #e3e5e7;
+
+          .text {
+            flex: 1;
+            padding: 0 10px;
+
+            p {
+              font-weight: 500;
+              margin: 0;
+              line-height: 32px;
+            }
+
+            p:first-child {
+              line-height: 30px;
+              font-weight: bold;
+            }
+
+            p:last-child {
+              font-size: 12px;
+              color: #9499a0;
+              text-align: right;
+            }
+          }
+        }
+
+        .user-avatar {
+          font-size: 30px;
+        }
+      }
+
+      .form {
+        padding: 4px;
+        text-align: right;
+
+        .el-textarea {
+          margin-bottom: 4px;
+        }
+      }
+    }
+
+    .records {
+      flex: 1;
+      margin: 0;
+      height: 100%;
+      padding: 10px 20px;
+      list-style: none;
+      overflow: auto;
+
+      > li {
+        display: flex;
+
+        + li {
+          margin-top: 10px;
+        }
+      }
+
+      .date {
+        width: 100px;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+
+        h2,
+        h3 {
+          margin: 0;
+        }
+
+        h2 {
+          font-size: 26px;
+          line-height: 32px;
+        }
+      }
+
+      .content {
+        flex: 1;
+        list-style: none;
+
+        li {
+          display: flex;
+          cursor: pointer;
+          border: 1px solid rgb(215, 232, 244);
+          background: rgb(247, 251, 254);
+          border-radius: 4px;
+          padding: 8px;
+
+          + li {
+            margin-top: 10px;
+          }
+        }
+
+        .user-avatar {
+          font-size: 40px;
+        }
+
+        .text {
+          flex: 1;
+          padding-left: 20px;
+          padding-right: 10px;
+
+          p {
+            font-weight: 500;
+            margin: 0;
+            line-height: 32px;
+
+            span {
+              color: #1d66dc;
+            }
+          }
+
+          .action {
+            display: flex;
+            justify-content: space-between;
+
+            span:first-child {
+              font-weight: bold;
+              color: #333;
+            }
+          }
+
+          .content {
+            display: flex;
+            justify-content: space-between;
+
+            span {
+              font-weight: bold;
+              color: #333;
+            }
+          }
+
+          .footer {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+          }
+        }
+      }
+    }
+  }
+</style>

+ 73 - 18
src/views/customer/list.vue

@@ -1,8 +1,8 @@
 <!--
  * @Author: wanglj 471442253@qq.com
  * @Date: 2022-12-26 16:34:37
- * @LastEditors: wanglj
- * @LastEditTime: 2023-03-22 10:54:33
+ * @LastEditors: niezch@dashoo.cn
+ * @LastEditTime: 2023-03-27 11:36:13
  * @Description: file content
  * @FilePath: \opms_frontend\src\views\customer\list.vue
 -->
@@ -14,35 +14,45 @@
       <el-tab-pane label="下属的客户" name="other" />
     </el-tabs>
     <el-row :gutter="10" style="margin-bottom: 10px">
-      <el-col :span="4">
-        <el-input v-model="queryForm.custCode" placeholder="客户编码" @keyup.enter.native="handleSearch" />
-      </el-col>
-      <el-col :span="4">
-        <el-input v-model="queryForm.custName" placeholder="客户名称" @keyup.enter.native="handleSearch" />
+      <!-- <el-col :span="4">
+        <el-input v-model="queryForm.custCode" placeholder="客户编码" clearable @keyup.enter.native="handleSearch" />
+      </el-col> -->
+      <el-col :span="3.5">
+        <el-input v-model="queryForm.custName" clearable placeholder="客户名称" @keyup.enter.native="handleSearch" />
       </el-col>
-      <el-col :span="4">
-        <el-select
-          v-model="queryForm.custIndustry"
-          clearable
-          placeholder="客户类型"
-          style="width: 100%"
-          @keyup.enter.native="handleSearch">
+      <!-- <el-col :span="4">
+        <el-select v-model="queryForm.custIndustry" clearable placeholder="客户类型" style="width: 100%">
           <el-option v-for="item in industryOptions" :key="item.key" :label="item.value" :value="item.key" />
         </el-select>
+      </el-col> -->
+      <el-col :span="3.5">
+        <el-input v-model="queryForm.custProvince" clearable placeholder="所属省" @keyup.enter.native="handleSearch" />
+      </el-col>
+      <el-col :span="3.5">
+        <el-input v-model="queryForm.custCity" clearable placeholder="所属市" @keyup.enter.native="handleSearch" />
+      </el-col>
+      <el-col :span="3.5">
+        <el-input v-model="queryForm.salesName" clearable placeholder="所属销售" @keyup.enter.native="handleSearch" />
       </el-col>
       <!-- <el-col :span="4">
         <el-select v-model="queryForm.custLevel" placeholder="客户级别" style="width: 100%">
           <el-option v-for="item in levelOptions" :key="item.value" :label="item.value" :value="item.value" />
         </el-select>
       </el-col> -->
-      <el-col :span="4">
-        <el-date-picker
+      <el-col :span="6">
+        <!-- <el-date-picker
           v-model="queryForm.followUpDate"
           placeholder="最后跟进时间"
           style="width: 100%"
           type="date"
-          value-format="yyyy-MM-dd"
-          @keyup.enter.native="handleSearch" />
+          value-format="yyyy-MM-dd" /> -->
+        <el-date-picker
+          v-model="queryForm.followUpDate"
+          end-placeholder="跟进结束时间"
+          range-separator="至"
+          start-placeholder="跟进开始时间"
+          style="width: 100%"
+          type="daterange" />
       </el-col>
       <el-col :span="4">
         <el-button icon="el-icon-plus" type="primary" @click="handleSearch">查询</el-button>
@@ -186,6 +196,10 @@
           pageNum: 1,
           pageSize: 10,
           isPublic: false,
+          salesName: '',
+          followUpDate: [new Date(this.getLastMonth(new Date())), new Date()],
+          custProvince: '',
+          custCity: '',
         },
         total: 0,
         listLoading: false,
@@ -296,6 +310,29 @@
       this.fetchData()
     },
     methods: {
+      formatDateTime(date) {
+        var y = date.getFullYear()
+        var m = date.getMonth() + 1
+        m = m < 10 ? '0' + m : m
+        var d = date.getDate()
+        d = d < 10 ? '0' + d : d
+        var h = date.getHours()
+        var minute = date.getMinutes()
+        minute = minute < 10 ? '0' + minute : minute
+        return y + '-' + m + '-' + d + ' ' + h + ':' + minute
+      },
+      getLastMonth(date) {
+        const now = new Date(date)
+        const year = now.getFullYear()
+        const month = now.getMonth() + 1
+        const day = now.getDate()
+        const nowMonthDay = new Date(year, month, 0).getDate() // 当前月的总天数
+        if (month - 1 <= 0) return year - 1 + '-' + 12 + '-' + day // 如果是1月,年数往前推一年
+        const lastMonthDay = new Date(year, parseInt(month) - 1, 0).getDate()
+        if (lastMonthDay >= day) return year + '-' + (month - 1) + '-' + day
+        if (day < nowMonthDay) return year + '-' + (month - 1) + '-' + (lastMonthDay - (nowMonthDay - day)) // 1个月前所在月的总天数小于现在的天日期
+        return year + '-' + (month - 1) + '-' + lastMonthDay // 当前天日期小于当前月总天数
+      },
       getOptions() {
         Promise.all([this.getDicts('cust_level'), this.getDicts('cust_idy')])
           .then(([level, industry]) => {
@@ -313,6 +350,20 @@
       async fetchData() {
         this.listLoading = true
         const params = { ...this.queryForm }
+        let _this = this
+        let CreateOn = []
+        if (!_this.queryForm.followUpDate) {
+          _this.queryForm.followUpDate = []
+        }
+        // 解析时间
+        if (_this.queryForm.followUpDate.length === 2) {
+          _this.queryForm.followUpDate[1].setHours(23)
+          _this.queryForm.followUpDate[1].setMinutes(59)
+          _this.queryForm.followUpDate[1].setSeconds(59)
+          CreateOn.push(_this.formatDateTime(_this.queryForm.followUpDate[0]))
+          CreateOn.push(_this.formatDateTime(_this.queryForm.followUpDate[1]))
+        }
+        params['CreateOn'] = CreateOn.join(',')
         const [err, res] = await to(api.getList(params))
         if (err) return (this.listLoading = false)
         this.list = res.data.list || []
@@ -347,6 +398,10 @@
           custCode: '', // 客户编码
           custName: '', //客户名称
           indusTry: '', // 客户类型  ()
+          salesName: '',
+          followUpDate: [new Date(this.getLastMonth(new Date())), new Date()],
+          custProvince: '',
+          custCity: '',
         }
         this.fetchData()
       },

+ 72 - 8
src/views/customer/openSea.vue

@@ -1,8 +1,8 @@
 <!--
  * @Author: wanglj 471442253@qq.com
  * @Date: 2022-12-15 15:38:21
- * @LastEditors: wanglj
- * @LastEditTime: 2023-03-22 10:43:54
+ * @LastEditors: niezch@dashoo.cn
+ * @La
  * @Description: file content
  * @FilePath: \opms_frontend\src\views\customer\openSea.vue
 -->
@@ -11,11 +11,25 @@
     <vab-query-form>
       <vab-query-form-top-panel>
         <el-form :inline="true" :model="queryForm" @submit.native.prevent>
+          <!-- <el-form-item>
+            <el-input v-model="queryForm.custCode" placeholder="客户编码" />
+          </el-form-item> -->
+          <el-form-item>
+            <el-input
+              v-model="queryForm.custName"
+              clearable
+              placeholder="客户名称"
+              @keyup.enter.native="handleSearch" />
+          </el-form-item>
           <el-form-item>
-            <el-input v-model="queryForm.custCode" placeholder="客户编码" @keyup.enter.native="handleSearch" />
+            <el-input
+              v-model="queryForm.custProvince"
+              clearable
+              placeholder="所在省"
+              @keyup.enter.native="handleSearch" />
           </el-form-item>
           <el-form-item>
-            <el-input v-model="queryForm.custName" placeholder="客户名称" @keyup.enter.native="handleSearch" />
+            <el-input v-model="queryForm.custCity" clearable placeholder="所在市" @keyup.enter.native="handleSearch" />
           </el-form-item>
           <el-form-item>
             <el-select
@@ -33,13 +47,20 @@
             </el-select>
           </el-form-item> -->
           <el-form-item>
-            <el-date-picker
+            <!-- <el-date-picker
               v-model="queryForm.followUpDate"
               placeholder="最后跟进时间"
               style="width: 100%"
               type="date"
-              value-format="yyyy-MM-dd"
-              @keyup.enter.native="handleSearch" />
+
+              value-format="yyyy-MM-dd" /> -->
+            <el-date-picker
+              v-model="queryForm.followUpDate"
+              end-placeholder="跟进结束时间"
+              range-separator="至"
+              start-placeholder="跟进开始时间"
+              style="width: 100%"
+              type="daterange" />
           </el-form-item>
           <el-form-item>
             <el-button icon="el-icon-plus" type="primary" @click="handleSearch">查询</el-button>
@@ -196,8 +217,10 @@
           custName: '', //客户名称
           custIndustry: '', // 客户类型  ()
           custLevel: '', //客户级别
-          followUpDate: '', //最后跟进时间
+          followUpDate: [new Date(this.getLastMonth(new Date())), new Date()], //最后跟进时间
           isPublic: true,
+          custProvince: '',
+          custCity: '',
         },
         selectRows: [],
         industryOptions: [], //客户类型
@@ -305,6 +328,18 @@
       this.getOptions()
     },
     methods: {
+      getLastMonth(date) {
+        const now = new Date(date)
+        const year = now.getFullYear()
+        const month = now.getMonth() + 1
+        const day = now.getDate()
+        const nowMonthDay = new Date(year, month, 0).getDate() // 当前月的总天数
+        if (month - 1 <= 0) return year - 1 + '-' + 12 + '-' + day // 如果是1月,年数往前推一年
+        const lastMonthDay = new Date(year, parseInt(month) - 1, 0).getDate()
+        if (lastMonthDay >= day) return year + '-' + (month - 1) + '-' + day
+        if (day < nowMonthDay) return year + '-' + (month - 1) + '-' + (lastMonthDay - (nowMonthDay - day)) // 1个月前所在月的总天数小于现在的天日期
+        return year + '-' + (month - 1) + '-' + lastMonthDay // 当前天日期小于当前月总天数
+      },
       getOptions() {
         Promise.all([this.getDicts('cust_level'), this.getDicts('cust_idy')])
           .then(([level, industry]) => {
@@ -316,6 +351,20 @@
       async fetchData() {
         this.listLoading = true
         const params = { ...this.queryForm }
+        let _this = this
+        let CreateOn = []
+        if (!_this.queryForm.followUpDate) {
+          _this.queryForm.followUpDate = []
+        }
+        // 解析时间
+        if (_this.queryForm.followUpDate.length === 2) {
+          _this.queryForm.followUpDate[1].setHours(23)
+          _this.queryForm.followUpDate[1].setMinutes(59)
+          _this.queryForm.followUpDate[1].setSeconds(59)
+          CreateOn.push(_this.formatDateTime(_this.queryForm.followUpDate[0]))
+          CreateOn.push(_this.formatDateTime(_this.queryForm.followUpDate[1]))
+        }
+        params['CreateOn'] = CreateOn.join(',')
         if (!params.followUpDate) params.followUpDate = null
         const [err, res] = await to(api.getPublicList(params))
         if (err) return (this.listLoading = false)
@@ -324,6 +373,17 @@
         this.listLoading = false
         this.$nextTick(() => this.$refs.table.doLayout())
       },
+      formatDateTime(date) {
+        var y = date.getFullYear()
+        var m = date.getMonth() + 1
+        m = m < 10 ? '0' + m : m
+        var d = date.getDate()
+        d = d < 10 ? '0' + d : d
+        var h = date.getHours()
+        var minute = date.getMinutes()
+        minute = minute < 10 ? '0' + minute : minute
+        return y + '-' + m + '-' + d + ' ' + h + ':' + minute
+      },
       handleSearch() {
         this.queryForm.pageNum = 1
         this.fetchData()
@@ -351,6 +411,10 @@
           custName: '', //客户名称
           custIndustry: '', // 客户类型  ()
           custLevel: '', //客户级别
+          followUpDate: [new Date(this.getLastMonth(new Date())), new Date()], //最后跟进时间
+          isPublic: true,
+          custProvince: '',
+          custCity: '',
         }
         this.fetchData()
       },

+ 26 - 1
src/views/plat/punchRecords/index.vue

@@ -45,7 +45,14 @@
                   <span>
                     {{ item.userNickName }}
                     <span v-show="item.userPostName">({{ item.userPostName }})</span>
-                    打卡
+                    打卡 &nbsp;
+                    <!-- 打卡类型(10居家20客户30经销商40代理商) 居家不显示 -->
+                    <span v-show="item.punchType != 10" @click="lookTarget(item)">
+                      {{ item.targetName }}
+                      <el-tag v-if="item.punchType == 20" type="success">客户</el-tag>
+                      <el-tag v-else-if="item.punchType == 30" type="warning">经销商</el-tag>
+                      <el-tag v-else-if="item.punchType == 40" type="danger">代理商</el-tag>
+                    </span>
                   </span>
                   <span>
                     <vab-icon icon="time-line" />
@@ -96,6 +103,24 @@
       lookPunchImg(path) {
         window.open(path, '_system')
       },
+      lookTarget(val) {
+        console.log(val)
+        let path = ''
+        switch (val.punchType) {
+          case '10':
+            break
+          case '20':
+            path = '/customer/detail?id=' + val.targetId
+            break
+          case '30':
+            path = '/base/info?id=' + val.targetId
+            break
+          case '40':
+            // path=''
+            break
+        }
+        this.$router.push(path)
+      },
       async fetchData() {
         let params = { ...this.queryForm }
         if (this.queryForm.date && this.queryForm.date.length === 2) {