yangfeng
2023-07-04 3d4f00f97ed2c16bd91e5d3eed4df6c641b3952b
新建项目第一次提交
54个文件已添加
18232 ■■■■■ 已修改文件
babel.config.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jsconfig.json 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 12984 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
public/index.html 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/serverconfig.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/responseHandler.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/style/index.scss 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/common/config/index.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/common/untils/wsCache.js 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/layout/components/AppMain.vue 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/layout/components/appHeader/index.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/layout/components/appsidebar/index.scss 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/layout/components/appsidebar/index.vue 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/layout/index.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/makepager/CommonSelectView.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/makepager/PagerView.vue 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/makepager/PublicFunctionBtnView.vue 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/makepager/SearchCommonView.vue 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/makepager/TableCommonView.vue 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/en-US.js 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/en-code.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/index.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/zh-CN.js 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/i18n/zh-cn-code.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/custom/index.js 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/deployCode.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/sales/index.js 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/service/index.js 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/custom/contacts/AddContactsDialog.vue 359 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/custom/contacts/index.vue 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/custom/customManage/AddCustomManageDialog.vue 542 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/custom/customManage/index.vue 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/custom/followupRecords/AddFollowupRecordsDialog.vue 349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/custom/followupRecords/index.vue 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/custom/index.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/custom/salesLead/AddSalesLeadDialog.vue 327 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/custom/salesLead/index.vue 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/login/index.vue 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/sales/index.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/index.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/orderManage/index.vue 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/serviceContract/AddServiceContractDialog.vue 456 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/serviceContract/index.vue 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/serviceFeeManage/index.vue 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/service/serviceFollowup/index.vue 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.develop.config.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
babel.config.js
New file
@@ -0,0 +1,5 @@
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}
jsconfig.json
New file
@@ -0,0 +1,19 @@
{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "baseUrl": "./",
    "moduleResolution": "node",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  }
}
package-lock.json
New file
Diff too large
package.json
New file
@@ -0,0 +1,55 @@
{
  "name": "sale-manage-web",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^1.4.0",
    "core-js": "^3.8.3",
    "crypto-js": "^4.1.1",
    "element-ui": "^2.15.13",
    "qs": "^6.11.2",
    "save": "^2.9.0",
    "svg-sprite-loader": "^6.0.11",
    "vue": "^2.6.14",
    "vue-i18n": "^8.26.7",
    "vue-router": "^3.6.5",
    "vuex": "^3.6.2",
    "web-storage-cache": "^1.1.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "sass": "^1.63.6",
    "sass-loader": "^13.3.2",
    "vue-template-compiler": "^2.6.14"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}
public/favicon.ico
public/index.html
New file
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
public/serverconfig.js
New file
@@ -0,0 +1,14 @@
const isWindows = typeof window !== "undefined" // windows环境
const isNode = typeof global !== "undefined" // node环境
const getServerJson = {
  managePath: isWindows ? window.location.origin : "", // 当前域名
  systemCode: "admin_platform", // 开发环境系统编码
  manageContextPath: "/manage", // 接口上下文
  localEncryptedKey: "platform cache key", // @/common/until/wsCache 加密使用的盐
  context: "/sale-manage-web"
}
if (isWindows) {
  window.getServerJson = getServerJson
} else if (isNode) {
  module.exports = getServerJson
}
src/App.vue
New file
@@ -0,0 +1,30 @@
<template>
  <div id="app" v-if="isShow">
    <!-- <img alt="Vue logo" src="./assets/logo.png" /> -->
    <router-view></router-view>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      isShow: true
    }
  }
}
</script>
<style>
html,
body,
#app {
  width: 100%;
  height: 100%;
  background-color: #f0f2f5;
}
body {
  margin: 0;
}
</style>
src/api/index.js
New file
@@ -0,0 +1,71 @@
import ax from "axios"
import { IS_PRODUCTION } from "@/common/config"
// import { wsCache } from "@/common/untils/wsCache"
import { responseHandler, errorResponseHandler } from "./responseHandler"
const JsonText = window.getServerJson
const axios = ax.create({
  baseURL: IS_PRODUCTION ? JsonText.managePath : "", // url = base url + request url
  withCredentials: true,
  headers: {
    "X-Requested-With": "XMLHttpRequest", // 给后台区分异步请求
    "Content-Type": "application/json;charset=UTF-8"
  },
  timeout: 300000 // request timeout
})
// 添加一个请求拦截器
axios.interceptors.request.use(
  (request) => {
    if (request.data instanceof FormData) {
      // 不处理
    } else if (request.data) {
      request.data["domain"] = JsonText.systemCode
    } else {
      request.data = { domain: JsonText.systemCode }
    }
    //用户登录标记
    // const token = wsCache.get('token')
    // request.headers['token'] = token
    return request
  },
  (error) => {
    return Promise.reject(error)
  }
)
// 添加一个响应拦截器
axios.interceptors.response.use(
  (response) => {
    // 处理响应请求池
    if (response.data.status.toString() === "200" && response.data.success === true) {
      return response
    } else {
      responseHandler(response)
      return Promise.reject(response.data)
    }
  },
  (error) => {
    errorResponseHandler(error)
    return Promise.reject(error)
  }
)
// 通用方法
export const POST = (url, params, config = {}) => {
  return axios.post(`${url}`, params, config).then((res) => res.data)
}
export const GET = (url, params, config = {}) => {
  return axios.get(`${url}`, { params: params, ...config }).then((res) => res.data)
}
export const PUT = (url, params, config = {}) => {
  return axios.put(`${url}`, params, config).then((res) => res.data)
}
export const DELETE = (url, params, config = {}) => {
  return axios.delete(`${url}`, { params: params }, config).then((res) => res.data)
}
export const PATCH = (url, params, config = {}) => {
  return axios.patch(`${url}`, params, config).then((res) => res.data)
}
export const Axios = axios
src/api/responseHandler.js
New file
@@ -0,0 +1,36 @@
// import { wsCache } from "@/common/untils/wsCache"
import { Message } from "element-ui"
import i18n from "@/i18n"
const durationTime = 2000
export function responseHandler(res) {
  const status = res.data.status.toString()
  // if (status.toString() === ) {
  // }
  const message = res.data.message || i18n.t(`businessStatusCode.${status}`)
  Message({
    message: message,
    offset: 70,
    type: "error",
    duration: durationTime
  })
}
export function errorResponseHandler(error) {
  let msg = ""
  if (error && error.response && error.response.status) {
    const status = error.response.status.toString()
    msg = error.response.message || i18n.t(`statusCode.${status}`)
  } else if (error.message === "Cancel") {
    return
  } else {
    msg = i18n.t(`statusCode.netErr`)
  }
  Message({
    message: msg,
    offset: 70,
    type: "error",
    duration: durationTime
  })
}
src/assets/logo.png
src/assets/style/index.scss
New file
@@ -0,0 +1 @@
@import "element-ui/lib/theme-chalk/index.css";
src/common/config/index.js
New file
@@ -0,0 +1,14 @@
let isProduction = process.env.NODE_ENV === "production"
let configObj = window.getServerJson
// 生产环境请求地址
export const baseUrl = configObj.managePath
// 是否是生产环境,打包的时候值会是true, 开发的时候值是false
export const IS_PRODUCTION = isProduction
// @/common/until/wsCache 加密使用的盐
export const LOCAL_ENCRYPTED_KEY = configObj.localEncryptedKey
// 接口上下文
export const manageContextPath = configObj.manageContextPath
src/common/untils/wsCache.js
New file
@@ -0,0 +1,49 @@
import AES from "crypto-js/aes"
import ENC_UTF8 from "crypto-js/enc-utf8"
import WebStorageCache from "web-storage-cache"
import { LOCAL_ENCRYPTED_KEY } from "@/common/config"
const cache = new WebStorageCache()
const isEncrypt = true
const isEncryptPartial = true
function getCache(key) {
  const encryptValue = cache.get(key)
  if (encryptValue === null) {
    return null
  }
  const bytes = AES.decrypt(encryptValue, LOCAL_ENCRYPTED_KEY)
  const plaintext = bytes.toString(ENC_UTF8)
  return JSON.parse(plaintext)
}
function setCache(key, value) {
  const encryptValue = AES.encrypt(JSON.stringify(value), LOCAL_ENCRYPTED_KEY).toString()
  return cache.set(key, encryptValue)
}
function deleteCache(key) {
  return cache.delete(key)
}
function getCacheWrapper(key) {
  if (isEncrypt || isEncryptPartial) {
    return getCache(key)
  } else {
    return cache.get(key)
  }
}
function setCacheWrapper(key, value) {
  if (isEncrypt || isEncryptPartial) {
    return setCache(key, value)
  } else {
    return cache.set(key, value)
  }
}
export const wsCache = {
  get: getCacheWrapper,
  set: setCacheWrapper,
  delete: deleteCache
}
src/components/layout/components/AppMain.vue
New file
@@ -0,0 +1,35 @@
<template>
  <div class="app-main">
    <AppHeader :headerTitle="$route.meta.title" />
    <transition>
      <router-view :key="key" />
    </transition>
  </div>
</template>
<script>
import AppHeader from "./appHeader/index.vue"
export default {
  name: "AppMain",
  components: { AppHeader },
  props: {},
  computed: {
    key() {
      return this.$route.fullPath
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.app-main {
  margin-left: 10px;
  box-sizing: border-box;
  display: flex;
  flex: 1;
  flex-direction: column;
  // height: 100%;
  width: 100%;
}
</style>
src/components/layout/components/appHeader/index.vue
New file
@@ -0,0 +1,29 @@
<template>
  <div class="sales-lead">
    <div class="header-title">{{ headerTitle }}</div>
  </div>
</template>
<script>
export default {
  name: "SalesLead",
  props: {
    headerTitle: String
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.sales-lead {
  height: 55px;
  line-height: 55px;
  background-color: #fff;
  margin-bottom: 10px;
  .header-title {
    margin-left: 16px;
    font-size: 16px;
    color: #475059;
  }
}
</style>
src/components/layout/components/appsidebar/index.scss
New file
@@ -0,0 +1,14 @@
.app-sidebar {
  position: relative;
  height: 100%;
  background-color: #545c64;
  .box {
    width: 200px;
    .el-menu {
      border-right: solid 0px #e6e6e6;
    }
    .el-submenu .el-menu-item {
      min-width: none;
    }
  }
}
src/components/layout/components/appsidebar/index.vue
New file
@@ -0,0 +1,78 @@
<!--导航组件-->
<template>
  <div class="app-sidebar">
    <div class="box">
      <el-menu
        router
        :default-active="$route.path"
        class="el-menu-vertical-demo"
        @select="handleOpen"
        @close="handleClose"
        background-color="#545c64"
        text-color="#fff"
        active-text-color="#ffd04b"
      >
        <el-submenu index="">
          <template slot="title">
            <i class="el-icon-location"></i>
            <span>客户管理</span>
          </template>
          <el-menu-item index="/custom/salesLead">销售线索</el-menu-item>
          <el-menu-item index="/custom/customManage">客户管理</el-menu-item>
          <el-menu-item index="/custom/contacts">联系人</el-menu-item>
          <el-menu-item index="/custom/followupRecords">跟进记录</el-menu-item>
        </el-submenu>
        <el-submenu index="2">
          <template slot="title">
            <i class="el-icon-location"></i>
            <span>销售管理</span>
          </template>
        </el-submenu>
        <el-submenu index="3">
          <template slot="title">
            <i class="el-icon-location"></i>
            <span>服务管理</span>
          </template>
          <el-menu-item index="/service/serviceContract">服务合同</el-menu-item>
          <el-menu-item index="/service/orderManage">工单管理</el-menu-item>
          <el-menu-item index="/service/serviceFollowup">服务回访单</el-menu-item>
          <el-menu-item index="/service/serviceFeeManage">服务收费管理</el-menu-item>
        </el-submenu>
      </el-menu>
    </div>
  </div>
</template>
<script>
export default {
  name: "AppSidebar",
  props: {},
  data() {
    return {}
  },
  watch: {
    // $route: {
    //   handler: "initNavMenu",
    //   immediate: true
    // }
  },
  created() {
    this.initNavMenu()
  },
  methods: {
    // 监听路由
    initNavMenu() {
      // console.log(this.$route.name)
    },
    handleOpen(index) {
      console.log("aaa", index)
    },
    handleClose() {}
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
@import "./index.scss";
</style>
src/components/layout/index.vue
New file
@@ -0,0 +1,28 @@
<template>
  <div class="app-content">
    <AppSidebar ref="sideBar" />
    <AppMain />
  </div>
</template>
<script>
import AppSidebar from "./components/appsidebar/index.vue"
import AppMain from "./components/AppMain.vue"
export default {
  name: "AppContainer",
  components: {
    AppSidebar,
    AppMain
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.app-content {
  display: flex;
  box-sizing: border-box;
  height: 100%;
  width: 100%;
}
</style>
src/components/makepager/CommonSelectView.vue
New file
@@ -0,0 +1,46 @@
<template>
  <div class="common-select">
    <el-select v-model="commonDefautValue" placeholder="请选择" class="common-select-sel" size="mini">
      <el-option v-for="item in commonOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
    </el-select>
    <div class="common-select-btn">
      <i class="el-icon-setting"></i>
    </div>
  </div>
</template>
<script>
export default {
  name: "CommonSelectView",
  props: {
    commonValue: {
      type: String,
      default: ""
    },
    commonOptions: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      commonDefautValue: this.commonValue
    }
  },
  methods: {}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.common-select {
  display: flex;
  .common-select-sel {
    width: 270px;
  }
  .common-select-btn {
    margin-left: 5px;
    font-size: 16px;
  }
}
</style>
src/components/makepager/PagerView.vue
New file
@@ -0,0 +1,50 @@
<template>
  <div class="page-view">
    <el-pagination
      :current-page="pageOptions.currPage"
      :page-sizes="pageSizes"
      :page-size="pageOptions.pageSize"
      :layout="layout"
      :total="pageOptions.totalCount"
      v-on="$listeners"
    >
    </el-pagination>
  </div>
</template>
<script>
export default {
  name: "PagerView",
  props: {
    pageSizes: {
      type: Array,
      default: () => [10, 20, 30, 40]
    },
    layout: {
      type: String,
      default: "total, sizes, prev, pager, next"
    },
    pageOptions: {
      type: Object,
      default: () => {
        return {
          currPage: 1,
          pageSize: 10,
          totalCount: 0
        }
      }
    }
  },
  data() {
    return {}
  },
  methods: {}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.page-view {
  margin-top: 10px;
}
</style>
src/components/makepager/PublicFunctionBtnView.vue
New file
@@ -0,0 +1,192 @@
<template>
  <div class="function-btn">
    <div class="btn-list">
      <el-button size="small" type="text" class="blue" @click="addBtnClick">新建</el-button>
      <el-button v-if="receive" size="small" type="text" class="gray" @click="receiveBtnClick">领取</el-button>
      <el-button size="small" type="text" class="gray" @click="allocationBtnClick">分配</el-button>
      <el-button size="small" type="text" class="gray" @click="deleteBtnClick">删除</el-button>
      <el-button v-if="submitApproval" size="small" type="text" class="gray width64" @click="submitApprovalBtnClick"
        >提交审批</el-button
      >
      <el-button v-if="duplicateCheck" size="small" type="text" class="gray" @click="duplicateCheckBtnClick"
        >查重</el-button
      >
      <el-button v-if="importButton" size="small" type="text" class="gray" @click="importBtnClick">导入</el-button>
      <el-dropdown trigger="click">
        <div class="gray btn-icon" @click="operateBtnClick">
          <i class="el-icon-present"></i>
        </div>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item
            v-for="operate in operatesList"
            @click.native="getOperateClick(operate)"
            :key="operate.id"
            >{{ operate.name }}</el-dropdown-item
          >
        </el-dropdown-menu>
      </el-dropdown>
      <div class="view-scope">
        <div class="view-scope-title">查看范围</div>
        <el-select v-model="viewScopeValue" placeholder="请选择" class="view-scope-sel" size="mini">
          <el-option v-for="item in viewScopeOptions" :key="item.value" :label="item.label" :value="item.value">
          </el-option>
        </el-select>
        <div class="view-scope-btn">
          <i class="el-icon-user"></i>
        </div>
      </div>
      <!-- 列表 -->
      <div v-if="listButton" class="gray btn-icon" @click="listBtnClick">
        <i class="el-icon-tickets"></i>
      </div>
      <!-- 地图 -->
      <div v-if="mapButton" class="gray btn-icon" @click="mapBtnClick">
        <i class="el-icon-location-information"></i>
      </div>
      <!-- 统计 -->
      <div v-if="statistics" class="gray btn-icon" @click="statisticsBtnClick">
        <i class="el-icon-data-line"></i>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "PublicFunctionBtnView",
  props: {
    receive: {
      type: Boolean,
      default: false
    },
    duplicateCheck: {
      type: Boolean,
      default: false
    },
    submitApproval: {
      type: Boolean,
      default: false
    },
    listButton: {
      type: Boolean,
      default: false
    },
    importButton: {
      type: Boolean,
      default: true
    },
    mapButton: {
      type: Boolean,
      default: false
    },
    statistics: {
      type: Boolean,
      default: false
    },
    operatesList: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      viewScopeOptions: [
        { value: "1", label: "全部" },
        { value: "2", label: "高级" },
        { value: "3", label: "我负责的" },
        { value: "4", label: "我创建的" },
        { value: "5", label: "共享给我的" },
        { value: "6", label: "我共享给他人的" }
      ],
      viewScopeValue: "全部"
    }
  },
  methods: {
    // 新建
    addBtnClick() {
      this.$parent.addBtnClick()
    },
    // 领取
    receiveBtnClick() {},
    // 分配
    allocationBtnClick() {},
    // 删除
    deleteBtnClick() {},
    // 提交审批
    submitApprovalBtnClick() {},
    // 查重
    duplicateCheckBtnClick() {},
    // 导入
    importBtnClick() {},
    // 操作
    operateBtnClick() {},
    // 列表
    listBtnClick() {},
    // 地图
    mapBtnClick() {},
    // 统计
    statisticsBtnClick() {},
    // 操作图标按钮
    getOperateClick(operate) {
      console.log(operate)
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.function-btn {
  margin-top: 10px;
  margin-left: 10px;
  .btn-list {
    display: flex;
    .el-button {
      height: 32px;
    }
    .blue {
      background-color: #2185ee;
      width: 54px;
      color: #ffffff;
    }
    .gray {
      background-color: #f0f3f7;
      width: 54px;
      color: #666;
    }
    .width64 {
      width: 64px;
    }
    .btn-icon {
      width: 48px;
      margin-left: 10px;
      height: 32px;
      line-height: 32px;
      text-align: center;
      font-size: 20px;
      border-radius: 4px;
      color: rgb(0, 102, 255);
    }
    .view-scope {
      display: flex;
      height: 32px;
      line-height: 32px;
      .view-scope-title {
        margin-left: 10px;
        font-size: 13px;
        color: #333;
      }
      .view-scope-sel {
        width: 165px;
        margin-left: 10px;
      }
      .view-scope-btn {
        font-size: 16px;
        margin-left: 10px;
        color: #bebebe;
      }
    }
  }
}
</style>
src/components/makepager/SearchCommonView.vue
New file
@@ -0,0 +1,302 @@
<template>
  <div class="search-list">
    <div class="search-top">
      <div class="query-class">
        <div class="query-class-title">查询分类</div>
        <el-select v-model="queryClassValue" placeholder="请选择" class="query-class-sel" size="mini">
          <el-option v-for="item in queryClassOptions" :key="item.value" :label="item.label" :value="item.value">
          </el-option>
        </el-select>
        <div class="query-class-btn">
          <i class="el-icon-setting"></i>
        </div>
      </div>
      <div class="search">
        <el-input placeholder="请输入内容" v-model="searchInput" class="input-with-select" clearable>
          <el-select v-model="searchSelValue" slot="prepend" placeholder="请选择" class="search-sel">
            <el-option v-for="item in searchOptions" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-select>
          <i slot="suffix" class="el-icon-search" style="cursor: pointer" @click="searchClick"></i>
        </el-input>
      </div>
      <div class="other-search">
        <div class="other-search-high" @click="highSearchClick">
          <div class="high-icon"><i class="el-icon-postcard"></i></div>
          <div>高级查找</div>
        </div>
        <div class="other-search-tile" @click="tileSearchClick">
          <div class="high-icon"><i class="el-icon-news"></i></div>
          <div>平铺查找</div>
        </div>
      </div>
    </div>
    <div v-if="isTileSearch" class="search-bottom">
      <el-table :data="tileSearchData" style="width: 100%">
        <el-table-column prop="selField" label="选择字段" width="430">
          <template slot-scope="scope">
            <el-select v-model="scope.row[scope.column.property]">
              <el-option v-for="(row, index) in selFieldList" :key="index" :label="row" :value="row"> </el-option>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column prop="selCondition" label="选择条件" width="350">
          <template slot-scope="scope">
            <el-select v-model="scope.row[scope.column.property]" style="width: 340px">
              <el-option v-for="(row, index) in selConditionList" :key="index" :label="row" :value="row"> </el-option>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column prop="keywords" label="关键字">
          <template slot-scope="scope">
            <el-input v-model="scope.row[scope.column.property]" placeholder="请输入内容"></el-input>
          </template>
        </el-table-column>
        <el-table-column prop="filterCriteria" label="筛选条件" width="100">
          <template slot-scope="scope">
            <el-select v-model="scope.row[scope.column.property]">
              <el-option v-for="(row, index) in filterCriteriaList" :key="index" :label="row" :value="row"> </el-option>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="" width="60">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="add-btn">
        <el-button @click="addBtn" type="text" size="small">新条件</el-button>
      </div>
      <div class="others-btn">
        <div class="hide-switch">
          <span>查找后自动隐藏</span>
          <el-switch v-model="value2" active-color="#2e68db" inactive-color="#AEB9CA" @change="hideSwitch"></el-switch>
        </div>
        <div>
          <el-button type="text" size="small" class="blue">立即查找</el-button>
          <el-button size="small">取消</el-button>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "SearchCommonView",
  props: {
    queryClass: {
      type: String,
      default: "1"
    },
    queryClassOptions: {
      type: Array,
      default: () => []
    },
    searchSel: {
      type: String,
      default: "1"
    },
    searchOptions: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      // queryClassOptions: [
      //   { value: "1", label: "全部" },
      //   { value: "2", label: "广告宣传" },
      //   { value: "3", label: "跟进中" },
      //   { value: "4", label: "失败关闭" }
      // ],
      queryClassValue: this.queryClass,
      searchInput: "",
      searchSelValue: this.searchSel,
      // searchOptions: [
      //   { value: "1", label: "客户名称" },
      //   { value: "2", label: "销售线索编号" },
      //   { value: "3", label: "联系人姓名" },
      //   { value: "4", label: "手机号码" },
      //   { value: "5", label: "商机来源" },
      //   { value: "6", label: "省份" },
      //   { value: "7", label: "城市" },
      //   { value: "8", label: "负责人" }
      // ],
      isTileSearch: false,
      tileSearchData: [
        {
          selField: "客户名称",
          selCondition: "包含",
          keywords: "",
          filterCriteria: "且"
        },
        {
          selField: "客户名称",
          selCondition: "包含",
          keywords: "",
          filterCriteria: "且"
        },
        {
          selField: "客户名称",
          selCondition: "包含",
          keywords: "",
          filterCriteria: "且"
        }
      ],
      selFieldList: ["客户名称", "销售线索编号", "联系人职务"],
      selConditionList: ["无", "包含", "等于", "不等于", "不包含", "是空值", "不是空值"],
      filterCriteriaList: ["且", "或"],
      value2: true
    }
  },
  methods: {
    searchClick() {
      console.log("sssssssssss")
    },
    // 高级查找
    highSearchClick() {},
    // 平铺查找
    tileSearchClick() {
      this.isTileSearch = !this.isTileSearch
    },
    // 删除
    handleClick(row) {
      console.log(row)
    },
    // 新条件
    addBtn() {
      this.tileSearchData.push({
        selField: "客户名称",
        selCondition: "包含",
        keywords: "",
        filterCriteria: "且"
      })
    },
    // 查找后是否隐藏
    hideSwitch() {}
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.search-list {
  font-size: 13px;
  color: #333;
  .search-top {
    display: flex;
    .query-class {
      display: flex;
      height: 60px;
      line-height: 60px;
      .query-class-title {
        margin-left: 10px;
      }
      .query-class-sel {
        width: 165px;
        margin-left: 10px;
      }
      .query-class-btn {
        font-size: 16px;
        margin-left: 10px;
        color: #bebebe;
      }
    }
    .search {
      height: 60px;
      line-height: 60px;
      margin-left: 20px;
      .el-icon-search {
        margin-top: 7px;
      }
    }
    .other-search {
      display: flex;
      height: 60px;
      line-height: 60px;
      margin-left: 20px;
      .other-search-high {
        display: flex;
        .high-icon {
          font-size: 18px;
        }
      }
      .other-search-tile {
        display: flex;
        margin-left: 20px;
        .high-icon {
          font-size: 18px;
        }
      }
    }
  }
  .search-bottom {
    background-color: #fff;
    .add-btn {
      margin-left: 10px;
    }
    .others-btn {
      position: relative;
      display: flex;
      justify-content: center;
      height: 55px;
      line-height: 55px;
      background-color: #f5f5f5;
      border-bottom: 1px solid #dadee5;
      .blue {
        background-color: #2185ee;
        width: 74px;
        color: #ffffff;
      }
      .hide-switch {
        position: absolute;
        left: 20px;
        .el-switch {
          margin-left: 10px;
        }
      }
    }
  }
}
::v-deep {
  .el-input__inner {
    height: 30px;
    color: #2765e1;
  }
  .el-input__prefix,
  .el-input__suffix {
    height: 30px;
  }
  .el-input__icon {
    line-height: 30px;
  }
  .search {
    .el-select .el-input {
      width: 115px;
    }
    .input-with-select .el-input-group__prepend {
      background-color: #fff;
    }
    .el-input__suffix {
      // 处理前缀图标不垂直居中的问题
      height: auto;
      font-size: 15px;
      &-inner {
        flex-direction: row-reverse;
        -webkit-flex-direction: row-reverse;
        display: flex;
      }
    }
    .el-input--suffix .el-input__inner {
      padding-right: 45px;
    }
    .search-sel .el-input--suffix .el-input__inner {
      padding-left: 5px;
      padding-right: 20px;
    }
  }
}
</style>
src/components/makepager/TableCommonView.vue
New file
@@ -0,0 +1,75 @@
<template>
  <div class="page-view">
    <el-table
      ref="table"
      border
      :data="tableList.tableInfomation"
      tooltip-effect="dark"
      style="width: 100%"
      :lazy="tableList.lazy"
      @selection-change="handleSelectionChange"
      :header-cell-style="{ background: '#ECF4FF', color: '#666' }"
    >
      <el-table-column type="selection" width="55"> </el-table-column>
      <el-table-column
        v-for="(item, i) in tableList.tableColumn"
        :key="i"
        :prop="item.prop"
        :label="item.label"
        :width="item.width"
        :min-width="item.min"
        sortable
      >
      </el-table-column>
      <slot name="tableButton" />
    </el-table>
  </div>
</template>
<script>
export default {
  name: "PagerView",
  props: {
    tableList: {
      type: Object,
      default: () => {
        return {
          tableInfomation: [], // 接口返回数据
          tableColumn: [
            // table表单
            { label: "", prop: "", min: 200, tooltip: true }
          ]
        }
      }
    }
  },
  data() {
    return {}
  },
  computed: {
    maxHeight() {
      if (this.tableList.height) {
        return `calc(100vh - ${this.tableList.height})`
      }
      return undefined
    }
  },
  methods: {
    handleReserve(row) {
      return row._id ? row._id : row.id
    },
    handleSelectionChange(val) {
      this.$emit("getSelectArray", val)
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.page-view {
  margin-top: 20px;
  margin-right: 10px;
  margin-bottom: 40px;
}
</style>
src/i18n/en-US.js
New file
@@ -0,0 +1,80 @@
import statusCode from "./en-code"
// placeholder 和 validate
const FormPlaceHolderAndValidate = {
  placeHolder: {
    // 表单国际化
    input: "place input",
    inputField: "please input {field}"
  },
  validate: {
    // 校验国际化
    notAllowedRepeat: "{field} can not repeat"
  }
}
// Nav Menu Button
const NavMenuAndButton = {
  nav: {
    KHGL: "Account", // 客户管理
    XSGL: "Sales", // 销售管理
    FWGL: "Service" // 服务管理
  },
  menu: {
    // 菜单国际化
    "KHGL-XSXS": "Leads",
    "KHGL-KHGL": "Accounts",
    "KHGL-LXR": "Contacts",
    "KHGL-YJJL": "Contact Records"
  },
  button: {
    // 按钮
    add: "Add",
    edit: "Edit"
  }
}
// http状态码
const HttpStatusCode = {
  businessStatusCode: {
    ...statusCode
  },
  statusCode: {
    newErr: "there's something wrong with the network", // 网络出问题了
    404: "the request cannot be found, please cantact the administrator", // 请求找不到,请联系管理员
    500: "server error", // 服务器错误
    502: "your network is out of date",
    400: "the request cannot be found, please cantact the administrator",
    420: "request method failed"
  }
}
// 其他
const Others = {
  message: {
    // 本地提示信息
    add: "{field} created successfully"
  },
  title: {
    cancel: "cancel"
  },
  confirm: {
    deleteRow: "are you sure to delete {rowName}?"
  }
}
// 业务字段
const Bussiness = {
  // 登录页面
  loginAccountNumber: "account number",
  loginPassword: "password",
  loginBtn: "log on"
}
export default {
  ...FormPlaceHolderAndValidate,
  ...NavMenuAndButton,
  ...HttpStatusCode,
  ...Others,
  ...Bussiness
}
src/i18n/en-code.js
New file
@@ -0,0 +1,3 @@
const code = {}
export default code
src/i18n/index.js
New file
@@ -0,0 +1,35 @@
import Vue from "vue"
import VueI18n from "vue-i18n"
// 导入本地国际化文件
import enLocal from "./en-US"
import zhLocal from "./zh-CN"
const messages = {
  "en-US": {
    ...enLocal
  },
  "zh-CN": {
    ...zhLocal
  }
}
Vue.use(VueI18n)
const i18n = new VueI18n({
  locale: "zh-CN",
  messages
})
function t(key, ...args) {
  if (args.length === 0) {
    return i18n.t(key)
  } else if (args.length === 1 && (typeof args[0]).toLowerCase() === "string") {
    return i18n.t(key, { field: i18n.t(args[0]) })
  } else if (args.length === 1 && (typeof args[0]).toLowerCase() === "object") {
    let obj = {}
    return i18n.t(key, obj)
  } else {
    throw new Error("出错了,请联系管理员")
  }
}
export { i18n as default, t }
src/i18n/zh-CN.js
New file
@@ -0,0 +1,80 @@
import statusCode from "./zh-cn-code"
// placeholder 和 validate
const FormPlaceHolderAndValidate = {
  placeHolder: {
    // 表单国际化
    input: "请输入",
    inputField: "请输入{field}"
  },
  validate: {
    // 校验国际化
    notAllowedRepeat: "{field}不能重复"
  }
}
// Nav Menu Button
const NavMenuAndButton = {
  nav: {
    KHGL: "客户管理",
    XSGL: "销售管理",
    FWGL: "服务管理"
  },
  menu: {
    // 菜单国际化
    "KHGL-XSXS": "销售线索",
    "KHGL-KHGL": "客户管理",
    "KHGL-LXR": "联系人",
    "KHGL-YJJL": "跃进记录"
  },
  button: {
    // 按钮
    add: "新建",
    edit: "编辑"
  }
}
// http状态码
const HttpStatusCode = {
  businessStatusCode: {
    ...statusCode
  },
  statusCode: {
    newErr: "网络出问题了",
    404: "请求找不到,请联系管理员",
    500: "服务器错误",
    502: "你的网络开小差了",
    400: "请求找不到,请联系管理员",
    420: "请求方法失败"
  }
}
// 其他
const Others = {
  message: {
    // 本地提示信息
    add: "{field}创建成功"
  },
  title: {
    cancel: "取消"
  },
  confirm: {
    deleteRow: "您确定删除 - {rowName} 吗?"
  }
}
// 业务字段
const Bussiness = {
  // 登录页面
  loginAccountNumber: "账号",
  loginPassword: "密码",
  loginBtn: "登录"
}
export default {
  ...FormPlaceHolderAndValidate,
  ...NavMenuAndButton,
  ...HttpStatusCode,
  ...Others,
  ...Bussiness
}
src/i18n/zh-cn-code.js
New file
@@ -0,0 +1,3 @@
const code = {}
export default code
src/main.js
New file
@@ -0,0 +1,14 @@
import Vue from "vue"
import App from "./App.vue"
import router from "./router"
import ElementUI from "element-ui"
import "element-ui/lib/theme-chalk/index.css"
import "@/assets/style/index.scss"
Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
  router,
  render: (h) => h(App)
}).$mount("#app")
src/router/custom/index.js
New file
@@ -0,0 +1,43 @@
// const type from '@/router/deployCode'
const salesLead = (resolve) => require(["@/views/custom/salesLead/index"], resolve) // 销售线索
const customManage = (resolve) => require(["@/views/custom/customManage/index"], resolve) // 销售线索
const contacts = (resolve) => require(["@/views/custom/contacts/index"], resolve) // 联系人
const followupRecords = (resolve) => require(["@/views/custom/followupRecords/index"], resolve) // 跟进记录
const appconfig = [
  {
    path: "/custom/salesLead",
    name: "salesLead",
    component: salesLead,
    meta: {
      title: "销售线索"
    }
  },
  {
    path: "/custom/customManage",
    name: "customManage",
    component: customManage,
    meta: {
      title: "客户管理"
    }
  },
  {
    path: "/custom/contacts",
    name: "contacts",
    component: contacts,
    meta: {
      title: "联系人"
    }
  },
  {
    path: "/custom/followupRecords",
    name: "followupRecords",
    component: followupRecords,
    meta: {
      title: "跟进记录"
    }
  }
]
export default appconfig
src/router/deployCode.js
New file
@@ -0,0 +1,4 @@
const deployCode = {
  khgl: "KHGL"
}
export default deployCode
src/router/index.js
New file
@@ -0,0 +1,86 @@
import Vue from "vue"
import Router from "vue-router"
// import type from "@/router/deployCode"
import customRouter from "./custom/index.js"
// import salesRouter from "./sales/index.js"
import serviceRouter from "./service/index.js"
Vue.use(Router)
const login = (resolve) => require(["@/views/login/index"], resolve)
const custom = (resolve) => require(["@/views/custom/index"], resolve)
// const sales = (resolve) => require(["@/views/sales/index"], resolve)
const service = (resolve) => require(["@/views/service/index"], resolve)
export const routes = [
  {
    path: "custom", // 客户管理
    name: "custom",
    component: custom,
    children: customRouter,
    meta: {
      title: "客户管理",
      isAllways: true
    }
  },
  // {
  //   path: "sales", // 销售管理
  //   name: "sales",
  //   component: sales,
  //   children: salesRouter,
  //   meta: {
  //     title: "销售管理",
  //     isAllways: true
  //   }
  // },
  {
    path: "service", // 服务管理
    name: "service",
    component: service,
    children: serviceRouter,
    meta: {
      title: "服务管理",
      isAllways: true
    }
  }
]
export const constantRoutes = [
  {
    path: "/",
    component: () => import("@/components/layout/index"),
    name: "Index",
    meta: {
      title: "首页",
      isAllways: true,
      insIndex: true
    },
    redirect: {
      name: "custom"
    },
    children: routes
  },
  {
    path: "/login",
    component: login,
    meta: {
      isLogin: true,
      title: "登录"
    }
  },
  {
    path: "*",
    redirect: "/404"
  }
]
// 导出路由 在 main.js 里使用
const createRouter = () =>
  new Router({
    mode: "history",
    // base: window.getServerJson.context,
    scrollBehavior: () => ({ y: 0 }),
    routes: constantRoutes
  })
const router = createRouter()
export default router
src/router/sales/index.js
New file
@@ -0,0 +1,43 @@
// const type from '@/router/deployCode'
const salesLead = (resolve) => require(["@/views/custom/salesLead/index"], resolve) // 销售线索
const customManage = (resolve) => require(["@/views/custom/customManage/index"], resolve) // 销售线索
const contacts = (resolve) => require(["@/views/custom/contacts/index"], resolve) // 联系人
const followupRecords = (resolve) => require(["@/views/custom/followupRecords/index"], resolve) // 跟进记录
const appconfig = [
  {
    path: "/custom/salesLead",
    name: "salesLead",
    component: salesLead,
    meta: {
      title: "销售线索"
    }
  },
  {
    path: "/custom/customManage",
    name: "customManage",
    component: customManage,
    meta: {
      title: "客户管理"
    }
  },
  {
    path: "/custom/contacts",
    name: "contacts",
    component: contacts,
    meta: {
      title: "联系人"
    }
  },
  {
    path: "/custom/followupRecords",
    name: "followupRecords",
    component: followupRecords,
    meta: {
      title: "跟进记录"
    }
  }
]
export default appconfig
src/router/service/index.js
New file
@@ -0,0 +1,43 @@
// const type from '@/router/deployCode'
const serviceContract = (resolve) => require(["@/views/service/serviceContract/index"], resolve) // 服务合同
const orderManage = (resolve) => require(["@/views/service/orderManage/index"], resolve) // 工单管理
const serviceFollowup = (resolve) => require(["@/views/service/serviceFollowup/index"], resolve) // 服务回访单
const serviceFeeManage = (resolve) => require(["@/views/service/serviceFeeManage/index"], resolve) // 服务收费管理
const appconfig = [
  {
    path: "/service/serviceContract",
    name: "serviceContract",
    component: serviceContract,
    meta: {
      title: "服务合同"
    }
  },
  {
    path: "/service/orderManage",
    name: "orderManage",
    component: orderManage,
    meta: {
      title: "工单管理"
    }
  },
  {
    path: "/service/serviceFollowup",
    name: "serviceFollowup",
    component: serviceFollowup,
    meta: {
      title: "服务回访单"
    }
  },
  {
    path: "/service/serviceFeeManage",
    name: "serviceFeeManage",
    component: serviceFeeManage,
    meta: {
      title: "服务收费管理"
    }
  }
]
export default appconfig
src/views/custom/contacts/AddContactsDialog.vue
New file
@@ -0,0 +1,359 @@
<template>
  <div class="add-contacts">
    <el-dialog
      :title="editContactsConfig.title + '联系人'"
      :visible.sync="editConfig.visible"
      :width="dialogWidth"
      :before-close="handleClose"
    >
      <el-form
        ref="form"
        :model="editConfig.infomation"
        :rules="rules"
        label-position="right"
        label-width="308px"
        size="mini"
      >
        <!-- 信息 -->
        <div class="basic-info">
          <!-- 基本信息 -->
          <div v-if="isUnflod" class="basic-info-title">基本信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="联系人姓名" prop="contactName">
                  <el-input v-model="editConfig.infomation.contactName"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12" v-if="isUnflod">
                <el-form-item label="联系人编号" prop="contactNumber">
                  <el-button type="text" style="color: #333; font-size: 13px">
                    {{ editConfig.infomation.contactNumber }}
                  </el-button>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="客户名称" prop="customName">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.customName"></el-input>
                    <div class="common-select-btn">
                      <i class="el-icon-circle-plus-outline"></i>
                    </div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="手机" prop="phoneNumber">
                  <el-input v-model="editConfig.infomation.phoneNumber"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="职务" prop="duties">
                  <el-input v-model="editConfig.infomation.duties"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item v-if="isUnflod" label="销售负责人" prop="salesHead">
                  <el-select v-model="editConfig.infomation.salesHead" placeholder="请选择" size="mini">
                    <el-option
                      v-for="item in salesHeadOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item v-if="isUnflod" label="首要联系人" prop="primaryContact">
                  <el-switch
                    v-model="editConfig.infomation.primaryContact"
                    active-color="#2E68DB"
                    inactive-color="#AEB9CA"
                  >
                  </el-switch>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item v-if="isUnflod" label="微信号" prop="wechat">
                  <el-input v-model="editConfig.infomation.wechat"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item v-if="isUnflod" label="生日" prop="birhday">
                  <el-date-picker v-model="editConfig.infomation.birhday" type="date" placeholder="选择日期">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系人Email" prop="contactsEmail">
                  <el-input v-model="editConfig.infomation.contactsEmail"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="isUnflod ? 24 : 12">
                <el-form-item label="下次回访日期" prop="nextFollowupDate"></el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 地址信息 -->
          <div v-if="isUnflod" class="basic-info-title">地址信息</div>
          <div v-if="isUnflod" class="address-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="国家" prop="country">
                  <CommonSelectView :common-value="editConfig.infomation.country" :common-options="countryOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="省份" prop="province">
                  <CommonSelectView :common-value="editConfig.infomation.province" :common-options="provinceOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="城市" prop="city">
                  <CommonSelectView :common-value="editConfig.infomation.city" :common-options="cityOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="区域" prop="region">
                  <CommonSelectView :common-value="editConfig.infomation.region" :common-options="regionOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="邮编" prop="postalCode">
                  <el-input v-model="editConfig.infomation.postalCode"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 备注信息 -->
          <div v-if="isUnflod" class="basic-info-title">备注信息</div>
          <div v-if="isUnflod" class="basic-info-view">
            <el-row>
              <el-col :span="24">
                <el-form-item label="备注" prop="notes">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    placeholder="请输入内容"
                    v-model="editConfig.infomation.notes"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 附件信息 -->
          <div v-if="isUnflod" class="basic-info-title">附件信息</div>
          <div v-if="isUnflod" class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="附件" prop="">
                  <div class="annex-view">
                    <div @click="addAnnexClick">添加</div>
                    <div class="setFormat" @click="setFormatClick">设置允许上传的文件格式</div>
                  </div>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </div>
        <!-- 展开收起 -->
        <div v-if="editConfig.title === '新建'" class="unflod-collapse" @click="unflodCollapseClick">
          <div>{{ unflodCollapseStr }}</div>
          <div v-if="isUnflod"><i class="el-icon-arrow-up"></i></div>
          <div v-else><i class="el-icon-arrow-down"></i></div>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" size="small" @click="editConfig.visible = false">保 存</el-button>
        <el-button size="small" @click="editConfig.visible = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import CommonSelectView from "@/components/makepager/CommonSelectView"
export default {
  name: "AddContactsDialog",
  props: {
    editContactsConfig: {
      type: Object,
      default: () => {
        return {
          visible: false,
          title: "新建",
          infomation: {
            contactName: "",
            contactNumber: "LEA50",
            customName: "",
            phoneNumber: "",
            duties: "",
            salesHead: "5",
            primaryContact: "新建",
            wechat: "1",
            birhday: "",
            contactsEmail: "",
            nextFollowupDate: "",
            country: "1",
            province: "1",
            city: "1",
            region: "1",
            postalCode: "",
            notes: ""
          }
        }
      }
    }
  },
  components: { CommonSelectView },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      dialogWidth: "80%",
      editConfig: this.editContactsConfig,
      rules: {
        contactName: [{ required: true, message: "请输入联系人姓名", trigger: "blur" }],
        contactNumber: [{ required: true, message: "请输入联系人编号", trigger: "blur" }],
        salesHead: [{ required: true, message: "请选择销售负责人", trigger: "change" }]
      },
      businessSourceOptions: [
        { value: "1", label: "后台注册" },
        { value: "2", label: "代理商客户" },
        { value: "3", label: "电话陌生拜访" },
        { value: "4", label: "直接访问" },
        { value: "5", label: "项目合作" },
        { value: "6", label: "个人自找" },
        { value: "7", label: "二次销售" },
        { value: "8", label: "公司电话" }
      ],
      salesHeadOptions: [
        { value: "1", label: "BOSS" },
        { value: "2", label: "Mia" },
        { value: "3", label: "财务" },
        { value: "4", label: "市场" },
        { value: "5", label: "系统管理员" },
        { value: "6", label: "销售" },
        { value: "7", label: "销售总监" }
      ],
      countryOptions: [{ value: "1", label: "中国" }], // 国家
      provinceOptions: [
        { value: "1", label: "北京市" },
        { value: "2", label: "上海市" },
        { value: "3", label: "吉林省" },
        { value: "4", label: "陕西省" }
      ], // 省份
      cityOptions: [
        { value: "1", label: "北京市" },
        { value: "2", label: "上海市" },
        { value: "3", label: "吉林市" },
        { value: "4", label: "西安市" }
      ], // 城市
      regionOptions: [
        { value: "1", label: "朝阳区" },
        { value: "2", label: "海淀区" },
        { value: "3", label: "通州区" },
        { value: "4", label: "西城区" }
      ], // 区域
      unflodCollapseStr: "收起",
      isUnflod: true
    }
  },
  created() {},
  methods: {
    handleClose() {
      this.editConfig.visible = false
    },
    // 添加附件
    addAnnexClick() {},
    // 设置允许上传文件格式
    setFormatClick() {},
    // 展开收起
    unflodCollapseClick() {
      if (this.unflodCollapseStr === "收起") {
        this.unflodCollapseStr = "展开更多栏目"
        this.isUnflod = false
      } else {
        this.unflodCollapseStr = "收起"
        this.isUnflod = true
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.add-contacts {
  .basic-info {
    .basic-info-title {
      background-color: #f4f8fe;
      padding-left: 10px;
      font-size: 15px;
      font-weight: bold;
      color: #666;
      height: 42px;
      line-height: 42px;
    }
    .basic-info-view {
      margin-top: 10px;
      padding-right: 40px;
      .custom-name {
        display: flex;
        .common-select-btn {
          margin-left: 5px;
          font-size: 16px;
        }
      }
    }
    .address-view {
      margin-top: 10px;
      padding-right: 40px;
    }
    .annex-view {
      display: flex;
      color: #6166d3;
      .setFormat {
        margin-left: 10px;
      }
    }
  }
  .unflod-collapse {
    display: flex;
    height: 30px;
    justify-content: center;
    align-items: center;
    color: #6166d3;
  }
  .dialog-footer {
    background-color: #f5f5f5;
    height: 55px;
    line-height: 55px;
  }
}
::v-deep {
  .el-dialog__header {
    padding: 12.5px 10px;
    border-bottom: 1px solid #e5e5e5;
    .el-dialog__title {
      font-size: 15px;
      color: #323232;
      font-weight: bold;
    }
  }
  .el-dialog__body {
    padding: 0px;
  }
  .el-dialog__footer {
    padding: 0px;
    text-align: center;
    box-sizing: border-box;
    border-top: 1px solid #dadee5;
  }
}
</style>
src/views/custom/contacts/index.vue
New file
@@ -0,0 +1,164 @@
<template>
  <div class="contacts-view">
    <SearchCommonView ref="searchCommonView" :query-class-options="queryClassOptions" :search-options="searchOptions" />
    <div class="btn-pager">
      <PublicFunctionBtnView :operates-list="operatesList" />
      <PagerView class="page" />
    </div>
    <TableCommonView ref="tableListRef" :table-list="tableList">
      <template slot="tableButton">
        <el-table-column label="操作" width="120" fixed="right">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small">编辑</el-button>
            <el-button type="text" size="small">跟进</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCommonView>
    <!-- 新建/编辑联系人 -->
    <AddContactsDialog v-if="editConfig.visible" :edit-contacts-config="editConfig" />
  </div>
</template>
<script>
import SearchCommonView from "@/components/makepager/SearchCommonView"
import PublicFunctionBtnView from "@/components/makepager/PublicFunctionBtnView"
import PagerView from "@/components/makepager/PagerView"
import TableCommonView from "@/components/makepager/TableCommonView"
import AddContactsDialog from "@/views/custom/contacts/AddContactsDialog"
export default {
  name: "ContactsView",
  props: {},
  components: {
    SearchCommonView,
    PublicFunctionBtnView,
    PagerView,
    TableCommonView,
    AddContactsDialog
  },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      tableList: {},
      queryClassOptions: [
        { value: "1", label: "全部" },
        { value: "2", label: "本月生日" }
      ],
      searchOptions: [],
      operatesList: [
        { id: "1", name: "共享" },
        { id: "2", name: "群发邮件" },
        { id: "3", name: "群发短信" },
        { id: "4", name: "批量编辑" },
        { id: "5", name: "导出" },
        { id: "6", name: "下载全部附件" },
        { id: "7", name: "合并" },
        { id: "8", name: "自动查重合并" },
        { id: "9", name: "树结构设置" },
        { id: "11", name: "审批设置" },
        { id: "12", name: "恢复预设列宽" }
      ],
      editConfig: {
        visible: false,
        title: "新建",
        infomation: {}
      }
    }
  },
  created() {
    this.setTable()
  },
  methods: {
    setTable() {
      this.tableList = {
        tableInfomation: [
          {
            contactName: "上海通用机械有限公司",
            customName: "BOSS",
            contactNumber: "C类客户",
            duties: "20",
            phoneNumber: "董奇伟",
            salesHead: "15988887777",
            primaryContact: "2023-07-26"
          }
        ],
        tableColumn: [
          { label: "联系人姓名", prop: "contactName", min: 100 }, // 联系人姓名
          { label: "客户名称", prop: "customName", min: 190 }, // 客户名称
          { label: "联系人编号", prop: "contactNumber", min: 100 }, // 联系人编号
          { label: "职务", prop: "duties", min: 120 }, // 职务
          { label: "手机", prop: "phoneNumber", min: 100 }, // 手机号码
          { label: "销售负责人", prop: "salesHead", min: 120 }, // 销售负责人
          { label: "首要联系人", prop: "primaryContact", min: 90 } // 首要联系人
        ]
      }
      this.searchOptions = []
      for (let i = 0; i < this.tableList.tableColumn.length; i++) {
        const label = this.tableList.tableColumn[i].label
        this.searchOptions.push({ value: (i + 1).toString(), label: label })
      }
    },
    // 新建
    addBtnClick() {
      this.editConfig.visible = true
      this.editConfig.title = "新建"
      this.editConfig.infomation = {
        customName: "",
        contactNumber: "LEA50",
        contactName: "",
        contactDuties: "",
        phoneNumber: "",
        businessStatus: "新建",
        businessSource: "1",
        owner: "",
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    },
    // 编辑
    handleClick(row) {
      console.log(row)
      this.editConfig.visible = true
      this.editConfig.title = "编辑"
      this.editConfig.infomation = {
        customName: row.customName,
        saleLeadNumber: row.saleLeadNumber,
        contactName: row.contactName,
        contactDuties: row.contactDuties,
        phoneNumber: row.phoneNumber,
        businessStatus: "新建",
        businessSource: row.businessSource,
        owner: row.owner,
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.contacts-view {
  .btn-pager {
    display: flex;
    .page {
      margin-left: auto;
    }
  }
}
</style>
src/views/custom/customManage/AddCustomManageDialog.vue
New file
@@ -0,0 +1,542 @@
<template>
  <div class="add-custom-manage">
    <el-dialog
      :title="editContactsConfig.title + '客户管理'"
      :visible.sync="editConfig.visible"
      :width="dialogWidth"
      :before-close="handleClose"
    >
      <el-form
        ref="form"
        :model="editConfig.infomation"
        :rules="rules"
        label-position="right"
        label-width="308px"
        size="mini"
        style="height: 60vh; overflow-x: hidden"
      >
        <!-- 信息 -->
        <div class="basic-info">
          <!-- 基本信息 -->
          <div class="basic-info-title">基本信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="客户名称" prop="customName">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.customName"></el-input>
                    <div class="common-select-btn">
                      <i class="el-icon-brush" title="工商查询"></i>
                    </div>
                    <div class="common-select-btn">
                      <i class="el-icon-search" title="查重"></i>
                    </div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="客户编号" prop="customNumber">
                  <el-input v-model="editConfig.infomation.customNumber"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="客户状态" prop="customStatus">
                  <CommonSelectView
                    :common-value="editConfig.infomation.customStatus"
                    :common-options="customStatusOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="销售负责人" prop="salesHead">
                  <el-select
                    v-model="editConfig.infomation.salesHead"
                    placeholder="请选择"
                    size="mini"
                    style="width: 63%"
                  >
                    <el-option
                      v-for="item in salesHeadOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="客户类型" prop="customType">
                  <CommonSelectView
                    :common-value="editConfig.infomation.customType"
                    :common-options="customTypeOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="客户来源" prop="customSource">
                  <CommonSelectView
                    :common-value="editConfig.infomation.customSource"
                    :common-options="customSourceOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="重要级别" prop="importantLevel">
                  <CommonSelectView
                    :common-value="editConfig.infomation.importantLevel"
                    :common-options="importantLevelOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="服务代表" prop="serviceAgent">
                  <el-select
                    v-model="editConfig.infomation.serviceAgent"
                    placeholder="请选择"
                    size="mini"
                    style="width: 63%"
                  >
                    <el-option
                      v-for="item in serviceAgentOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="下次回访日期" prop="nextFollowupDate">
                  <el-date-picker v-model="editConfig.infomation.nextFollowupDate" type="date" placeholder="选择日期">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="最晚服务到期日" prop="latestServiceDate">
                  <el-date-picker v-model="editConfig.infomation.latestServiceDate" type="date" placeholder="选择日期">
                  </el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 客户首要联系人 -->
          <div class="basic-info-title">客户首要联系人</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="联系人姓名" prop="contactName">
                  <el-input v-model="editConfig.infomation.contactName"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系人手机" prop="phoneNumber">
                  <el-input v-model="editConfig.infomation.phoneNumber"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系人职务" prop="duties">
                  <el-input v-model="editConfig.infomation.duties"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系人微信" prop="wechat">
                  <el-input v-model="editConfig.infomation.wechat"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系人Email" prop="contactsEmail">
                  <el-input v-model="editConfig.infomation.contactsEmail"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 工商信息 -->
          <div class="basic-info-title">工商信息</div>
          <div class="address-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="所属行业" prop="industry">
                  <CommonSelectView :common-value="editConfig.infomation.industry" :common-options="industryOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="法定代表人" prop="legalPerson">
                  <el-input v-model="editConfig.infomation.legalPerson"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="注册时间" prop="registerTime">
                  <el-date-picker v-model="editConfig.infomation.registerTime" type="date" placeholder="选择日期">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="注册资金" prop="registerCapital">
                  <CommonSelectView
                    :common-value="editConfig.infomation.registerCapital"
                    :common-options="registerCapitalOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="公司性质" prop="companyNature">
                  <CommonSelectView
                    :common-value="editConfig.infomation.companyNature"
                    :common-options="companyNatureOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="客户规模" prop="customerSize">
                  <CommonSelectView
                    :common-value="editConfig.infomation.customerSize"
                    :common-options="customerSizeOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="经营范围" prop="operateRange">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    placeholder="请输入内容"
                    v-model="editConfig.infomation.operateRange"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 地址信息 -->
          <div class="basic-info-title">地址信息</div>
          <div class="address-view">
            <el-row>
              <el-col :span="24">
                <el-form-item label="定位" prop="position">
                  <el-input v-model="editConfig.infomation.position"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="地图" prop="map">
                  <div style="height: 100px"></div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="国家" prop="country">
                  <CommonSelectView :common-value="editConfig.infomation.country" :common-options="countryOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="省份" prop="province">
                  <CommonSelectView :common-value="editConfig.infomation.province" :common-options="provinceOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="城市" prop="city">
                  <CommonSelectView :common-value="editConfig.infomation.city" :common-options="cityOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="区域" prop="region">
                  <CommonSelectView :common-value="editConfig.infomation.region" :common-options="regionOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="详细地址" prop="address">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    placeholder="请输入内容"
                    v-model="editConfig.infomation.address"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 备注信息 -->
          <div class="basic-info-title">备注信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="24">
                <el-form-item label="备注" prop="notes">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    placeholder="请输入内容"
                    v-model="editConfig.infomation.notes"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 附件信息 -->
          <div class="basic-info-title">附件信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="附件" prop="">
                  <div class="annex-view">
                    <div @click="addAnnexClick">添加</div>
                    <div class="setFormat" @click="setFormatClick">设置允许上传的文件格式</div>
                  </div>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 选择审批流程 -->
          <div class="basic-info-title">选择审批流程</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="20">
                <el-form-item label="审批流程" prop="approvalWorkflow">
                  <el-select
                    v-model="editConfig.infomation.approvalWorkflow"
                    placeholder="请选择"
                    size="mini"
                    style="width: 100%"
                  >
                    <el-option
                      v-for="item in approvalWorkflowOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="20">
                <el-form-item label="审批步骤" prop="approvalSteps">
                  <el-input v-model="editConfig.infomation.approvalSteps"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="20">
                <el-form-item label="审批人" prop="approvalPerson">
                  <el-input v-model="editConfig.infomation.approvalPerson"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="20">
                <el-form-item label="需要加急审批" prop="approvalUrgent">
                  <el-checkbox v-model="editConfig.infomation.approvalUrgent"></el-checkbox>
                </el-form-item>
              </el-col>
              <el-col :span="20">
                <el-form-item label="审批意见" prop="approvalOpinion">
                  <el-input v-model="editConfig.infomation.approvalOpinion" type="textarea" :rows="2"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" size="small" @click="editConfig.visible = false">保并提交审批</el-button>
        <el-button type="primary" size="small" @click="editConfig.visible = false">保存</el-button>
        <el-button size="small" @click="editConfig.visible = false">取消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import CommonSelectView from "@/components/makepager/CommonSelectView"
export default {
  name: "AddCustomManageDialog",
  props: {
    editContactsConfig: {
      type: Object,
      default: () => {
        return {
          visible: false,
          title: "新建",
          infomation: {
            customName: "",
            customNumber: "AC6521",
            customStatus: "",
            salesHead: "5",
            customType: "",
            customSource: "",
            importantLevel: "",
            serviceAgent: "",
            nextFollowupDate: "",
            latestServiceDate: "",
            contactName: "",
            phoneNumber: "",
            duties: "",
            wechat: "1",
            contactsEmail: "",
            industry: "",
            legalPerson: "",
            registerTime: "",
            registerCapital: "",
            companyNature: "",
            customerSize: "",
            operateRange: "",
            position: "",
            map: "",
            country: "1",
            province: "1",
            city: "1",
            region: "1",
            notes: "",
            approvalWorkflow: "",
            approvalSteps: "",
            approvalPerson: "",
            approvalUrgent: "",
            approvalOpinion: ""
          }
        }
      }
    }
  },
  components: { CommonSelectView },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      dialogWidth: "80%",
      editConfig: this.editContactsConfig,
      rules: {
        customName: [{ required: true, message: "请输入客户名称", trigger: "blur" }],
        customStatus: [{ required: true, message: "请选择客户状态", trigger: "change" }],
        salesHead: [{ required: true, message: "请选择销售负责人", trigger: "change" }],
        approvalOpinion: [{ required: true, message: "请输入审批意见", trigger: "blur" }]
      },
      businessSourceOptions: [
        { value: "1", label: "后台注册" },
        { value: "2", label: "代理商客户" },
        { value: "3", label: "电话陌生拜访" },
        { value: "4", label: "直接访问" },
        { value: "5", label: "项目合作" },
        { value: "6", label: "个人自找" },
        { value: "7", label: "二次销售" },
        { value: "8", label: "公司电话" }
      ],
      salesHeadOptions: [
        { value: "1", label: "BOSS" },
        { value: "2", label: "Mia" },
        { value: "3", label: "财务" },
        { value: "4", label: "市场" },
        { value: "5", label: "系统管理员" },
        { value: "6", label: "销售" },
        { value: "7", label: "销售总监" }
      ],
      customStatusOptions: [], // 客户状态
      customTypeOptions: [], // 客户类型
      customSourceOptions: [], // 客户来源
      importantLevelOptions: [], // 重要级别
      serviceAgentOptions: [], // 服务代表
      industryOptions: [], // 所属行业
      registerCapitalOptions: [], // 注册资金
      companyNatureOptions: [], // 公司性质
      customerSizeOptions: [], // 客户规模
      countryOptions: [{ value: "1", label: "中国" }], // 国家
      provinceOptions: [
        { value: "1", label: "北京市" },
        { value: "2", label: "上海市" },
        { value: "3", label: "吉林省" },
        { value: "4", label: "陕西省" }
      ], // 省份
      cityOptions: [
        { value: "1", label: "北京市" },
        { value: "2", label: "上海市" },
        { value: "3", label: "吉林市" },
        { value: "4", label: "西安市" }
      ], // 城市
      regionOptions: [
        { value: "1", label: "朝阳区" },
        { value: "2", label: "海淀区" },
        { value: "3", label: "通州区" },
        { value: "4", label: "西城区" }
      ], // 区域
      approvalWorkflowOptions: [] // 审批流程
    }
  },
  created() {},
  methods: {
    handleClose() {
      this.editConfig.visible = false
    },
    // 添加附件
    addAnnexClick() {},
    // 设置允许上传文件格式
    setFormatClick() {}
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.add-custom-manage {
  .basic-info {
    .basic-info-title {
      background-color: #f4f8fe;
      padding-left: 10px;
      font-size: 15px;
      font-weight: bold;
      color: #666;
      height: 42px;
      line-height: 42px;
    }
    .basic-info-view {
      margin-top: 10px;
      padding-right: 40px;
      .custom-name {
        display: flex;
        .common-select-btn {
          margin-left: 5px;
          font-size: 18px;
        }
      }
    }
    .address-view {
      margin-top: 10px;
      padding-right: 40px;
    }
    .annex-view {
      display: flex;
      color: #6166d3;
      .setFormat {
        margin-left: 10px;
      }
    }
  }
  .unflod-collapse {
    display: flex;
    height: 30px;
    justify-content: center;
    align-items: center;
    color: #6166d3;
  }
  .dialog-footer {
    background-color: #f5f5f5;
    height: 55px;
    line-height: 55px;
  }
}
::v-deep {
  .el-dialog__header {
    padding: 12.5px 10px;
    border-bottom: 1px solid #e5e5e5;
    .el-dialog__title {
      font-size: 15px;
      color: #323232;
      font-weight: bold;
    }
  }
  .el-dialog__body {
    padding: 0px;
  }
  .el-dialog__footer {
    padding: 0px;
    text-align: center;
    box-sizing: border-box;
    border-top: 1px solid #dadee5;
  }
}
</style>
src/views/custom/customManage/index.vue
New file
@@ -0,0 +1,267 @@
<template>
  <div class="custom-manage">
    <div class="tab-view">
      <el-tabs v-model="activeName" @tab-click="tabsClick">
        <el-tab-pane label="全部(含所有公海)" name="first"></el-tab-pane>
        <el-tab-pane label="全部(含公海)" name="second"></el-tab-pane>
        <el-tab-pane label="全部(不含公海)" name="third"></el-tab-pane>
        <el-tab-pane label="公海已分配" name="fourth"></el-tab-pane>
        <el-tab-pane label="公未分配" name="aaa"></el-tab-pane>
      </el-tabs>
      <div class="sel-gonghai">
        <el-select v-model="gonghaiValue" placeholder="请选择" class="query-class-sel" size="mini">
          <el-option v-for="item in gonghaiOptions" :key="item.value" :label="item.label" :value="item.value">
          </el-option>
        </el-select>
        <div class="query-class-btn">
          <i class="el-icon-setting"></i>
        </div>
      </div>
    </div>
    <SearchCommonView ref="searchCommonView" :query-class-options="queryClassOptions" :search-options="searchOptions" />
    <div class="btn-pager">
      <PublicFunctionBtnView
        :duplicate-check="true"
        :list-button="true"
        :map-button="true"
        :statistics="true"
        :operates-list="operatesList"
      />
      <PagerView class="page" />
    </div>
    <TableCommonView ref="tableListRef" :table-list="tableList">
      <template slot="tableButton">
        <el-table-column label="操作" width="120" fixed="right">
          <template slot-scope="scope">
            <el-button type="text" size="small">变更公海</el-button>
            <el-button @click="handleClick(scope.row)" type="text" size="small">编辑</el-button>
            <el-button type="text" size="small">跟进</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCommonView>
    <!-- 新建/编辑客户管理 -->
    <AddCustomManageDialog v-if="editConfig.visible" :edit-contacts-config="editConfig" />
  </div>
</template>
<script>
import SearchCommonView from "@/components/makepager/SearchCommonView"
import PublicFunctionBtnView from "@/components/makepager/PublicFunctionBtnView"
import PagerView from "@/components/makepager/PagerView"
import TableCommonView from "@/components/makepager/TableCommonView"
import AddCustomManageDialog from "@/views/custom/customManage/AddCustomManageDialog"
export default {
  name: "CustomManage",
  props: {},
  components: {
    SearchCommonView,
    PublicFunctionBtnView,
    PagerView,
    TableCommonView,
    AddCustomManageDialog
  },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      tableList: {},
      activeName: "second",
      gonghaiValue: "",
      gonghaiOptions: [],
      queryClassOptions: [
        { value: "1", label: "全部" },
        { value: "2", label: "潜在客户" },
        { value: "3", label: "成交客户" },
        { value: "4", label: "今日待联系" },
        { value: "5", label: "本月需回访" },
        { value: "6", label: "超过15天未联系" }
      ],
      searchOptions: [],
      operatesList: [
        { id: "1", name: "共享" },
        { id: "2", name: "群发邮件" },
        { id: "3", name: "群发短信" },
        { id: "4", name: "批量编辑" },
        { id: "5", name: "变更公海" },
        { id: "6", name: "提交审批" },
        { id: "7", name: "导出" },
        { id: "8", name: "下载全部附件" }
      ],
      editConfig: {
        visible: false,
        title: "新建",
        infomation: {}
      }
    }
  },
  created() {
    this.setTable()
  },
  methods: {
    setTable() {
      this.tableList = {
        tableInfomation: [
          {
            customName: "上海通用机械有限公司",
            saleLeadOwner: "BOSS",
            importantLevel: "C类客户",
            notContactDay: "20",
            contactName: "董奇伟",
            phoneNumber: "15988887777",
            nextFollowDate: "2023-07-26",
            detailAddress: "上海市静安区威海路115号",
            customStatus: "潜在客户"
          }
        ],
        tableColumn: [
          { label: "客户名称", prop: "customName", min: 190 }, // 客户名称
          { label: "销售负责人", prop: "saleLeadOwner", min: 120 }, // 销售负责人
          { label: "重要级别", prop: "importantLevel", min: 120 }, // 重要级别
          { label: "下次回访日期", prop: "notContactDay", min: 90 }, // 未联系人天数
          { label: "手机号码", prop: "nextFollowDate", min: 150 }, // 下次回访日期
          { label: "详细地址", prop: "detailAddress", min: 290 }, // 详细地址
          { label: "客户状态", prop: "customStatus", min: 100 }, // 客户状态
          { label: "联系人姓名", prop: "contactName", min: 100 }, // 联系人姓名
          { label: "手机", prop: "phoneNumber", min: 100 } // 手机号码
        ]
      }
      this.searchOptions = []
      for (let i = 0; i < this.tableList.tableColumn.length; i++) {
        const label = this.tableList.tableColumn[i].label
        this.searchOptions.push({ value: (i + 1).toString(), label: label })
      }
    },
    tabsClick(tab, event) {
      console.log(tab, event)
    },
    // 新建
    addBtnClick() {
      this.editConfig.visible = true
      this.editConfig.title = "新建"
      this.editConfig.infomation = {
        customName: "",
        customNumber: "AC6521",
        customStatus: "",
        salesHead: "5",
        customType: "",
        customSource: "",
        importantLevel: "",
        serviceAgent: "",
        nextFollowupDate: "",
        latestServiceDate: "",
        contactName: "",
        phoneNumber: "",
        duties: "",
        wechat: "1",
        contactsEmail: "",
        industry: "",
        legalPerson: "",
        registerTime: "",
        registerCapital: "",
        companyNature: "",
        customerSize: "",
        operateRange: "",
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        notes: "",
        approvalWorkflow: "",
        approvalSteps: "",
        approvalPerson: "",
        approvalUrgent: "",
        approvalOpinion: ""
      }
    },
    // 编辑
    handleClick(row) {
      console.log(row)
      this.editConfig.visible = true
      this.editConfig.title = "编辑"
      this.editConfig.infomation = {
        customName: row.customName,
        customNumber: "AC6521",
        customStatus: "",
        salesHead: row.salesHead,
        customType: "",
        customSource: "",
        importantLevel: "",
        serviceAgent: "",
        nextFollowupDate: row.nextFollowupDate,
        latestServiceDate: "",
        contactName: row.contactName,
        phoneNumber: row.phoneNumber,
        duties: "",
        wechat: "1",
        contactsEmail: "",
        industry: "",
        legalPerson: "",
        registerTime: "",
        registerCapital: "",
        companyNature: "",
        customerSize: "",
        operateRange: "",
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        notes: "",
        approvalWorkflow: "",
        approvalSteps: "",
        approvalPerson: "",
        approvalUrgent: "",
        approvalOpinion: ""
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.custom-manage {
  .tab-view {
    position: relative;
    .sel-gonghai {
      display: flex;
      position: absolute;
      top: 5px;
      left: 660px;
      height: 35px;
      line-height: 35px;
      .query-class-sel {
        width: 165px;
        margin-left: 10px;
      }
      .query-class-btn {
        font-size: 16px;
        margin-left: 10px;
        color: #bebebe;
      }
    }
  }
  .btn-pager {
    display: flex;
    .page {
      margin-left: auto;
    }
  }
}
::v-deep {
  .el-tabs--top .el-tabs__item.is-top:nth-child(2) {
    padding-left: 25px;
  }
  .el-tabs__item {
    padding: 0 25px;
    height: 45px;
  }
}
</style>
src/views/custom/followupRecords/AddFollowupRecordsDialog.vue
New file
@@ -0,0 +1,349 @@
<template>
  <div class="add-followup-records">
    <el-dialog
      :title="editContactsConfig.title + '跟进记录'"
      :visible.sync="editConfig.visible"
      :width="dialogWidth"
      :before-close="handleClose"
    >
      <el-form
        ref="form"
        :model="editConfig.infomation"
        :rules="rules"
        label-position="right"
        label-width="308px"
        size="mini"
      >
        <!-- 信息 -->
        <div class="basic-info">
          <!-- 基本信息 -->
          <div v-if="isUnflod" class="basic-info-title">基本信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="客户名称" prop="customName">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.customName"></el-input>
                    <div class="common-select-btn"><i class="el-icon-circle-plus-outline"></i></div>
                    <div class="common-select-btn"><i class="el-icon-edit-outline"></i></div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12" v-if="isUnflod">
                <el-form-item label="跟进记录编号" prop="followupRecordsNumber">
                  <el-button type="text" style="color: #333; font-size: 13px">
                    {{ editConfig.infomation.followupRecordsNumber }}
                  </el-button>
                </el-form-item>
              </el-col>
              <el-col v-if="isUnflod" :span="12">
                <el-form-item label="客户状态" prop="customStatus">
                  <CommonSelectView
                    :common-value="editConfig.infomation.customStatus"
                    :common-options="customStatusOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系人姓名" prop="contactName">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.contactName"></el-input>
                    <div class="common-select-btn"><i class="el-icon-circle-plus-outline"></i></div>
                    <div class="common-select-btn"><i class="el-icon-edit-outline"></i></div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item v-if="isUnflod" label="负责人" prop="owner">
                  <el-select v-model="editConfig.infomation.owner" placeholder="请选择" size="mini">
                    <el-option v-for="item in ownerOptions" :key="item.value" :label="item.label" :value="item.value">
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="主题" prop="theme">
                  <el-input v-model="editConfig.infomation.theme"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="isUnflod ? 24 : 12">
                <el-form-item label="跟进记录" prop="followupRecords">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    v-model="editConfig.infomation.followupRecords"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系方式" prop="phoneNumber">
                  <el-input v-model="editConfig.infomation.phoneNumber"></el-input>
                </el-form-item>
              </el-col>
              <el-col v-if="isUnflod" :span="12">
                <el-form-item label="销售机会" prop="salesOpportunity">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.salesOpportunity"></el-input>
                    <div class="common-select-btn"><i class="el-icon-circle-plus-outline"></i></div>
                    <div class="common-select-btn"><i class="el-icon-edit-outline"></i></div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="销售线索" prop="salesClue">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.salesClue"></el-input>
                    <div class="common-select-btn"><i class="el-icon-circle-plus-outline"></i></div>
                    <div class="common-select-btn"><i class="el-icon-edit-outline"></i></div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系日期" prop="contactDate">
                  <el-date-picker v-model="editConfig.infomation.contactDate" type="date" placeholder="选择日期">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="下次回访日期" prop="nextFollowupDate">
                  <el-date-picker v-model="editConfig.infomation.nextFollowupDate" type="date" placeholder="选择日期">
                  </el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 备注信息 -->
          <div v-if="isUnflod" class="basic-info-title">备注信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="24">
                <el-form-item label="拜访目的" prop="visitPurpose">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    v-model="editConfig.infomation.visitPurpose"
                  ></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="内容" prop="content">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    v-model="editConfig.infomation.content"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 附件信息 -->
          <div v-if="isUnflod" class="basic-info-title">附件信息</div>
          <div v-if="isUnflod" class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="附件" prop="">
                  <div class="annex-view">
                    <div @click="addAnnexClick">添加</div>
                    <div class="setFormat" @click="setFormatClick">设置允许上传的文件格式</div>
                  </div>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </div>
        <!-- 展开收起 -->
        <div v-if="editConfig.title === '新建'" class="unflod-collapse" @click="unflodCollapseClick">
          <div>{{ unflodCollapseStr }}</div>
          <div v-if="isUnflod"><i class="el-icon-arrow-up"></i></div>
          <div v-else><i class="el-icon-arrow-down"></i></div>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" size="small" @click="editConfig.visible = false">保 存</el-button>
        <el-button size="small" @click="editConfig.visible = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import CommonSelectView from "@/components/makepager/CommonSelectView"
export default {
  name: "AddFollowupRecordsDialog",
  props: {
    editContactsConfig: {
      type: Object,
      default: () => {
        return {
          visible: false,
          title: "新建",
          infomation: {
            customName: "",
            followupRecordsNumber: "LEA50",
            customStatus: "",
            contactName: "",
            owner: "",
            theme: "",
            followupRecords: "",
            phoneNumber: "",
            salesOpportunity: "",
            salesClue: "",
            contactDate: "",
            nextFollowupDate: "",
            visitPurpose: "",
            content: ""
          }
        }
      }
    }
  },
  components: { CommonSelectView },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      dialogWidth: "80%",
      editConfig: this.editContactsConfig,
      rules: {
        followupRecordsNumber: [{ required: true, message: "请输入跟进记录编号", trigger: "blur" }],
        owner: [{ required: true, message: "请选择负责人", trigger: "change" }],
        followupRecords: [{ required: true, message: "请输入跟进记录", trigger: "blur" }]
      },
      businessSourceOptions: [
        { value: "1", label: "后台注册" },
        { value: "2", label: "代理商客户" },
        { value: "3", label: "电话陌生拜访" },
        { value: "4", label: "直接访问" },
        { value: "5", label: "项目合作" },
        { value: "6", label: "个人自找" },
        { value: "7", label: "二次销售" },
        { value: "8", label: "公司电话" }
      ],
      ownerOptions: [
        { value: "1", label: "BOSS" },
        { value: "2", label: "Mia" },
        { value: "3", label: "财务" },
        { value: "4", label: "市场" },
        { value: "5", label: "系统管理员" },
        { value: "6", label: "销售" },
        { value: "7", label: "销售总监" }
      ],
      countryOptions: [{ value: "1", label: "中国" }], // 国家
      provinceOptions: [
        { value: "1", label: "北京市" },
        { value: "2", label: "上海市" },
        { value: "3", label: "吉林省" },
        { value: "4", label: "陕西省" }
      ], // 省份
      cityOptions: [
        { value: "1", label: "北京市" },
        { value: "2", label: "上海市" },
        { value: "3", label: "吉林市" },
        { value: "4", label: "西安市" }
      ], // 城市
      regionOptions: [
        { value: "1", label: "朝阳区" },
        { value: "2", label: "海淀区" },
        { value: "3", label: "通州区" },
        { value: "4", label: "西城区" }
      ], // 区域
      unflodCollapseStr: "收起",
      isUnflod: true
    }
  },
  created() {},
  methods: {
    handleClose() {
      this.editConfig.visible = false
    },
    // 添加附件
    addAnnexClick() {},
    // 设置允许上传文件格式
    setFormatClick() {},
    // 展开收起
    unflodCollapseClick() {
      if (this.unflodCollapseStr === "收起") {
        this.unflodCollapseStr = "展开更多栏目"
        this.isUnflod = false
      } else {
        this.unflodCollapseStr = "收起"
        this.isUnflod = true
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.add-followup-records {
  .basic-info {
    .basic-info-title {
      background-color: #f4f8fe;
      padding-left: 10px;
      font-size: 15px;
      font-weight: bold;
      color: #666;
      height: 42px;
      line-height: 42px;
    }
    .basic-info-view {
      margin-top: 10px;
      padding-right: 40px;
      .custom-name {
        display: flex;
        .common-select-btn {
          margin-left: 5px;
          font-size: 16px;
        }
      }
    }
    .address-view {
      margin-top: 10px;
      padding-right: 40px;
    }
    .annex-view {
      display: flex;
      color: #6166d3;
      .setFormat {
        margin-left: 10px;
      }
    }
  }
  .unflod-collapse {
    display: flex;
    height: 30px;
    justify-content: center;
    align-items: center;
    color: #6166d3;
  }
  .dialog-footer {
    background-color: #f5f5f5;
    height: 55px;
    line-height: 55px;
  }
}
::v-deep {
  .el-dialog__header {
    padding: 12.5px 10px;
    border-bottom: 1px solid #e5e5e5;
    .el-dialog__title {
      font-size: 15px;
      color: #323232;
      font-weight: bold;
    }
  }
  .el-dialog__body {
    padding: 0px;
  }
  .el-dialog__footer {
    padding: 0px;
    text-align: center;
    box-sizing: border-box;
    border-top: 1px solid #dadee5;
  }
}
</style>
src/views/custom/followupRecords/index.vue
New file
@@ -0,0 +1,165 @@
<template>
  <div class="followup-records">
    <SearchCommonView ref="searchCommonView" :query-class-options="queryClassOptions" :search-options="searchOptions" />
    <div class="btn-pager">
      <PublicFunctionBtnView :statistics="true" :operates-list="operatesList" />
      <PagerView class="page" />
    </div>
    <TableCommonView ref="tableListRef" :table-list="tableList">
      <template slot="tableButton">
        <el-table-column label="操作" width="120" fixed="right">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small">编辑</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCommonView>
    <!-- 新建/编辑跟进记录 -->
    <AddFollowupRecordsDialog v-if="editConfig.visible" :edit-contacts-config="editConfig" />
  </div>
</template>
<script>
import SearchCommonView from "@/components/makepager/SearchCommonView"
import PublicFunctionBtnView from "@/components/makepager/PublicFunctionBtnView"
import PagerView from "@/components/makepager/PagerView"
import TableCommonView from "@/components/makepager/TableCommonView"
import AddFollowupRecordsDialog from "@/views/custom/followupRecords/AddFollowupRecordsDialog"
export default {
  name: "FollowupRecords",
  props: {},
  components: {
    SearchCommonView,
    PublicFunctionBtnView,
    PagerView,
    TableCommonView,
    AddFollowupRecordsDialog
  },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      tableList: {},
      activeName: "second",
      queryClassOptions: [
        { value: "1", label: "全部" },
        { value: "2", label: "今日联系" },
        { value: "3", label: "本周联系" },
        { value: "4", label: "本月联系" }
      ],
      searchOptions: [],
      operatesList: [
        { id: "1", name: "共享" },
        { id: "2", name: "批量编辑" },
        { id: "3", name: "导出" },
        { id: "4", name: "下载全部附件" },
        { id: "5", name: "更改创建人" },
        { id: "6", name: "树结构设置" },
        { id: "7", name: "审批设置" },
        { id: "8", name: "回访预设列宽" }
      ],
      editConfig: {
        visible: false,
        title: "新建",
        infomation: {}
      }
    }
  },
  created() {
    this.setTable()
  },
  methods: {
    setTable() {
      this.tableList = {
        tableInfomation: [
          {
            theme: "上门拜访",
            customName: "上海通用机械有限公司",
            contactName: "BOSS",
            customStatus: "C类客户",
            phoneNumber: "15988887777",
            contactDate: "董奇伟",
            nextFollowupDate: "2023-07-28",
            owner: "2023-07-26",
            followupRecords: "上海市静安区威海路115号"
          }
        ],
        tableColumn: [
          { label: "主题", prop: "theme", min: 190 }, // 主题
          { label: "客户名称", prop: "customName", min: 190 }, // 客户名称
          { label: "联系人姓名", prop: "contactName", min: 100 }, // 联系人姓名
          { label: "客户状态", prop: "customStatus", min: 100 }, // 客户状态
          { label: "联系方式", prop: "phoneNumber", min: 100 }, // 联系方式
          { label: "联系人日期", prop: "contactDate", min: 100 }, // 联系人日期
          { label: "下次回访日期", prop: "nextFollowupDate", min: 130 }, // 下次回访日期
          { label: "负责人", prop: "owner", min: 120 }, // 负责人
          { label: "跟进记录", prop: "followupRecords", min: 120 } // 跟进记录
        ]
      }
      this.searchOptions = []
      for (let i = 0; i < this.tableList.tableColumn.length; i++) {
        const label = this.tableList.tableColumn[i].label
        this.searchOptions.push({ value: (i + 1).toString(), label: label })
      }
    },
    // 新建
    addBtnClick() {
      this.editConfig.visible = true
      this.editConfig.title = "新建"
      this.editConfig.infomation = {
        customName: "",
        followupRecordsNumber: "LEA50",
        customStatus: "",
        contactName: "",
        owner: "",
        theme: "",
        followupRecords: "",
        phoneNumber: "",
        salesOpportunity: "",
        salesClue: "",
        contactDate: "",
        nextFollowupDate: "",
        visitPurpose: "",
        content: ""
      }
    },
    // 编辑
    handleClick(row) {
      console.log(row)
      this.editConfig.visible = true
      this.editConfig.title = "编辑"
      this.editConfig.infomation = {
        customName: row.customName,
        followupRecordsNumber: "LEA50",
        customStatus: row.customStatus,
        contactName: row.contactName,
        owner: row.owner,
        theme: row.theme,
        followupRecords: row.followupRecords,
        phoneNumber: row.phoneNumber,
        salesOpportunity: "",
        salesClue: "",
        contactDate: row.contactDate,
        nextFollowupDate: row.nextFollowupDate,
        visitPurpose: "",
        content: ""
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.followup-records {
  .btn-pager {
    display: flex;
    .page {
      margin-left: auto;
    }
  }
}
</style>
src/views/custom/index.vue
New file
@@ -0,0 +1,21 @@
<template>
  <div class="content">
    <router-view />
  </div>
</template>
<script>
export default {
  name: "CustomM",
  props: {}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.content {
  width: 100%;
  background-color: #fff;
  height: calc(100vh - 60px);
}
</style>
src/views/custom/salesLead/AddSalesLeadDialog.vue
New file
@@ -0,0 +1,327 @@
<template>
  <div class="add-sales-lead">
    <el-dialog
      :title="editSalesLeadConfig.title + '销售线索'"
      :visible.sync="editConfig.visible"
      :width="dialogWidth"
      :before-close="handleClose"
    >
      <el-form
        ref="form"
        :model="editConfig.infomation"
        :rules="rules"
        label-position="right"
        label-width="308px"
        size="mini"
      >
        <!-- 信息 -->
        <div class="basic-info">
          <!-- 基本信息 -->
          <div v-if="isUnflod" class="basic-info-title">基本信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="客户名称" prop="customName">
                  <el-input v-model="editConfig.infomation.customName"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="销售线索编号" prop="saleLeadNumber">
                  <span>{{ editSalesLeadConfig.infomationsaleLeadNumber }}</span>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="联系人姓名" prop="contactName">
                  <el-input v-model="editConfig.infomation.contactName"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系人职务" prop="contactDuties">
                  <el-input v-model="editConfig.infomation.contactDuties"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="手机号码" prop="phoneNumber">
                  <el-input v-model="editConfig.infomation.phoneNumber"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="商机状态" prop="businessStatus">
                  <span>{{ editConfig.infomation.businessStatus }}</span>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="商机来源" prop="businessSource">
                  <CommonSelectView
                    :common-value="editConfig.infomation.businessSource"
                    :common-options="businessSourceOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="负责人" prop="owner">
                  <el-select v-model="editConfig.infomation.owner" placeholder="请选择" size="mini">
                    <el-option v-for="item in ownerOptions" :key="item.value" :label="item.label" :value="item.value">
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 地址信息 -->
          <div v-if="isUnflod" class="basic-info-title">地址信息</div>
          <div v-if="isUnflod" class="address-view">
            <el-row>
              <el-col :span="24">
                <el-form-item label="定位" prop="position">
                  <el-input v-model="editConfig.infomation.position"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="地图" prop="map">
                  <div style="height: 100px"></div>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="国家" prop="country">
                  <CommonSelectView :common-value="editConfig.infomation.country" :common-options="countryOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="省份" prop="province">
                  <CommonSelectView :common-value="editConfig.infomation.province" :common-options="provinceOptions" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="城市" prop="city">
                  <CommonSelectView :common-value="editConfig.infomation.city" :common-options="cityOptions" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="区域" prop="region">
                  <CommonSelectView :common-value="editConfig.infomation.region" :common-options="regionOptions" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="地址" prop="address">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    placeholder="请输入内容"
                    v-model="editConfig.infomation.address"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 备注信息 -->
          <div v-if="isUnflod" class="basic-info-title">备注信息</div>
          <div v-if="isUnflod" class="basic-info-view">
            <el-row>
              <el-col :span="24">
                <el-form-item label="地址" prop="address">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    placeholder="请输入内容"
                    v-model="editConfig.infomation.address"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </div>
        <!-- 展开收起 -->
        <div v-if="editConfig.title === '新建'" class="unflod-collapse" @click="unflodCollapseClick">
          <div>{{ unflodCollapseStr }}</div>
          <div v-if="isUnflod"><i class="el-icon-arrow-up"></i></div>
          <div v-else><i class="el-icon-arrow-down"></i></div>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" size="small" @click="editConfig.visible = false">保 存</el-button>
        <el-button size="small" @click="editConfig.visible = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import CommonSelectView from "@/components/makepager/CommonSelectView"
export default {
  name: "AddSalesLeadDialog",
  props: {
    editSalesLeadConfig: {
      type: Object,
      default: () => {
        return {
          visible: false,
          title: "新建",
          infomation: {
            customName: "",
            saleLeadNumber: "LEA50",
            contactName: "",
            contactDuties: "",
            phoneNumber: "",
            businessStatus: "新建",
            businessSource: "1",
            owner: "",
            position: "",
            map: "",
            country: "1",
            province: "1",
            city: "1",
            region: "1",
            address: ""
          }
        }
      }
    }
  },
  components: { CommonSelectView },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      dialogWidth: "80%",
      editConfig: this.editSalesLeadConfig,
      rules: {
        customName: [{ required: true, message: "请输入客户名称", trigger: "blur" }],
        saleLeadNumber: [{ required: true, message: "请输入销售线索编号", trigger: "blur" }],
        businessStatus: [{ required: true, message: "请输入商机状态", trigger: "blur" }],
        businessSource: [{ required: true, message: "请选择商机来源", trigger: "change" }]
      },
      businessSourceOptions: [
        { value: "1", label: "后台注册" },
        { value: "2", label: "代理商客户" },
        { value: "3", label: "电话陌生拜访" },
        { value: "4", label: "直接访问" },
        { value: "5", label: "项目合作" },
        { value: "6", label: "个人自找" },
        { value: "7", label: "二次销售" },
        { value: "8", label: "公司电话" }
      ],
      ownerOptions: [
        { value: "1", label: "BOSS" },
        { value: "2", label: "Mia" },
        { value: "3", label: "财务" },
        { value: "4", label: "市场" },
        { value: "5", label: "系统管理员" },
        { value: "6", label: "销售" },
        { value: "7", label: "销售总监" }
      ],
      countryOptions: [{ value: "1", label: "中国" }], // 国家
      provinceOptions: [
        { value: "1", label: "北京市" },
        { value: "2", label: "上海市" },
        { value: "3", label: "吉林省" },
        { value: "4", label: "陕西省" }
      ], // 省份
      cityOptions: [
        { value: "1", label: "北京市" },
        { value: "2", label: "上海市" },
        { value: "3", label: "吉林市" },
        { value: "4", label: "西安市" }
      ], // 城市
      regionOptions: [
        { value: "1", label: "朝阳区" },
        { value: "2", label: "海淀区" },
        { value: "3", label: "通州区" },
        { value: "4", label: "西城区" }
      ], // 区域
      unflodCollapseStr: "收起",
      isUnflod: true
    }
  },
  created() {},
  methods: {
    handleClose() {
      this.editConfig.visible = false
    },
    // 展开收起
    unflodCollapseClick() {
      if (this.unflodCollapseStr === "收起") {
        this.unflodCollapseStr = "展开更多栏目"
        this.isUnflod = false
      } else {
        this.unflodCollapseStr = "收起"
        this.isUnflod = true
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.add-sales-lead {
  .basic-info {
    .basic-info-title {
      background-color: #f4f8fe;
      padding-left: 10px;
      font-size: 15px;
      font-weight: bold;
      color: #666;
      height: 42px;
      line-height: 42px;
    }
    .basic-info-view {
      margin-top: 10px;
      padding-right: 40px;
    }
    .address-view {
      margin-top: 10px;
      padding-right: 40px;
    }
  }
  .unflod-collapse {
    display: flex;
    height: 30px;
    justify-content: center;
    align-items: center;
    color: #6166d3;
  }
  .dialog-footer {
    background-color: #f5f5f5;
    height: 55px;
    line-height: 55px;
  }
}
::v-deep {
  .el-dialog__header {
    padding: 12.5px 10px;
    border-bottom: 1px solid #e5e5e5;
    .el-dialog__title {
      font-size: 15px;
      color: #323232;
      font-weight: bold;
    }
  }
  .el-dialog__body {
    padding: 0px;
  }
  .el-dialog__footer {
    padding: 0px;
    text-align: center;
    box-sizing: border-box;
    border-top: 1px solid #dadee5;
  }
}
</style>
src/views/custom/salesLead/index.vue
New file
@@ -0,0 +1,167 @@
<template>
  <div class="sales-lead">
    <SearchCommonView ref="searchCommonView" :query-class-options="queryClassOptions" :search-options="searchOptions" />
    <div class="btn-pager">
      <PublicFunctionBtnView :operates-list="operatesList" />
      <PagerView class="page" />
    </div>
    <TableCommonView ref="tableListRef" :table-list="tableList">
      <template slot="tableButton">
        <el-table-column label="操作" width="120">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small">编辑</el-button>
            <el-button type="text" size="small">跟进</el-button>
            <el-button type="text" size="small">推进</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCommonView>
    <!-- 新建/编辑销售线索 -->
    <AddSalesLeadDialog v-if="editSalesLeadConfig.visible" :edit-sales-lead-config="editSalesLeadConfig" />
  </div>
</template>
<script>
import SearchCommonView from "@/components/makepager/SearchCommonView"
import PublicFunctionBtnView from "@/components/makepager/PublicFunctionBtnView"
import PagerView from "@/components/makepager/PagerView"
import TableCommonView from "@/components/makepager/TableCommonView"
import AddSalesLeadDialog from "@/views/custom/salesLead/AddSalesLeadDialog"
export default {
  name: "SalesLead",
  props: {},
  components: {
    SearchCommonView,
    PublicFunctionBtnView,
    PagerView,
    TableCommonView,
    AddSalesLeadDialog
  },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      tableList: {},
      queryClassOptions: [
        { value: "1", label: "全部" },
        { value: "2", label: "广告宣传" },
        { value: "3", label: "跟进中" },
        { value: "4", label: "失败关闭" }
      ],
      searchOptions: [],
      operatesList: [
        { id: "1", name: "共享" },
        { id: "2", name: "批量编辑" },
        { id: "3", name: "导出" },
        { id: "4", name: "下载全部附件" },
        { id: "5", name: "更改创建人" },
        { id: "6", name: "树结构设置" },
        { id: "7", name: "审批设置" },
        { id: "8", name: "公海参数设置" }
      ],
      editSalesLeadConfig: {
        visible: false,
        title: "新建",
        infomation: {}
      }
    }
  },
  created() {
    this.setTable()
  },
  methods: {
    setTable() {
      this.tableList = {
        tableInfomation: [
          {
            customName: "上海通用机械有限公司",
            saleLeadNumber: "LEA110",
            contactName: "董奇伟",
            phoneNumber: "15988887777",
            businessSource: "朋友介绍",
            province: "江苏省",
            city: "连云港市",
            owner: "销售总监"
          }
        ],
        tableColumn: [
          { label: "客户名称", prop: "customName", min: 190 }, // 客户名称
          { label: "销售线索编号", prop: "saleLeadNumber", min: 190 }, // 销售线索编号
          { label: "联系人姓名", prop: "contactName", min: 190 }, // 联系人姓名
          { label: "手机号码", prop: "phoneNumber", min: 190 }, // 手机号码
          { label: "商机来源", prop: "businessSource", min: 190 }, // 商机来源
          { label: "省份", prop: "province", min: 190 }, // 省份
          { label: "城市", prop: "city", min: 190 }, // 城市
          { label: "负责人", prop: "owner", min: 190 } // 负责人
        ]
      }
      this.searchOptions = []
      for (let i = 0; i < this.tableList.tableColumn.length; i++) {
        const label = this.tableList.tableColumn[i].label
        this.searchOptions.push({ value: (i + 1).toString(), label: label })
      }
    },
    // 新建
    addBtnClick() {
      this.editSalesLeadConfig.visible = true
      this.editSalesLeadConfig.title = "新建"
      this.editSalesLeadConfig.infomation = {
        customName: "",
        saleLeadNumber: "LEA50",
        contactName: "",
        contactDuties: "",
        phoneNumber: "",
        businessStatus: "新建",
        businessSource: "1",
        owner: "",
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    },
    // 编辑
    handleClick(row) {
      console.log(row)
      this.editSalesLeadConfig.visible = true
      this.editSalesLeadConfig.title = "编辑"
      this.editSalesLeadConfig.infomation = {
        customName: row.customName,
        saleLeadNumber: row.saleLeadNumber,
        contactName: row.contactName,
        contactDuties: row.contactDuties,
        phoneNumber: row.phoneNumber,
        businessStatus: "新建",
        businessSource: row.businessSource,
        owner: row.owner,
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.sales-lead {
  .btn-pager {
    display: flex;
    .page {
      margin-left: auto;
    }
  }
}
</style>
src/views/login/index.vue
New file
@@ -0,0 +1,30 @@
<template>
  <div class="login">
    <h1>login</h1>
  </div>
</template>
<script>
export default {
  name: "LoginOn",
  props: {}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
src/views/sales/index.vue
New file
@@ -0,0 +1,21 @@
<template>
  <div class="content">
    <router-view />
  </div>
</template>
<script>
export default {
  name: "SalesM",
  props: {}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.content {
  width: 100%;
  background-color: #fff;
  height: calc(100vh - 60px);
}
</style>
src/views/service/index.vue
New file
@@ -0,0 +1,21 @@
<template>
  <div class="content">
    <router-view />
  </div>
</template>
<script>
export default {
  name: "ServiceM",
  props: {}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.content {
  width: 100%;
  background-color: #fff;
  height: calc(100vh - 60px);
}
</style>
src/views/service/orderManage/index.vue
New file
@@ -0,0 +1,158 @@
<template>
  <div class="sales-lead">
    <SearchCommonView ref="searchCommonView" :query-class-options="queryClassOptions" :search-options="searchOptions" />
    <div class="btn-pager">
      <PublicFunctionBtnView :receive="true" :submit-approval="true" :operates-list="operatesList" />
      <PagerView class="page" />
    </div>
    <TableCommonView ref="tableListRef" :table-list="tableList">
      <template slot="tableButton">
        <el-table-column label="操作" width="120">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small">编辑</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCommonView>
    <!-- 新建/编辑销售线索 -->
    <AddSalesLeadDialog v-if="editSalesLeadConfig.visible" :edit-sales-lead-config="editSalesLeadConfig" />
  </div>
</template>
<script>
import SearchCommonView from "@/components/makepager/SearchCommonView"
import PublicFunctionBtnView from "@/components/makepager/PublicFunctionBtnView"
import PagerView from "@/components/makepager/PagerView"
import TableCommonView from "@/components/makepager/TableCommonView"
import AddSalesLeadDialog from "@/views/custom/salesLead/AddSalesLeadDialog"
export default {
  name: "SalesLead",
  props: {},
  components: {
    SearchCommonView,
    PublicFunctionBtnView,
    PagerView,
    TableCommonView,
    AddSalesLeadDialog
  },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      tableList: {},
      queryClassOptions: [{ value: "1", label: "全部" }],
      searchOptions: [],
      operatesList: [
        { id: "1", name: "共享" },
        { id: "2", name: "批量编辑" },
        { id: "3", name: "导出" },
        { id: "4", name: "下载全部附件" },
        { id: "5", name: "更改创建人" },
        { id: "6", name: "树结构设置" },
        { id: "7", name: "审批设置" },
        { id: "8", name: "恢复预设列宽" }
      ],
      editSalesLeadConfig: {
        visible: false,
        title: "新建",
        infomation: {}
      }
    }
  },
  created() {
    this.setTable()
  },
  methods: {
    setTable() {
      this.tableList = {
        tableInfomation: [
          {
            orderNumber: "LEA110",
            customName: "上海通用机械有限公司",
            contactName: "董奇伟",
            servicePerson: "系统管理员",
            orderStatus: "已结单",
            repairSource: "电话报修",
            orderType: "保内收费"
          }
        ],
        tableColumn: [
          { label: "工单编号", prop: "orderNumber", min: 100 }, // 工单编号
          { label: "客户名称", prop: "customName", min: 130 }, // 客户名称
          { label: "联系人姓名", prop: "contactName" }, // 联系人姓名
          { label: "服务人员", prop: "servicePerson" }, // 服务人员
          { label: "工单状态", prop: "orderStatus" }, // 工单状态
          { label: "报修来源", prop: "repairSource" }, // 报修来源
          { label: "工单类型", prop: "orderType" } // 工单类型
        ]
      }
      this.searchOptions = []
      for (let i = 0; i < this.tableList.tableColumn.length; i++) {
        const label = this.tableList.tableColumn[i].label
        this.searchOptions.push({ value: (i + 1).toString(), label: label })
      }
    },
    // 新建
    addBtnClick() {
      this.editSalesLeadConfig.visible = true
      this.editSalesLeadConfig.title = "新建"
      this.editSalesLeadConfig.infomation = {
        customName: "",
        saleLeadNumber: "LEA50",
        contactName: "",
        contactDuties: "",
        phoneNumber: "",
        businessStatus: "新建",
        businessSource: "1",
        owner: "",
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    },
    // 编辑
    handleClick(row) {
      console.log(row)
      this.editSalesLeadConfig.visible = true
      this.editSalesLeadConfig.title = "编辑"
      this.editSalesLeadConfig.infomation = {
        customName: row.customName,
        saleLeadNumber: row.saleLeadNumber,
        contactName: row.contactName,
        contactDuties: row.contactDuties,
        phoneNumber: row.phoneNumber,
        businessStatus: "新建",
        businessSource: row.businessSource,
        owner: row.owner,
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.sales-lead {
  .btn-pager {
    display: flex;
    .page {
      margin-left: auto;
    }
  }
}
</style>
src/views/service/serviceContract/AddServiceContractDialog.vue
New file
@@ -0,0 +1,456 @@
<template>
  <div class="service-contract">
    <el-dialog
      :title="editCommonConfig.title + '客户管理'"
      :visible.sync="editConfig.visible"
      :width="dialogWidth"
      :before-close="handleClose"
    >
      <el-form
        ref="form"
        :model="editConfig.infomation"
        :rules="rules"
        label-position="right"
        label-width="308px"
        size="mini"
        style="height: 60vh; overflow-x: hidden"
      >
        <!-- 信息 -->
        <div class="basic-info">
          <!-- 基本信息 -->
          <div class="basic-info-title">基本信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="客户名称" prop="customName">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.customName"></el-input>
                    <div class="common-select-btn"><i class="el-icon-circle-plus-outline" title="选择"></i></div>
                    <div class="common-select-btn"><i class="el-icon-edit" title="编辑"></i></div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="服务合同编号" prop="serviceContractNumber">
                  <el-input v-model="editConfig.infomation.serviceContractNumber"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="负责人" prop="owner">
                  <el-select v-model="editConfig.infomation.owner" placeholder="请选择" size="mini" style="width: 63%">
                    <el-option v-for="item in ownerOptions" :key="item.value" :label="item.label" :value="item.value">
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="联系人姓名" prop="contactName">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.contactName"></el-input>
                    <div class="common-select-btn"><i class="el-icon-circle-plus-outline" title="选择"></i></div>
                    <div class="common-select-btn"><i class="el-icon-edit" title="编辑"></i></div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="销售机会" prop="salesOpportunity">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.salesOpportunity"></el-input>
                    <div class="common-select-btn"><i class="el-icon-circle-plus-outline" title="选择"></i></div>
                    <div class="common-select-btn"><i class="el-icon-edit" title="编辑"></i></div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="合同订单" prop="contractOrder">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.contractOrder"></el-input>
                    <div class="common-select-btn"><i class="el-icon-circle-plus-outline" title="选择"></i></div>
                    <div class="common-select-btn"><i class="el-icon-edit" title="编辑"></i></div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="报价单" prop="quotation">
                  <div class="custom-name">
                    <el-input v-model="editConfig.infomation.quotation"></el-input>
                    <div class="common-select-btn"><i class="el-icon-circle-plus-outline" title="选择"></i></div>
                    <div class="common-select-btn"><i class="el-icon-edit" title="编辑"></i></div>
                  </div>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="合同类型" prop="contractType">
                  <CommonSelectView
                    :common-value="editConfig.infomation.contractType"
                    :common-options="contractTypeOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="签约日期" prop="signDate">
                  <el-date-picker v-model="editConfig.infomation.signDate" type="date" placeholder="选择日期">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="服务开始日期" prop="startDate">
                  <el-date-picker v-model="editConfig.infomation.startDate" type="date" placeholder="选择日期">
                  </el-date-picker>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="服务到期日" prop="endDate">
                  <el-date-picker v-model="editConfig.infomation.endDate" type="date" placeholder="选择日期">
                  </el-date-picker>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 动态信息 -->
          <div class="basic-info-title">动态信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="合同状态" prop="contractStatus">
                  <CommonSelectView
                    :common-value="editConfig.infomation.contractStatus"
                    :common-options="contractStatusOptions"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="应服务次数" prop="serviceNumber">
                  <el-input v-model="editConfig.infomation.serviceNumber"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 条款与条件 -->
          <div class="basic-info-title">条款与条件</div>
          <div class="address-view">
            <el-row>
              <el-col :span="24">
                <el-form-item label="条款和条约" prop="termsTreaty">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 4, maxRows: 6 }"
                    placeholder="请输入内容"
                    v-model="editConfig.infomation.termsTreaty"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 备注信息 -->
          <div class="basic-info-title">备注信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="24">
                <el-form-item label="备注" prop="notes">
                  <el-input
                    type="textarea"
                    :autosize="{ minRows: 2, maxRows: 4 }"
                    placeholder="请输入内容"
                    v-model="editConfig.infomation.notes"
                  ></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 附件信息 -->
          <div class="basic-info-title">附件信息</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="12">
                <el-form-item label="附件" prop="">
                  <div class="annex-view">
                    <div @click="addAnnexClick">添加</div>
                    <div class="setFormat" @click="setFormatClick">设置允许上传的文件格式</div>
                  </div>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <!-- 产品管理 -->
          <div class="basic-info-title" style="display: flex">
            产品管理
            <div style="margin-left: 400px">
              币种
              <el-select v-model="editConfig.infomation.currency" placeholder="请选择" size="mini" style="width: 63%">
                <el-option v-for="item in currencyOptions" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </div>
          </div>
          <div class="basic-info-view">
            <el-form ref="form" :model="productTableList" :show-message="false" label-position="right">
              <el-table :data="productTableList.tableData" style="width: 100%">
                <el-table-column prop="id" label="#" width="30"></el-table-column>
                <el-table-column prop="productName" label="产品名称">
                  <template slot-scope="scope">
                    <el-form-item
                      label=" "
                      :prop="'productTableList.tableData.' + scope.$index + '.productName'"
                      :rules="[{ required: true, message: '输入不能为空' }]"
                    >
                      <el-input
                        v-model.trim="scope.row.productName"
                        maxlength="50"
                        size="mini"
                        style="width: 60px"
                      ></el-input>
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column prop="productNumber" label="产品编号"></el-table-column>
                <el-table-column prop="startDate" label="服务开始日">
                  <el-form-item
                    label=" "
                    prop="'productTableList.tableData.' + scope.$index + '.startDate'"
                    :rules="[{ required: true, message: '输入不能为空' }]"
                  >
                    <el-date-picker v-model="scope.row.startDate" type="date" placeholder="选择日期"> </el-date-picker>
                  </el-form-item>
                </el-table-column>
                <el-table-column prop="address" label="服务到期日"> </el-table-column>
                <el-table-column prop="productNumber" label="数量"></el-table-column>
                <el-table-column prop="name" label="含税单价"> </el-table-column>
                <el-table-column prop="address" label="不含税单价"> </el-table-column>
                <el-table-column prop="productNumber" label="折扣率(%)"></el-table-column>
                <el-table-column prop="name" label="折扣额"> </el-table-column>
                <el-table-column prop="address" label="税(销售)"> </el-table-column>
                <el-table-column prop="productNumber" label="实际含税单价"></el-table-column>
                <el-table-column prop="name" label="价税合计"> </el-table-column>
                <el-table-column prop="address" label="描述"> </el-table-column>
              </el-table>
            </el-form>
          </div>
          <!-- 选择审批流程 -->
          <div class="basic-info-title">选择审批流程</div>
          <div class="basic-info-view">
            <el-row>
              <el-col :span="20">
                <el-form-item label="审批流程" prop="approvalWorkflow">
                  <el-select
                    v-model="editConfig.infomation.approvalWorkflow"
                    placeholder="请选择"
                    size="mini"
                    style="width: 100%"
                  >
                    <el-option
                      v-for="item in approvalWorkflowOptions"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    >
                    </el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="20">
                <el-form-item label="审批步骤" prop="approvalSteps">
                  <el-input v-model="editConfig.infomation.approvalSteps"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="20">
                <el-form-item label="审批人" prop="approvalPerson">
                  <el-input v-model="editConfig.infomation.approvalPerson"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="20">
                <el-form-item label="审批意见" prop="approvalOpinion">
                  <el-input v-model="editConfig.infomation.approvalOpinion" type="textarea" :rows="2"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" size="small" @click="editConfig.visible = false">保并提交审批</el-button>
        <el-button type="primary" size="small" @click="editConfig.visible = false">保存</el-button>
        <el-button size="small" @click="editConfig.visible = false">取消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import CommonSelectView from "@/components/makepager/CommonSelectView"
export default {
  name: "AddServiceContractDialog",
  props: {
    editCommonConfig: {
      type: Object,
      default: () => {
        return {
          visible: false,
          title: "新建",
          infomation: {
            customName: "",
            serviceContractNumber: "AC6521",
            owner: "5",
            contactName: "",
            salesOpportunity: "",
            contractOrder: "",
            quotation: "",
            contractType: "",
            signDate: "",
            startDate: "",
            endDate: "",
            contractStatus: "",
            serviceNumber: "",
            termsTreaty: "",
            notes: "",
            approvalWorkflow: "",
            approvalSteps: "",
            approvalPerson: "",
            approvalOpinion: ""
          }
        }
      }
    }
  },
  components: { CommonSelectView },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      dialogWidth: "80%",
      editConfig: this.editCommonConfig,
      rules: {
        serviceContractNumber: [{ required: true, message: "请输入服务合同编号", trigger: "blur" }],
        signDate: [{ required: true, message: "请选择", trigger: "change" }],
        owner: [{ required: true, message: "请选择负责人", trigger: "change" }],
        approvalOpinion: [{ required: true, message: "请输入审批意见", trigger: "blur" }]
      },
      businessSourceOptions: [
        { value: "1", label: "后台注册" },
        { value: "2", label: "代理商客户" },
        { value: "3", label: "电话陌生拜访" },
        { value: "4", label: "直接访问" },
        { value: "5", label: "项目合作" },
        { value: "6", label: "个人自找" },
        { value: "7", label: "二次销售" },
        { value: "8", label: "公司电话" }
      ],
      ownerOptions: [
        // 负责人
        { value: "1", label: "BOSS" },
        { value: "2", label: "Mia" },
        { value: "3", label: "财务" },
        { value: "4", label: "市场" },
        { value: "5", label: "系统管理员" },
        { value: "6", label: "销售" },
        { value: "7", label: "销售总监" }
      ],
      contractTypeOptions: [], // 合同类型
      contractStatusOptions: [], // 合同状态
      currencyOptions: [
        { value: "1", label: "人民币(¥)" },
        { value: "2", label: "英镑(£)" },
        { value: "3", label: "欧元(€)" }
      ], // 币种
      approvalWorkflowOptions: [], // 审批流程
      productTableList: {
        tableData: [
          {
            id: "1",
            productNumber: "123",
            date: "2016-05-02",
            name: "王小虎",
            address: "上海市普陀区金沙江路 1518 弄"
          }
        ]
      }
    }
  },
  created() {},
  methods: {
    handleClose() {
      this.editConfig.visible = false
    },
    // 添加附件
    addAnnexClick() {},
    // 设置允许上传文件格式
    setFormatClick() {}
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.service-contract {
  .basic-info {
    .basic-info-title {
      background-color: #f4f8fe;
      padding-left: 10px;
      font-size: 15px;
      font-weight: bold;
      color: #666;
      height: 42px;
      line-height: 42px;
    }
    .basic-info-view {
      margin-top: 10px;
      padding-right: 40px;
      .custom-name {
        display: flex;
        .common-select-btn {
          margin-left: 5px;
          font-size: 18px;
        }
      }
    }
    .address-view {
      margin-top: 10px;
      padding-right: 40px;
    }
    .annex-view {
      display: flex;
      color: #6166d3;
      .setFormat {
        margin-left: 10px;
      }
    }
  }
  .unflod-collapse {
    display: flex;
    height: 30px;
    justify-content: center;
    align-items: center;
    color: #6166d3;
  }
  .dialog-footer {
    background-color: #f5f5f5;
    height: 55px;
    line-height: 55px;
  }
}
::v-deep {
  .el-dialog__header {
    padding: 12.5px 10px;
    border-bottom: 1px solid #e5e5e5;
    .el-dialog__title {
      font-size: 15px;
      color: #323232;
      font-weight: bold;
    }
  }
  .el-dialog__body {
    padding: 0px;
  }
  .el-dialog__footer {
    padding: 0px;
    text-align: center;
    box-sizing: border-box;
    border-top: 1px solid #dadee5;
  }
}
</style>
src/views/service/serviceContract/index.vue
New file
@@ -0,0 +1,199 @@
<template>
  <div class="sales-lead">
    <SearchCommonView ref="searchCommonView" :query-class-options="queryClassOptions" :search-options="searchOptions" />
    <div class="btn-pager">
      <PublicFunctionBtnView :submit-approval="true" :operates-list="operatesList" />
      <PagerView class="page" />
    </div>
    <TableCommonView ref="tableListRef" :table-list="tableList">
      <template slot="tableButton">
        <el-table-column label="操作" width="60">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small">编辑</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCommonView>
    <!-- 新建/编辑销售线索 -->
    <AddServiceContractDialog v-if="editConfig.visible" :edit-common-config="editConfig" />
  </div>
</template>
<script>
import SearchCommonView from "@/components/makepager/SearchCommonView"
import PublicFunctionBtnView from "@/components/makepager/PublicFunctionBtnView"
import PagerView from "@/components/makepager/PagerView"
import TableCommonView from "@/components/makepager/TableCommonView"
import AddServiceContractDialog from "@/views/service/serviceContract/AddServiceContractDialog"
export default {
  name: "SalesLead",
  props: {},
  components: {
    SearchCommonView,
    PublicFunctionBtnView,
    PagerView,
    TableCommonView,
    AddServiceContractDialog
  },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      tableList: {},
      queryClassOptions: [
        { value: "1", label: "全部" },
        { value: "2", label: "30天后过期" },
        { value: "3", label: "60天后过期" },
        { value: "4", label: "已过期15天" },
        { value: "5", label: "已过期60天" }
      ],
      searchOptions: [],
      operatesList: [
        { id: "1", name: "共享" },
        { id: "2", name: "批量编辑" },
        { id: "3", name: "导出" },
        { id: "4", name: "下载全部附件" },
        { id: "5", name: "更改创建人" },
        { id: "6", name: "电子签署管理后台" },
        { id: "7", name: "树结构设置" },
        { id: "8", name: "审批设置" },
        { id: "9", name: "恢复预设列宽" }
      ],
      editConfig: {
        visible: false,
        title: "新建",
        infomation: {}
      }
    }
  },
  created() {
    this.setTable()
  },
  methods: {
    setTable() {
      this.tableList = {
        tableInfomation: [
          {
            serviceContractNumber: "FWHT20230703123",
            customName: "上海铃铛信息科技有限公司",
            signDate: "2023-06-26",
            contractType: "按年",
            contractStatus: "已创建",
            owner: "Boss",
            productName: "软件",
            startDate: "2023-06-26",
            endDate: "2024-06-25",
            priceTax: "¥5,000.00"
          }
        ],
        tableColumn: [
          { label: "服务合同编号", prop: "serviceContractNumber", min: 100 }, // 服务合同编号
          { label: "客户名称", prop: "customName", min: 120 }, // 客户名称
          { label: "签约日期", prop: "signDate" }, // 签约日期
          { label: "合同类型", prop: "contractType" }, // 合同类型
          { label: "合同状态", prop: "contractStatus" }, // 合同状态
          { label: "负责人", prop: "owner" }, // 负责人
          { label: "产品名称", prop: "productName" }, // 产品名称
          { label: "服务开始日", prop: "startDate" }, // 服务开始日
          { label: "服务到期日", prop: "endDate" }, // 服务到期日
          { label: "价税合计", prop: "priceTax" } // 价税合计
        ]
      }
      this.searchOptions = []
      for (let i = 0; i < this.tableList.tableColumn.length; i++) {
        const label = this.tableList.tableColumn[i].label
        this.searchOptions.push({ value: (i + 1).toString(), label: label })
      }
    },
    // 新建
    addBtnClick() {
      this.editConfig.visible = true
      this.editConfig.title = "新建"
      this.editConfig.infomation = {
        customName: "",
        serviceContractNumber: "AC6521",
        owner: "5",
        contactName: "",
        salesOpportunity: "",
        contractOrder: "",
        quotation: "",
        contractType: "",
        signDate: "",
        startDate: "",
        endDate: "",
        customType: "",
        customSource: "",
        importantLevel: "",
        serviceAgent: "",
        nextFollowupDate: "",
        latestServiceDate: "",
        customStatus: "",
        phoneNumber: "",
        duties: "",
        wechat: "1",
        contactsEmail: "",
        industry: "",
        legalPerson: "",
        registerTime: "",
        registerCapital: "",
        companyNature: "",
        customerSize: "",
        operateRange: "",
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        notes: "",
        approvalWorkflow: "",
        approvalSteps: "",
        approvalPerson: "",
        approvalUrgent: "",
        approvalOpinion: ""
      }
    },
    // 编辑
    handleClick(row) {
      console.log(row)
      this.editSalesLeadConfig.visible = true
      this.editSalesLeadConfig.title = "编辑"
      this.editSalesLeadConfig.infomation = {
        customName: row.customName,
        saleLeadNumber: row.saleLeadNumber,
        contactName: row.contactName,
        contactDuties: row.contactDuties,
        phoneNumber: row.phoneNumber,
        businessStatus: "新建",
        businessSource: row.businessSource,
        owner: row.owner,
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.sales-lead {
  .btn-pager {
    display: flex;
    .page {
      margin-left: auto;
    }
  }
}
</style>
src/views/service/serviceFeeManage/index.vue
New file
@@ -0,0 +1,178 @@
<template>
  <div class="sales-lead">
    <SearchCommonView ref="searchCommonView" :query-class-options="queryClassOptions" :search-options="searchOptions" />
    <div class="btn-pager">
      <PublicFunctionBtnView
        :duplicate-check="true"
        :list-button="true"
        :map-button="true"
        :statistics="true"
        :operates-list="operatesList"
      />
      <PagerView class="page" />
    </div>
    <TableCommonView ref="tableListRef" :table-list="tableList">
      <template slot="tableButton">
        <el-table-column label="操作" width="100">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small">编辑</el-button>
            <el-button type="text" size="small">跟进</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCommonView>
    <!-- 新建/编辑销售线索 -->
    <AddSalesLeadDialog v-if="editSalesLeadConfig.visible" :edit-sales-lead-config="editSalesLeadConfig" />
  </div>
</template>
<script>
import SearchCommonView from "@/components/makepager/SearchCommonView"
import PublicFunctionBtnView from "@/components/makepager/PublicFunctionBtnView"
import PagerView from "@/components/makepager/PagerView"
import TableCommonView from "@/components/makepager/TableCommonView"
import AddSalesLeadDialog from "@/views/custom/salesLead/AddSalesLeadDialog"
export default {
  name: "SalesLead",
  props: {},
  components: {
    SearchCommonView,
    PublicFunctionBtnView,
    PagerView,
    TableCommonView,
    AddSalesLeadDialog
  },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      tableList: {},
      queryClassOptions: [
        { value: "1", label: "全部" },
        { value: "2", label: "广告宣传" },
        { value: "3", label: "跟进中" },
        { value: "4", label: "失败关闭" }
      ],
      searchOptions: [],
      operatesList: [
        { id: "1", name: "共享" },
        { id: "2", name: "批量编辑" },
        { id: "3", name: "导出" },
        { id: "4", name: "下载全部附件" },
        { id: "5", name: "更改创建人" },
        { id: "6", name: "树结构设置" },
        { id: "7", name: "审批设置" },
        { id: "8", name: "公海参数设置" }
      ],
      editSalesLeadConfig: {
        visible: false,
        title: "新建",
        infomation: {}
      }
    }
  },
  created() {
    this.setTable()
  },
  methods: {
    setTable() {
      this.tableList = {
        tableInfomation: [
          {
            customName: "123123",
            customType: "普通客户",
            salesHead: "系统管理员",
            modifyTime: "2023-0703 11:22:12",
            customerSize: "499以上",
            importantLevel: "A类客户",
            customNumber: "AC651",
            customStatus: "潜在客户",
            productName: "自动打印机",
            startDate: "2023-06-27",
            endDate: "2024-07-15"
          }
        ],
        tableColumn: [
          { label: "客户名称", prop: "customName", min: 120 }, // 客户名称
          { label: "客户类型", prop: "customType", min: 90 }, // 客户类型
          { label: "销售负责人", prop: "salesHead" }, // 销售负责人
          { label: "修改时间", prop: "modifyTime", min: 100 }, // 修改时间
          { label: "客户规模", prop: "customerSize" }, // 客户规模
          { label: "重要级别", prop: "importantLevel" }, // 重要级别
          { label: "客户编号", prop: "customNumber" }, // 客户编号
          { label: "客户状态", prop: "customStatus" }, // 客户状态
          { label: "产品名称", prop: "productName" }, // 产品名称
          { label: "服务开始日期", prop: "startDate" }, // 服务开始日期
          { label: "服务到期日", prop: "endDate" } // 服务到期日
        ]
      }
      this.searchOptions = []
      for (let i = 0; i < this.tableList.tableColumn.length; i++) {
        const label = this.tableList.tableColumn[i].label
        this.searchOptions.push({ value: (i + 1).toString(), label: label })
      }
    },
    // 新建
    addBtnClick() {
      this.editSalesLeadConfig.visible = true
      this.editSalesLeadConfig.title = "新建"
      this.editSalesLeadConfig.infomation = {
        customName: "",
        saleLeadNumber: "LEA50",
        contactName: "",
        contactDuties: "",
        phoneNumber: "",
        businessStatus: "新建",
        businessSource: "1",
        owner: "",
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    },
    // 编辑
    handleClick(row) {
      console.log(row)
      this.editSalesLeadConfig.visible = true
      this.editSalesLeadConfig.title = "编辑"
      this.editSalesLeadConfig.infomation = {
        customName: row.customName,
        saleLeadNumber: row.saleLeadNumber,
        contactName: row.contactName,
        contactDuties: row.contactDuties,
        phoneNumber: row.phoneNumber,
        businessStatus: "新建",
        businessSource: row.businessSource,
        owner: row.owner,
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.sales-lead {
  .btn-pager {
    display: flex;
    .page {
      margin-left: auto;
    }
  }
}
</style>
src/views/service/serviceFollowup/index.vue
New file
@@ -0,0 +1,158 @@
<template>
  <div class="sales-lead">
    <SearchCommonView ref="searchCommonView" :query-class-options="queryClassOptions" :search-options="searchOptions" />
    <div class="btn-pager">
      <PublicFunctionBtnView :import-button="false" :operates-list="operatesList" />
      <PagerView class="page" />
    </div>
    <TableCommonView ref="tableListRef" :table-list="tableList">
      <template slot="tableButton">
        <el-table-column label="操作" width="60">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small">编辑</el-button>
          </template>
        </el-table-column>
      </template>
    </TableCommonView>
    <!-- 新建/编辑销售线索 -->
    <AddSalesLeadDialog v-if="editSalesLeadConfig.visible" :edit-sales-lead-config="editSalesLeadConfig" />
  </div>
</template>
<script>
import SearchCommonView from "@/components/makepager/SearchCommonView"
import PublicFunctionBtnView from "@/components/makepager/PublicFunctionBtnView"
import PagerView from "@/components/makepager/PagerView"
import TableCommonView from "@/components/makepager/TableCommonView"
import AddSalesLeadDialog from "@/views/custom/salesLead/AddSalesLeadDialog"
export default {
  name: "SalesLead",
  props: {},
  components: {
    SearchCommonView,
    PublicFunctionBtnView,
    PagerView,
    TableCommonView,
    AddSalesLeadDialog
  },
  computed: {
    searchCommonHeight() {
      return this.$refs.searchCommonView.offsetHeight
    }
  },
  data() {
    return {
      tableList: {},
      queryClassOptions: [{ value: "1", label: "全部" }],
      searchOptions: [],
      operatesList: [
        { id: "1", name: "共享" },
        { id: "2", name: "批量编辑" },
        { id: "3", name: "导出" },
        { id: "4", name: "下载全部附件" },
        { id: "5", name: "更改创建人" },
        { id: "6", name: "树结构设置" },
        { id: "7", name: "审批设置" },
        { id: "8", name: "恢复预设列宽" }
      ],
      editSalesLeadConfig: {
        visible: false,
        title: "新建",
        infomation: {}
      }
    }
  },
  created() {
    this.setTable()
  },
  methods: {
    setTable() {
      this.tableList = {
        tableInfomation: [
          {
            followupNumber: "HF30",
            customName: "上海通用机械有限公司",
            contactName: "董奇伟",
            customServiceForm: "TT5031",
            visitor: "系统管理员",
            satisfaction: "100%",
            modifyTime: "2023-0703 11:22:12"
          }
        ],
        tableColumn: [
          { label: "回访单编号", prop: "followupNumber", min: 80 }, // 回访单编号
          { label: "客户名称", prop: "customName", min: 130 }, // 客户名称
          { label: "联系人姓名", prop: "contactName" }, // 联系人姓名
          { label: "客户服务单", prop: "customServiceForm" }, // 客户服务单
          { label: "回访人", prop: "visitor" }, // 回访人
          { label: "满意度", prop: "satisfaction" }, // 满意度
          { label: "修改时间", prop: "modifyTime" } // 修改时间
        ]
      }
      this.searchOptions = []
      for (let i = 0; i < this.tableList.tableColumn.length; i++) {
        const label = this.tableList.tableColumn[i].label
        this.searchOptions.push({ value: (i + 1).toString(), label: label })
      }
    },
    // 新建
    addBtnClick() {
      this.editSalesLeadConfig.visible = true
      this.editSalesLeadConfig.title = "新建"
      this.editSalesLeadConfig.infomation = {
        customName: "",
        saleLeadNumber: "LEA50",
        contactName: "",
        contactDuties: "",
        phoneNumber: "",
        businessStatus: "新建",
        businessSource: "1",
        owner: "",
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    },
    // 编辑
    handleClick(row) {
      console.log(row)
      this.editSalesLeadConfig.visible = true
      this.editSalesLeadConfig.title = "编辑"
      this.editSalesLeadConfig.infomation = {
        customName: row.customName,
        saleLeadNumber: row.saleLeadNumber,
        contactName: row.contactName,
        contactDuties: row.contactDuties,
        phoneNumber: row.phoneNumber,
        businessStatus: "新建",
        businessSource: row.businessSource,
        owner: row.owner,
        position: "",
        map: "",
        country: "1",
        province: "1",
        city: "1",
        region: "1",
        address: ""
      }
    }
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.sales-lead {
  .btn-pager {
    display: flex;
    .page {
      margin-left: auto;
    }
  }
}
</style>
vue.config.js
New file
@@ -0,0 +1,54 @@
const { defineConfig } = require("@vue/cli-service")
module.exports = defineConfig({
  transpileDependencies: true
})
// const path = require("path")
// const getServerJson = require("./public/serverconfig")
// const devServer = require("./vue.develop.config")
// const { context } = getServerJson
// function resolve(dir) {
//   return path.join(__dirname, dir)
// }
// module.exports = {
//   publicPath: context,
//   lintOnSave: false,
//   productionSourceMap: false, // 如果你不需要生产环境的source map, 可以将其设置为false 以加速生产环境构建
//   devServer,
//   transpileDependencies: [
//     // 兼容IE11浏览器(兼容npm包和cnpm包)
//     "crypto-js",
//     "sockjs-client"
//   ],
//   configureWebpack: (config) => {
//     if (process.env.NODE_ENV === "production") {
//       // 为生产环境修改配置
//       config.optimization.minimizer[0].options.terserOptions.compress.warings = false
//       config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
//       config.optimization.minimizer[0].options.terserOptions.compress.drop_debugger = true
//       config.optimization.minimizer[0].options.terserOptions.compress.pure_funcs = ["console.log"]
//       config.performance = {
//         hints: "warning",
//         maxEntrypointSize: 20000000, // 入口起点的最大体积
//         maxAssetSize: 10000000 // 生成文件的最大体积
//       }
//     } else {
//       // 为开发环境修改配置
//       config.devtool = "eval-source-map"
//     }
//   },
//   chainWebpack(config) {
//     // 设置svg导入
//     config.module.rule("svg").exclude.add(resolve("srv/assets/icons")).end()
//     config.module
//       .rule("icons")
//       .test(/\.svg$/)
//       .include.add(resolve("src/assets/icons"))
//       .end()
//       .use("svg-sprite-loader")
//       .loader("svg-sprite-loader")
//       .options({
//         symbolId: "icon-[name]"
//       })
//       .end()
//   }
// }
vue.develop.config.js
New file
@@ -0,0 +1,18 @@
const { manageContextPath } = require("./public/serverconfig.js")
// 开发
const targetProxy = "http://basic-stable.cn" // 地址需后端提供
module.exports = {
  open: true,
  proxy: {
    [manageContextPath]: {
      target: targetProxy,
      changeOrigin: true
    }
  },
  watchOptions: {
    aggregateTimeout: 300, // 改动延迟时间
    poll: 1000, // 轮询时间
    ignored: /node_modules/
  }
}