salary
qsh 5 months ago
parent 58929c05ef
commit 8a5ae3948a
  1. 2
      .vscode/settings.json
  2. 13
      src/api/call/index.js
  3. 94
      src/components/SSTable/index.vue
  4. 75
      src/components/Search/src/Search.vue
  5. 8
      src/layout/components/UserInfo/src/UserInfo.vue
  6. 2
      src/plugins/cache/index.js
  7. 7
      src/styles/index.scss
  8. 2
      src/views/Clue/Pool/Comp/DialogClue.vue
  9. 11
      src/views/Clue/Pool/Comp/DialogFollow.vue
  10. 2
      src/views/Clue/Pool/Comp/DialogSuccess.vue
  11. 117
      src/views/Clue/Pool/Comp/DrawerClue.vue
  12. 8
      src/views/Clue/Pool/Comp/follow.data.js
  13. 11
      src/views/Clue/Pool/cluePool.data.js
  14. 41
      src/views/Clue/Pool/index.vue
  15. 7
      src/views/Clue/Set/Comp/ClueGet.vue
  16. 85
      src/views/Clue/Set/Comp/ClueSend.vue
  17. 26
      src/views/Home/Index.vue
  18. 17
      vite.config.js
  19. 8647
      yarn-error.log

@ -8,7 +8,7 @@
"source.fixAll.eslint": "explicit"
},
"[vue]": {
"editor.defaultFormatter": "Vue.volar"
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"

@ -0,0 +1,13 @@
import request from '@/config/axios'
export default {
callLogin(data) {
return request.post({ url: '/call-api/openapi/V2.0.4/agentLogin', data })
},
callUserStatus(data) {
return request.post({ url: '/call-api/openapi/V2.0.4/getAgentStatus', data })
},
callNumber(data) {
return request.post({ url: '/call-api/openapi/V2.0.4/callNumber', data })
}
}

@ -19,10 +19,20 @@
trigger="click"
virtual-triggering
>
<el-checkbox-group v-model="checkedColumns">
<el-checkbox v-for="item in tableColumns" :key="item.field" :label="item.field">
<el-checkbox-group v-model="checkedColumns" @change="confirm">
<draggable
v-model="allColumns"
item-key="field"
ghost-class="draggable-ghost"
:animation="400"
@end="onDragEnd"
>
<template #item="{ element: item }">
<el-checkbox :key="item.field" :label="item.field">
{{ item.label }}
</el-checkbox>
</template>
</draggable>
</el-checkbox-group>
</el-popover>
</div>
@ -37,12 +47,19 @@
</template>
<script setup>
import draggable from 'vuedraggable'
import { useUserStore } from '@/store/modules/user'
import { useRoute } from 'vue-router'
import cache from '@/plugins/cache'
const props = defineProps({
tableObject: { type: Object, default: () => ({ tableList: [] }) },
tableColumns: { type: Array, default: () => [] }
})
const emit = defineEmits(['update:tableObject', 'getList'])
const emit = defineEmits(['update:tableObject', 'getList', 'getCheckedColumns'])
const route = useRoute()
const { id: userId } = useUserStore().user //ID
const currentPage = ref(props.tableObject?.currentPage || 1)
@ -50,9 +67,12 @@ const pageSize = ref(props.tableObject?.pageSize || 20)
const ColumnSetting = ref()
const TableColumnPop = ref()
// 使
const allColumns = ref({})
//
const checkedColumns = ref([])
// ,使
function getList({ page, limit }) {
emit('update:tableObject', { ...props.tableObject, currentPage: page, pageSize: limit })
nextTick(() => {
@ -60,9 +80,75 @@ function getList({ page, limit }) {
})
}
// ""
const clickSetting = () => {
unref(TableColumnPop).TableColumnPop?.delayHide?.()
}
// 使
function getAllColumns() {
// 1.
const localData = getColumn('TableColumnAll')[route.name] || []
// 2. 使
if (localData && localData) {
const newColumns = props.tableColumns.filter(
(item) => !localData.some((it) => it.field == item.field)
)
allColumns.value = [...localData, ...newColumns]
} else {
allColumns.value = [...props.tableColumns]
}
}
//
function getColumn(name = 'shitTable') {
return cache.local.get(`${name}-${userId}`) || {}
}
//
function setColumn(val, name = 'shitTable') {
cache.local.set(`${name}-${userId}`, val)
}
//
function getUserCheckedColumns() {
// 1.
const localData = getColumn('shitTable')[route.name]
// 2. 使使
if (localData && localData.length) {
checkedColumns.value = localData
} else {
checkedColumns.value = allColumns.value.map((it) => it.field)
}
// 3.
emitColumns()
}
//
function onDragEnd() {
const obj = getColumn('TableColumnAll')
obj[route.name] = allColumns.value
// 1.
setColumn(obj, 'TableColumnAll')
// 2.
emitColumns()
}
//
function confirm() {
const obj = getColumn()
obj[route.name] = checkedColumns.value
setColumn(obj, 'shitTable')
emitColumns()
}
//
function emitColumns() {
const arr = allColumns.value.filter((item) => checkedColumns.value.includes(item.field))
emit('getCheckedColumns', arr)
}
getAllColumns()
getUserCheckedColumns()
defineExpose({ getUserCheckedColumns })
</script>
<style lang="scss" scoped></style>

@ -7,6 +7,13 @@ import { findIndex } from '@/utils'
import { cloneDeep } from 'lodash-es'
import { FormSchema } from '@/types/form'
import { useUserStore } from '@/store/modules/user'
import { useRoute } from 'vue-router'
import cache from '@/plugins/cache'
const route = useRoute()
const { id: userId } = useUserStore().user //ID
const { t } = useI18n()
const props = defineProps({
@ -43,8 +50,16 @@ const emit = defineEmits(['search', 'reset'])
const visible = ref(true)
const SchemaSetting = ref()
const SettingPop = ref()
const checkedSchema = ref([])
// 使
const usedSchema = ref([])
const newSchema = computed(() => {
let schema: FormSchema[] = cloneDeep(props.schema)
let schema: FormSchema[] = cloneDeep(usedSchema.value)
if (props.expand && props.expandField && !unref(visible)) {
const index = findIndex(schema, (v: FormSchema) => v.field === props.expandField)
if (index > -1) {
@ -65,6 +80,43 @@ const newSchema = computed(() => {
return schema
})
function initSearch() {
reset()
// 1.
const localData = getColumn('Schema')[route.name]
// 2. 使使
if (localData && localData.length) {
usedSchema.value = localData
} else {
const obj = getColumn('Schema')
obj[route.name] = [props.schema[0]]
setSchema(obj)
usedSchema.value = [props.schema[0]]
}
checkedSchema.value = usedSchema.value.map((it) => it.field)
}
function changeSearch() {
const obj = getColumn('Schema')
obj[route.name] = props.schema.filter((item) => checkedSchema.value.includes(item.field))
setSchema(obj)
initSearch()
}
//
function getColumn(name = 'Schema') {
return cache.local.get(`${name}-${userId}`) || {}
}
//
function setSchema(val: Array<Object>, name = 'Schema') {
cache.local.set(`${name}-${userId}`, val)
}
function setSearch() {
unref(SettingPop).SettingPop?.delayHide?.()
}
const { register, elFormRef, methods } = useForm({
model: props.model || {}
})
@ -96,6 +148,8 @@ const setVisible = () => {
unref(elFormRef)?.resetFields()
visible.value = !unref(visible)
}
initSearch()
</script>
<template>
@ -114,6 +168,25 @@ const setVisible = () => {
>
<template #action>
<div v-if="layout === 'inline'">
<ElButton ref="SchemaSetting" @click="setSearch">
<Icon class="mr-5px" icon="ep:setting" />
查询设置
</ElButton>
<el-popover
ref="SettingPop"
:virtual-ref="SchemaSetting"
placement="bottom"
width="120px"
trigger="click"
virtual-triggering
>
<el-checkbox-group v-model="checkedSchema" @change="changeSearch">
<el-checkbox v-for="item in schema" :key="item.field" :label="item.field">
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
</el-popover>
<!-- update by 芋艿去除搜索的 type="primary"颜色变淡一点 -->
<ElButton v-if="showSearch" @click="search">
<Icon class="mr-5px" icon="ep:search" />

@ -52,7 +52,13 @@ const toDocument = () => {
<ElDropdown :class="prefixCls" trigger="click">
<div class="flex items-center">
<img :src="avatar" alt="" class="w-[calc(var(--logo-height)-25px)] rounded-[50%]" />
<span class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]">
<span
v-if="userName"
class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]"
>
莳松科技管理员
</span>
<span v-else class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]">
{{ userName }}
</span>
</div>

@ -1,5 +1,5 @@
import router from '@/router'
import { name as appName } from '../../../../package.json'
import { name as appName } from '../../../package.json'
let name = `${appName}-${import.meta.env.VITE_APP_ENV}`

@ -17,7 +17,9 @@
}
.el-dialog__body {
overflow-y: auto;
padding-top: 0;
max-height: calc(100% - 118px);
}
/* nprogress 适配 element-plus 的主题色 */
@ -48,3 +50,8 @@
.crud-form-item .el-input__wrapper {
width: 100%;
}
.el-dialog {
margin-top: 5vh;
max-height: 90vh;
}

@ -1,5 +1,5 @@
<template>
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px">
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="800px" style="height: 90vh">
<el-tabs v-model="tabName">
<el-tab-pane label="线索信息" name="info">
<Form

@ -28,6 +28,12 @@
</el-collapse>
</div>
</div>
<template #footer>
<span>
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleSave"> </el-button>
</span>
</template>
</el-dialog>
</template>
@ -256,6 +262,11 @@ const activeQues = ref('')
function filterList() {
showList.value = resultList.filter((it) => it.question.includes(keyword.value))
}
function handleSave() {
console.log('保存成功')
dialogVisible.value = false
}
</script>
<style lang="scss" scoped></style>

@ -1,5 +1,5 @@
<template>
<el-dialog title="成交登记" v-model="show" width="800px">
<el-dialog title="成交登记" v-model="show" width="800px" style="height: 90vh">
<Descriptions :data="info" :schema="schema" :columns="2" />
<el-form :model="form" ref="formRef" :rules="rules" label-width="80px" class="mt-20px">
<el-row :gutter="20">

@ -8,6 +8,7 @@
:destroy-on-close="true"
:show-close="true"
:wrapperClosable="true"
@close="destroyMap"
>
<!-- header -->
<el-skeleton :loading="loading" animated>
@ -51,7 +52,7 @@
<el-button type="danger" plain>删除</el-button>
</div>
</div>
<div v-dompurify-html="followContent"></div>
<div>{{ followContent }}</div>
<div class="flex mt-10px" style="align-items: center">
<div class="flex" style="color: #666; align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
@ -78,7 +79,7 @@
<el-button type="danger" plain>删除</el-button>
</div>
</div>
<div key="followContent" v-dompurify-html="followContent2"></div>
<div>{{ followContent2 }}</div>
<div class="flex mt-10px" style="align-items: center">
<div class="flex" style="color: #666; align-items: center">
<Icon icon="ep:clock" class="mr-5px" />
@ -95,22 +96,11 @@
</el-timeline>
</el-tab-pane>
<el-tab-pane label="详细信息" name="infoDetail">
<el-descriptions :column="2" border>
<el-descriptions-item min-width="150px" label="线索名称">{{
info.name
}}</el-descriptions-item>
<el-descriptions-item min-width="150px" label="联系方式"
>18888888888</el-descriptions-item
<Descriptions :data="info" :schema="schema" :columns="2" />
<el-checkbox v-model="showSchool" :label="true" @change="handleShowSchool"
>展示场地</el-checkbox
>
<el-descriptions-item min-width="150px" label="线索来源">驾考宝典</el-descriptions-item>
<el-descriptions-item min-width="150px" label="意向状态">高意向</el-descriptions-item>
<el-descriptions-item min-width="150px" :span="2" label="诉求"
>这是诉求内容这是诉求内容这是诉求内容这是诉求内容这是诉求内容这是诉求内容这是诉求内容</el-descriptions-item
>
<el-descriptions-item min-width="150px" :span="2" label="备注"
>这是备注内容</el-descriptions-item
>
</el-descriptions>
<div id="dialogMap" class="mt-20px" style="height: 400px; width: 100%"></div>
</el-tab-pane>
<el-tab-pane label="操作记录" name="operateRecord">
<el-timeline>
@ -188,10 +178,42 @@
<script setup>
import DialogFollow from './DialogFollow.vue'
import ImgFlag from '@/assets/imgs/flag/position_blue.png'
import AMapLoader from '@amap/amap-jsapi-loader'
const show = ref(false)
const info = ref(null)
const loading = ref(false)
const schema = ref([
{
field: 'name',
label: '线索名称'
},
{
field: 'contact',
label: '联系方式'
},
{
field: 'supplier',
label: '意向状态'
},
{
field: 'supplier',
label: '创建时间'
},
{
field: 'purchaseCount',
label: '诉求',
span: 2
},
{
field: 'remark',
label: '备注',
isEditor: true,
span: 2
}
])
const followContent = `<p style="color: red;">这是本次跟进的内容。</p><br/><p>我还能放图片,但需要你自己排版:</p><br/><img style="width: 200px;" src="https://q6.itc.cn/images01/20240407/0e6be21aebc847648109304f20370790.jpeg">`
const followContent2 = `<p style="color: red;">这是本次跟进的内容。</p>`
@ -211,9 +233,65 @@ const followList = ref([
}
])
//
const dialogMap = ref(null)
const aMap = ref(null)
function open(row) {
info.value = row
show.value = true
if (!dialogMap.value) {
nextTick(() => {
initMap()
})
}
}
function initMap() {
AMapLoader.load({
key: '2ffb0e2ea90b1df0b8be48ed66e18fc8', //key
version: '2.0'
}).then((AMap) => {
aMap.value = AMap
dialogMap.value = new AMap.Map('dialogMap', {
zoom: 12,
zooms: [2, 22],
center: [117.283042, 31.86119]
})
})
}
const showSchool = ref(false)
const schoolMarkers = ref([])
function handleShowSchool() {
if (showSchool.value) {
let marker1 = new aMap.value.Marker({
map: dialogMap.value,
position: [117.258001, 31.895216],
label: {
content: '慧安驾校桃花社区训练基地',
direction: 'left'
},
icon: ImgFlag,
// extData: element,
clickable: true
})
let marker2 = new aMap.value.Marker({
map: dialogMap.value,
position: [117.286731, 31.902396],
label: {
content: '(皖西)瑞星驾校总校(D)',
direction: 'left'
},
icon: ImgFlag,
// extData: element,
clickable: true
})
schoolMarkers.value = [marker1, marker2]
} else {
dialogMap.value.remove(schoolMarkers.value)
}
}
const infoIndex = ref('followRecord')
@ -229,6 +307,11 @@ function addFollow() {
function updateFollow() {
followRef.value.open('update', { nextFollowTime: '2024-04-01 12:12' })
}
function destroyMap() {
dialogMap.value = null
aMap.value = null
}
</script>
<style lang="scss" scoped></style>

@ -18,7 +18,7 @@ const crudSchemas = reactive([
type: 'datetime',
format: 'YYYY-MM-DD HH:mm',
valueFormat: 'YYYY-MM-DD HH:mm',
placeholder: '创建时间'
placeholder: '本次跟进时间'
}
}
},
@ -45,7 +45,11 @@ const crudSchemas = reactive([
field: 'remark',
isTable: true,
form: {
component: 'Editor',
component: 'Input',
componentProps: {
type: 'textarea',
autosize: { minRows: 5, maxRows: 10 }
},
colProps: {
span: 24
}

@ -28,6 +28,12 @@ const crudSchemas = reactive([
isSearch: true,
isTable: true
},
{
label: '线索位置',
field: 'address',
isSearch: true,
isTable: true
},
{
label: '线索来源',
field: 'resource',
@ -183,6 +189,11 @@ const crudSchemas = reactive([
placeholder: '创建时间'
}
}
},
{
label: '跟进记录',
field: 'followRecord',
isTable: true
}
])
export const { allSchemas } = useCrudSchemas(crudSchemas)

@ -31,7 +31,7 @@
</el-tabs>
<div class="absolute" style="right: 10px; top: 0">
<el-button plain>导入</el-button>
<el-button type="primary" @click="handleInsert">新增</el-button>
<el-button type="primary" @click="handleInsert">新增线索</el-button>
</div>
</div>
<!-- 搜索工作栏 -->
@ -47,14 +47,28 @@
v-model:tableObject="tableObject"
:tableColumns="allSchemas.tableColumns"
@get-list="getTableList"
@get-checked-columns="getCheckedColumns"
>
<el-table-column
v-for="item in allSchemas.tableColumns"
v-for="item in showColumns"
:key="item.field"
:prop="item.field"
:label="item.label"
min-width="120px"
/>
>
<template #default="{ row }">
<div v-if="item.field == 'followRecord'">
<el-button type="primary" text style="padding: 0" @click="handleFollow(row)"
>快速新增</el-button
>
</div>
<div v-else-if="item.field == 'contact'">
<span>{{ row[item.field] }}</span>
<Icon class="ml-5px" icon="ep:phone" @click="makeCall(row.contact)" />
</div>
<span v-else>{{ row[item.field] }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200px" fixed="right">
<template #default="scope">
<el-button type="primary" link @click="handleDetail(scope.row)">详情</el-button>
@ -68,6 +82,7 @@
<DialogClue ref="formRef" />
<DrawerClue ref="drawerRef" />
<DialogSuccess ref="successRef" />
<DialogFollow ref="followRef" />
</div>
</template>
@ -76,6 +91,7 @@ import { allSchemas } from './cluePool.data'
import DialogClue from './Comp/DialogClue.vue'
import DrawerClue from './Comp/DrawerClue.vue'
import DialogSuccess from './Comp/DialogSuccess.vue'
import DialogFollow from './Comp/DialogFollow.vue'
const searchForm = ref({
mode: '2'
@ -83,6 +99,7 @@ const searchForm = ref({
const formRef = ref()
const drawerRef = ref()
const successRef = ref()
const followRef = ref()
// const { tableObject, tableMethods } = useTable({
// getListApi: MailTemplateApi.getMailTemplatePage, //
@ -90,12 +107,20 @@ const successRef = ref()
// })
const tableObject = ref({
tableList: [{ name: '测试', contact: '18888888888' }],
tableList: [{ name: '测试', contact: '17318531354' }],
loading: false,
total: 1,
pageSize: 20,
currentPage: 1
})
const showColumns = ref([])
//
function getCheckedColumns(list) {
showColumns.value = list
}
const setSearchParams = function () {
//
}
@ -117,6 +142,14 @@ function handleDetail(row) {
drawerRef.value.open(row)
}
function handleFollow(row) {
followRef.value.open('create', row)
}
async function makeCall(phone) {
console.log('打电话:' + phone)
}
//
function handleSuccess(row) {
successRef.value.open(row)

@ -1,6 +1,6 @@
<template>
<div>
<el-table :data="list" border stripe>
<el-table :data="list" border>
<el-table-column type="index" width="50" />
<el-table-column label="来源名称">
<template #default="{ row }">
@ -12,6 +12,11 @@
<el-input v-model="row.link" placeholder="请输入" :clearable="false" />
</template>
</el-table-column>
<el-table-column label="是否启用" width="100px">
<template #default="{ row }">
<el-switch v-model="row.inEnable" :active-value="true" :inactive-value="false" />
</template>
</el-table-column>
<el-table-column label="操作" width="100px">
<template #default="{ $index }">
<el-button type="primary" style="padding: 0px" text @click="handleRemove($index)"

@ -1,4 +1,27 @@
<template>
<div class="flex">
<div class="mr-20px" style="width: 500px">
<el-input
v-model="searchForm.keyword"
placeholder="请输入关键字查询"
clearable
class="mb-10px"
@keyup.enter="getUserList"
/>
<el-table :data="userList" @cell-click="selectUser">
<el-table-column prop="name" label="员工姓名" />
<el-table-column prop="phone" label="电话" />
<el-table-column prop="workNum" label="工号" />
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="searchForm.pageSize"
v-model:page="searchForm.pageNum"
:total="total"
@pagination="getUserList"
/>
</div>
<el-form :model="form" ref="sendForm" :rules="rules" label-width="100px" :inline="false">
<el-form-item label="是否自动分配">
<el-radio-group v-model="form.isAuto">
@ -7,7 +30,7 @@
</el-radio-group>
</el-form-item>
<div v-if="form.isAuto">
<el-form-item label="分配对象">
<!-- <el-form-item label="分配对象">
<div>
<el-checkbox
v-model="checkUserAll"
@ -27,7 +50,7 @@
</el-checkbox>
</el-checkbox-group>
</div>
</el-form-item>
</el-form-item> -->
<el-form-item label="线索来源">
<div>
<el-checkbox
@ -51,6 +74,14 @@
</el-form-item>
<el-form-item label="权重配置">
<div>
<el-radio-group v-model="form.isRandom">
<el-radio :label="1">
<Tooltip message="根据剩余的线索平均分配到未分配线索的所有人" />
平均分配
</el-radio>
<el-radio :label="0"> 权重分配 </el-radio>
</el-radio-group>
<div v-if="form.isRandom == 0">
<div v-for="(item, index) in intentionOptions" :key="index" class="flex mb-10px">
<div class="mr-15px" style="width: 100px">{{ item.label }}</div>
<el-input v-model="item.value" type="number" placeholder="请输入权重">
@ -58,6 +89,7 @@
</el-input>
</div>
</div>
</div>
</el-form-item>
<el-form-item label="分配时间">
<el-time-picker
@ -74,9 +106,20 @@
<el-button>重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
const searchForm = ref({
keyword: '',
pageSize: 20,
pageNum: 1
})
const total = ref(1)
const userList = ref([{ name: '张三', phone: '1888888888', workNum: '202101030001' }])
const form = ref({
isAuto: 1,
users: [1, 2],
@ -85,23 +128,27 @@ const form = ref({
})
const rules = ref({})
const checkUserAll = ref(false)
const userIndeterminate = ref(true)
const userOptions = ref([
{ label: '张三', value: 1 },
{ label: '李四', value: 2 },
{ label: '王二', value: 3 }
])
// const checkUserAll = ref(false)
// const userIndeterminate = ref(true)
// const userOptions = ref([
// { label: '', value: 1 },
// { label: '', value: 2 },
// { label: '', value: 3 }
// ])
function userCheckAllChange(val) {
form.value.users = val ? userOptions.value.map((it) => it.value) : []
userIndeterminate.value = false
}
// function userCheckAllChange(val) {
// form.value.users = val ? userOptions.value.map((it) => it.value) : []
// userIndeterminate.value = false
// }
function userCheckedChange(val) {
const checkedCount = val.length
checkUserAll.value = checkedCount == userOptions.value.length
userIndeterminate.value = checkedCount > 0 && checkedCount < userOptions.value.length
// function userCheckedChange(val) {
// const checkedCount = val.length
// checkUserAll.value = checkedCount == userOptions.value.length
// userIndeterminate.value = checkedCount > 0 && checkedCount < userOptions.value.length
// }
function getUserList() {
console.log('获取列表')
}
function onSubmit() {
@ -133,6 +180,10 @@ const intentionOptions = ref([
{ label: '低意向', value: 20 },
{ label: '未知意向', value: 40 }
])
function selectUser(row) {
console.log(row)
}
</script>
<style lang="scss" scoped></style>

@ -68,10 +68,10 @@
</el-skeleton>
</el-card>
<el-row class="mt-10px" :gutter="10" justify="space-between">
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-10px">
<!-- <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-10px">
<el-card shadow="never">
<template #header>
<div class="flex justify-between h-3">
<div class="flex justify-between ">
<span>本月成交来源</span>
</div>
</template>
@ -79,11 +79,11 @@
<Echart :options="pieOptionsData" :height="280" />
</el-skeleton>
</el-card>
</el-col>
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-10px">
</el-col> -->
<el-col :xl="8" :lg="8" :md="12" :sm="12" :xs="24" class="mb-10px">
<el-card shadow="never">
<template #header>
<div class="flex justify-between h-3">
<div class="flex justify-between">
<span>成交率</span>
</div>
</template>
@ -94,10 +94,10 @@
</el-skeleton>
</el-card>
</el-col>
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-10px">
<el-col :xl="8" :lg="8" :md="12" :sm="12" :xs="24" class="mb-10px">
<el-card shadow="never">
<template #header>
<div class="flex justify-between h-3">
<div class="flex justify-between items-center">
<span>跟进榜Top10</span>
<el-radio-group v-model="followDate" size="small">
<el-radio label="day">本日</el-radio>
@ -123,18 +123,16 @@
</el-skeleton>
</el-card>
</el-col>
<el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24" class="mb-10px">
<el-col :xl="8" :lg="8" :md="12" :sm="12" :xs="24" class="mb-10px">
<el-card shadow="never">
<template #header>
<div class="flex justify-between h-3">
<span>本月成交榜Top10</span>
</div>
<div class="flex justify-between"> 本月成交榜Top10 </div>
</template>
<el-skeleton :loading="loading" animated>
<el-table :data="followList" size="small">
<el-table-column prop="sort" label="排名" width="50" />
<el-table-column prop="name" label="姓名" width="70" />
<el-table-column prop="count" label="跟进数量" width="70" />
<el-table-column prop="count" label="成交数量" width="70" />
<el-table-column prop="orgName" label="所属组织" />
</el-table>
</el-skeleton>
@ -255,4 +253,8 @@ getAllApi()
.number-font {
font-family: numberFont !important;
}
:deep(.el-card__header) {
padding: 10px;
}
</style>

@ -30,16 +30,17 @@ export default ({ command, mode }) => {
// 端口号
port: env.VITE_PORT,
host: '0.0.0.0',
open: env.VITE_OPEN === 'true'
open: env.VITE_OPEN === 'true',
// 本地跨域代理. 目前注释的原因:暂时没有用途,server 端已经支持跨域
// proxy: {
// ['/admin-api']: {
proxy: {
['/call-api']: {
// target: env.VITE_BASE_URL,
// ws: false,
// changeOrigin: true,
// rewrite: (path) => path.replace(new RegExp(`^/admin-api`), ''),
// },
// },
target: 'http://119.3.87.30:443',
ws: false,
changeOrigin: true,
rewrite: (path) => path.replace(new RegExp(`^/call-api`), '')
}
}
},
// 项目使用的vite插件。 单独提取到build/vite/plugin中管理
plugins: createVitePlugins(),

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save