【电销老师】 新增# 跟进信息表单和跟进记录
parent
01d3cf875d
commit
cf132dd72a
|
@ -0,0 +1,64 @@
|
|||
<template>
|
||||
<view class="p-[32rpx] bg-white">
|
||||
<view class="flex justify-between items-center mb-[20rpx]">
|
||||
<text class="text-[44rpx] font-bold">修改跟进信息</text>
|
||||
<text class="text-[28rpx]">全部清空</text>
|
||||
</view>
|
||||
<TForm ref="tForm" :model="form" :rules="rules" errorType="toast">
|
||||
<TFormItem prop="clientName">
|
||||
<TInputField
|
||||
v-model="form.clientName"
|
||||
label="客户姓名"
|
||||
placeholder="请填写客户姓名(必填)"
|
||||
inputAlign="left"
|
||||
/>
|
||||
</TFormItem>
|
||||
<TFormItem prop="mobile">
|
||||
<TInputField
|
||||
v-model="form.mobile"
|
||||
label="电话"
|
||||
placeholder="请填写电话(必填)"
|
||||
inputAlign="left"
|
||||
/>
|
||||
</TFormItem>
|
||||
<TFormItem prop="desc">
|
||||
<TTextareaField label="基本情况" placeholder="请填写基本情况(必填)" autoHeight />
|
||||
</TFormItem>
|
||||
</TForm>
|
||||
<u-button class="btn" color="#0E66FB" shape="circle" @click="handleConfirm">确认</u-button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const tForm = ref()
|
||||
const form = ref({
|
||||
clientName: '',
|
||||
mobile: '',
|
||||
desc: ''
|
||||
})
|
||||
const rules = {
|
||||
clientName: [{ required: true, message: '请填写客户姓名', trigger: 'blur' }],
|
||||
mobile: [{ required: true, message: '请填写电话', trigger: 'blur' }],
|
||||
desc: [{ required: true, message: '请填写基本情况', trigger: 'blur' }]
|
||||
}
|
||||
const handleConfirm = () => {
|
||||
tForm.value
|
||||
.validate()
|
||||
.then(valid => {
|
||||
if (valid) {
|
||||
console.log('校验通过')
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.btn) {
|
||||
button {
|
||||
@apply h-[88rpx] px-[60rpx] mt-[60rpx] mb-[28rpx];
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -94,7 +94,8 @@ const onClear = () => {
|
|||
<style lang="scss" scoped>
|
||||
.design-search {
|
||||
width: 100%;
|
||||
padding: 0 32rpx;
|
||||
padding: 14rpx 24rpx;
|
||||
background-color: $white;
|
||||
.t-search {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
|
|
@ -6,17 +6,26 @@
|
|||
* @FilePath: \chargingpile-uniapp\src\components\design-textarea-field.vue
|
||||
-->
|
||||
<template>
|
||||
<view class="remark" :style="remarkStyle">
|
||||
<view :class="required ? 'field-required' : ''" v-if="label">{{ label }}</view>
|
||||
<view class="design-field">
|
||||
<text class="field" :class="{ 'field-required': required }">{{ label }}</text>
|
||||
<u-textarea
|
||||
class="textarea"
|
||||
v-model="innerValue"
|
||||
:placeholder="placeholder"
|
||||
border="none"
|
||||
:autoHeight="autoHeight"
|
||||
placeholderStyle="color: '#7c7e82'"
|
||||
></u-textarea>
|
||||
<!-- <u-textarea
|
||||
v-model="innerValue"
|
||||
:placeholder="placeholder"
|
||||
:maxlength="maxlength"
|
||||
:count="count"
|
||||
:disabled="disabled"
|
||||
:autoHeight="autoHeight"
|
||||
border="none"
|
||||
placeholderStyle="color: '#7c7e82'"
|
||||
></u-textarea>
|
||||
></u-textarea> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
@ -46,7 +55,7 @@ const props = defineProps({
|
|||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: true
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
|
@ -55,6 +64,10 @@ const props = defineProps({
|
|||
remarkStyle: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
autoHeight: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
@ -75,9 +88,16 @@ watch(
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.remark {
|
||||
@include flex-direction;
|
||||
padding: 32rpx 20rpx 20rpx 32rpx;
|
||||
gap: 20rpx;
|
||||
.design-field {
|
||||
@include flex-align;
|
||||
border-bottom: 1px solid $gray-3;
|
||||
padding: 24rpx 32rpx 24rpx 32rpx;
|
||||
.field {
|
||||
width: 240rpx;
|
||||
}
|
||||
.wrapper,
|
||||
.textarea {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<template>
|
||||
<view class="flex flex-col bg-white rounded-[16rpx] mb-[20rpx]">
|
||||
<view
|
||||
class="flex justify-between px-[24rpx] py-[12rpx] border-b border-solid border-[#F3F3F3]"
|
||||
>
|
||||
<slot name="title" />
|
||||
</view>
|
||||
<view class="px-[24rpx] py-[16rpx] flex flex-col gap-[16rpx]">
|
||||
<slot name="content" />
|
||||
</view>
|
||||
<view class="px-[32rpx] border-t border-solid border-[#F3F3F3] flex justify-end py-[12rpx]">
|
||||
<slot name="action" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
cardInfo: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style scoped></style>
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<w-card>
|
||||
<template #title>
|
||||
<view class="flex justify-between w-full py-[10rpx]">
|
||||
<view class="flex">
|
||||
<text>韩梅梅</text>
|
||||
<view class="flex ml-[48rpx] gap-[4rpx] items-center">
|
||||
<text class="text-primary">18138952909</text>
|
||||
<u-copy content="uview-plus is great !">
|
||||
<TIcon name="icon-copy" color="#0E66FB" />
|
||||
</u-copy>
|
||||
</view>
|
||||
</view>
|
||||
<text>待领取</text>
|
||||
</view>
|
||||
</template>
|
||||
<template #content>
|
||||
<view class="flex gap-[20rpx] mb-[16rpx]">
|
||||
<text class="text-muted w-[128rpx]">基本情况</text>
|
||||
<text class="flex-1">
|
||||
{{ ellipsisDesc(item) }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="flex gap-[20rpx] mb-[16rpx]">
|
||||
<text class="text-muted w-[128rpx]">跟进时间</text>
|
||||
<text class="flex-1">2025-02-08 11:11:30</text>
|
||||
</view>
|
||||
<view class="flex gap-[20rpx] mb-[16rpx]">
|
||||
<text class="text-muted w-[128rpx]">招生老师</text>
|
||||
<text class="flex-1">王五</text>
|
||||
</view>
|
||||
<view class="flex gap-[20rpx]">
|
||||
<text class="text-muted w-[128rpx]">状态</text>
|
||||
<text class="flex-1">账号不存在</text>
|
||||
</view>
|
||||
</template>
|
||||
<template #action>
|
||||
<u-button color="#0E66FB" shape="circle" @click="handleEditFollow">修改跟进</u-button>
|
||||
</template>
|
||||
</w-card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
const ellipsisDesc = computed(
|
||||
() => item => item.desc?.length >= 14 ? item.desc?.slice(0, 14) + '...' : item.desc
|
||||
)
|
||||
const handleEditFollow = () => {
|
||||
const { item } = props
|
||||
uni.navigateTo({
|
||||
url: '/bundle/pages/follow_edit/index?id=' + item.id
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped></style>
|
|
@ -0,0 +1,64 @@
|
|||
<template>
|
||||
<view class="mt-[32rpx] p-[32rpx] bg-white">
|
||||
<view class="flex justify-between items-center mb-[20rpx]">
|
||||
<text class="text-[44rpx] font-bold">跟进信息</text>
|
||||
<text class="text-[28rpx]">全部清空</text>
|
||||
</view>
|
||||
<TForm ref="tForm" :model="form" :rules="rules" errorType="toast">
|
||||
<TFormItem prop="clientName">
|
||||
<TInputField
|
||||
v-model="form.clientName"
|
||||
label="客户姓名"
|
||||
placeholder="请填写客户姓名(必填)"
|
||||
inputAlign="left"
|
||||
/>
|
||||
</TFormItem>
|
||||
<TFormItem prop="mobile">
|
||||
<TInputField
|
||||
v-model="form.mobile"
|
||||
label="电话"
|
||||
placeholder="请填写电话(必填)"
|
||||
inputAlign="left"
|
||||
/>
|
||||
</TFormItem>
|
||||
<TFormItem prop="desc">
|
||||
<TTextareaField label="基本情况" placeholder="请填写基本情况(必填)" autoHeight />
|
||||
</TFormItem>
|
||||
</TForm>
|
||||
<u-button class="btn" color="#0E66FB" shape="circle" @click="handleConfirm">确认</u-button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const tForm = ref()
|
||||
const form = ref({
|
||||
clientName: '',
|
||||
mobile: '',
|
||||
desc: ''
|
||||
})
|
||||
const rules = {
|
||||
clientName: [{ required: true, message: '请填写客户姓名', trigger: 'blur' }],
|
||||
mobile: [{ required: true, message: '请填写电话', trigger: 'blur' }],
|
||||
desc: [{ required: true, message: '请填写基本情况', trigger: 'blur' }]
|
||||
}
|
||||
const handleConfirm = () => {
|
||||
tForm.value
|
||||
.validate()
|
||||
.then(valid => {
|
||||
if (valid) {
|
||||
console.log('校验通过')
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.btn) {
|
||||
button {
|
||||
@apply h-[88rpx] px-[60rpx] mt-[60rpx] mb-[28rpx];
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<view class="flex-1 h-full flex flex-col">
|
||||
<TSearch
|
||||
v-model="searchValue"
|
||||
placeholder="搜索客户姓名/手机号码"
|
||||
backgroundColor="#F5F5F5"
|
||||
/>
|
||||
<view class="flex-1 mt-3 px-2 overflow-auto bg-[#FAFAFE]">
|
||||
<!-- <z-paging
|
||||
ref="paging"
|
||||
v-model="dataList"
|
||||
@query="queryList"
|
||||
:fixed="false"
|
||||
height="100%"
|
||||
> -->
|
||||
|
||||
<clue-card
|
||||
v-for="(item, index) in dataList"
|
||||
:key="`${index} + 'unique'`"
|
||||
:item="item"
|
||||
/>
|
||||
<!-- </z-paging> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { apiOverhaulPagelist } from '@/api/overhaul'
|
||||
import { useZPaging } from '@/hooks/useZPaging'
|
||||
import { ref } from 'vue'
|
||||
import clueCard from './clue-card.vue'
|
||||
|
||||
const searchValue = ref('')
|
||||
const queryParams = ref({})
|
||||
const dataList = ref([
|
||||
{
|
||||
id: 1
|
||||
}
|
||||
])
|
||||
const { paging, queryList, refresh, changeApi, setParams } = useZPaging(
|
||||
queryParams.value,
|
||||
apiOverhaulPagelist,
|
||||
() => {}
|
||||
)
|
||||
</script>
|
||||
<style scoped></style>
|
|
@ -1,5 +1,11 @@
|
|||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/telesale/home/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/salesman/contract/index",
|
||||
"style": {
|
||||
|
@ -96,6 +102,12 @@
|
|||
{
|
||||
"root": "bundle",
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/follow_edit/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/select-role/index",
|
||||
"style": {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<template>
|
||||
<view class="flex flex-col h-screen">
|
||||
<u-tabs
|
||||
:list="tabs"
|
||||
:scrollable="false"
|
||||
:itemStyle="{ height: '44px', flex: 1 }"
|
||||
:activeStyle="{ color: '#0E66FB' }"
|
||||
lineWidth="60"
|
||||
lineColor="#0E66FB"
|
||||
:current="activeTab"
|
||||
@change="handleChangeTab"
|
||||
></u-tabs>
|
||||
<view class="flex-1 bg-gray3">
|
||||
<follow-form v-if="activeTab === 0" />
|
||||
<follow-record v-else-if="activeTab === 1" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import followForm from '@/components/widgets/telesale/follow-form.vue'
|
||||
import followRecord from '@/components/widgets/telesale/follow-record.vue'
|
||||
|
||||
const activeTab = ref(1)
|
||||
const tabs = shallowRef([
|
||||
{ name: '新增跟进', value: 0 },
|
||||
{ name: '跟进动态', value: 1 }
|
||||
])
|
||||
const handleChangeTab = item => {
|
||||
activeTab.value = item.value
|
||||
}
|
||||
</script>
|
||||
<style scoped></style>
|
|
@ -1,214 +1,18 @@
|
|||
@font-face {
|
||||
font-family: 'iconfont'; /* Project id 4649146 */
|
||||
src: url('//at.alicdn.com/t/c/font_4649146_kddkfg8pdqn.woff2?t=1728201715233') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_4649146_kddkfg8pdqn.woff?t=1728201715233') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_4649146_kddkfg8pdqn.ttf?t=1728201715233') format('truetype');
|
||||
font-family: 'iconfont'; /* Project id 4837700 */
|
||||
src: url('//at.alicdn.com/t/c/font_4837700_qu0wamoi86a.woff2?t=1740458346519') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_4837700_qu0wamoi86a.woff?t=1740458346519') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_4837700_qu0wamoi86a.ttf?t=1740458346519') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: 'iconfont' !important;
|
||||
font-size: 32rpx;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-weixiugongren:before {
|
||||
content: '\e60c';
|
||||
}
|
||||
|
||||
.icon-fuzhi_o:before {
|
||||
.icon-copy:before {
|
||||
content: '\eb4e';
|
||||
}
|
||||
|
||||
.icon-tequanG:before {
|
||||
content: '\e668';
|
||||
}
|
||||
|
||||
.icon-overtime:before {
|
||||
content: '\e604';
|
||||
}
|
||||
|
||||
.icon-selected:before {
|
||||
content: '\e67e';
|
||||
}
|
||||
|
||||
.icon-empty:before {
|
||||
content: '\e621';
|
||||
}
|
||||
|
||||
.icon-success-fill:before {
|
||||
content: '\e842';
|
||||
}
|
||||
|
||||
.icon-success-fill-active:before {
|
||||
content: '\f463';
|
||||
}
|
||||
|
||||
.icon-home:before {
|
||||
content: '\f461';
|
||||
}
|
||||
|
||||
.icon-home-active-copy:before {
|
||||
content: '\f462';
|
||||
}
|
||||
|
||||
.icon-my-task:before {
|
||||
content: '\e69e';
|
||||
}
|
||||
|
||||
.icon-my-task-active-copy:before {
|
||||
content: '\e881';
|
||||
}
|
||||
|
||||
.icon-repeal:before {
|
||||
content: '\e76b';
|
||||
}
|
||||
|
||||
.icon-view:before {
|
||||
content: '\e636';
|
||||
}
|
||||
|
||||
.icon-hollow-down:before {
|
||||
content: '\e615';
|
||||
}
|
||||
|
||||
.icon-rmb:before {
|
||||
content: '\e634';
|
||||
}
|
||||
|
||||
.icon-profile:before {
|
||||
content: '\e603';
|
||||
}
|
||||
|
||||
.icon-profile-copy:before {
|
||||
content: '\e87e';
|
||||
}
|
||||
|
||||
.icon-client-copy:before {
|
||||
content: '\e87c';
|
||||
}
|
||||
|
||||
.icon-contract-copy:before {
|
||||
content: '\e87d';
|
||||
}
|
||||
|
||||
.icon-contract:before {
|
||||
content: '\e601';
|
||||
}
|
||||
|
||||
.icon-client:before {
|
||||
content: '\e605';
|
||||
}
|
||||
|
||||
.icon-Cooperation:before {
|
||||
content: '\e749';
|
||||
}
|
||||
|
||||
.icon-success:before {
|
||||
content: '\e843';
|
||||
}
|
||||
|
||||
.icon-xuanze:before {
|
||||
content: '\e627';
|
||||
}
|
||||
|
||||
.icon-solid-time:before {
|
||||
content: '\e63b';
|
||||
}
|
||||
|
||||
.icon-clock:before {
|
||||
content: '\e600';
|
||||
}
|
||||
|
||||
.icon-scan-code:before {
|
||||
content: '\e712';
|
||||
}
|
||||
|
||||
.icon-shaixuan:before {
|
||||
content: '\e641';
|
||||
}
|
||||
|
||||
.icon-location:before {
|
||||
content: '\e625';
|
||||
}
|
||||
|
||||
.icon-add-device:before {
|
||||
content: '\e711';
|
||||
}
|
||||
|
||||
.icon-add-contact:before {
|
||||
content: '\e602';
|
||||
}
|
||||
|
||||
.icon-female:before {
|
||||
content: '\e71a';
|
||||
}
|
||||
|
||||
.icon-male:before {
|
||||
content: '\e71c';
|
||||
}
|
||||
|
||||
.icon-image:before {
|
||||
content: '\e68d';
|
||||
}
|
||||
|
||||
.icon-edit:before {
|
||||
content: '\e67a';
|
||||
}
|
||||
|
||||
.icon-dianhua:before {
|
||||
content: '\e608';
|
||||
}
|
||||
|
||||
.icon-scan:before {
|
||||
content: '\e68b';
|
||||
}
|
||||
|
||||
.icon-baoxiuneirong:before {
|
||||
content: '\e87a';
|
||||
}
|
||||
|
||||
.icon-weixiu:before {
|
||||
content: '\e635';
|
||||
}
|
||||
|
||||
.icon-right:before {
|
||||
content: '\e623';
|
||||
}
|
||||
|
||||
.icon-down:before {
|
||||
content: '\e87f';
|
||||
}
|
||||
|
||||
.icon-up:before {
|
||||
content: '\e880';
|
||||
}
|
||||
|
||||
.icon-left:before {
|
||||
content: '\e87b';
|
||||
}
|
||||
|
||||
.icon-add:before {
|
||||
content: '\e633';
|
||||
}
|
||||
|
||||
.icon-navigator:before {
|
||||
content: '\e631';
|
||||
}
|
||||
|
||||
.icon-mobile:before {
|
||||
content: '\e669';
|
||||
}
|
||||
|
||||
.icon-more:before {
|
||||
content: '\e867';
|
||||
}
|
||||
|
||||
.icon-clear:before {
|
||||
content: '\e648';
|
||||
}
|
||||
|
||||
.icon-search:before {
|
||||
content: '\e64c';
|
||||
}
|
||||
|
|
|
@ -120,7 +120,11 @@ page {
|
|||
}
|
||||
|
||||
.u-textarea {
|
||||
background-color: $gray-1 !important;
|
||||
padding-top: 6rpx !important;
|
||||
padding-bottom: 6rpx !important;
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
// background-color: $gray-1 !important;
|
||||
}
|
||||
// 显示字段的表单,不需要输入
|
||||
.c-form-item-wrapper {
|
||||
|
|
|
@ -11,6 +11,7 @@ $gray1: #7f7f7f;
|
|||
$gray2: #999;
|
||||
$gray3: #dedede;
|
||||
$gray4: #46c6a8;
|
||||
$gray5: #f8f8f8;
|
||||
$blue1: #2759ff;
|
||||
$blue2: #2799ff;
|
||||
$blue3: #495aff;
|
||||
|
|
|
@ -27,8 +27,10 @@ module.exports = {
|
|||
blue: '#4173ff',
|
||||
gray: '#EFEFEF',
|
||||
gray2: '#7C7E82',
|
||||
gray3: '#F8F8F8',
|
||||
lightblack: '#3D3D3D',
|
||||
border: '#F1F1F1'
|
||||
border: '#F1F1F1',
|
||||
border2: '#F3F3F3'
|
||||
},
|
||||
fontSize: {
|
||||
xs: '24rpx',
|
||||
|
|
Loading…
Reference in New Issue