【招生老师】 新增# 跟进列表
parent
cf132dd72a
commit
702b348e83
|
@ -13,7 +13,7 @@ import { getAllDict } from '@/hooks/useDictOptions'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
getAllDict()
|
// getAllDict()
|
||||||
|
|
||||||
onLaunch(async () => {
|
onLaunch(async () => {
|
||||||
appStore.getSystemInfoFn()
|
appStore.getSystemInfoFn()
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
<template>
|
||||||
|
<view class="bg-[#FAFAFE]">
|
||||||
|
<view class="bg-white px-[32rpx]">
|
||||||
|
<TForm ref="tForm" :model="form" :rules="rules" errorType="toast">
|
||||||
|
<TFormItem prop="publishName">
|
||||||
|
<TInputField
|
||||||
|
v-model="form.publishName"
|
||||||
|
label="发布人"
|
||||||
|
placeholder=""
|
||||||
|
inputAlign="left"
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="120"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="clientName">
|
||||||
|
<TInputField
|
||||||
|
v-model="form.clientName"
|
||||||
|
label="客户姓名"
|
||||||
|
placeholder=""
|
||||||
|
inputAlign="left"
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="120"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="mobile">
|
||||||
|
<TInputField
|
||||||
|
v-model="form.mobile"
|
||||||
|
label="电话"
|
||||||
|
placeholder=""
|
||||||
|
inputAlign="left"
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="120"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="desc">
|
||||||
|
<TTextareaField
|
||||||
|
v-model="form.desc"
|
||||||
|
label="基本情况"
|
||||||
|
placeholder=""
|
||||||
|
autoHeight
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="120"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="status">
|
||||||
|
<TInputField
|
||||||
|
v-model="parseStatusText"
|
||||||
|
label="状态"
|
||||||
|
placeholder=""
|
||||||
|
inputAlign="left"
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="120"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="isComplete">
|
||||||
|
<TSwitchField
|
||||||
|
v-model="form.isComplete"
|
||||||
|
label="是否转化成功"
|
||||||
|
:labelWidth="120"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="remark">
|
||||||
|
<TTextareaField
|
||||||
|
v-model="form.remark"
|
||||||
|
label="备注"
|
||||||
|
placeholder="请填写备注(选填)"
|
||||||
|
autoHeight
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="120"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
</TForm>
|
||||||
|
</view>
|
||||||
|
<view class="px-[60rpx]">
|
||||||
|
<u-button class="btn" color="#0E66FB" shape="circle" @click="handleSubmit">
|
||||||
|
提交
|
||||||
|
</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { shallowRef } from 'vue'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const id = ref('')
|
||||||
|
|
||||||
|
const tForm = ref()
|
||||||
|
const form = ref({
|
||||||
|
publishName: '张三',
|
||||||
|
clientName: '张三',
|
||||||
|
mobile: '18138952909',
|
||||||
|
desc: '学生爸爸接电话,学生高三毕业,300多分,家长不清楚学生收到录取通知,家长说学生不读书了,我让家长先问问学生对未来的规划先和学生沟通一下,家长同意我们加他微信发专业资料给他看看,可以在微信上问问学生具体情况。推荐3+2,给家长发一下学校简介和专业资料。',
|
||||||
|
status: 1,
|
||||||
|
isComplete: 0,
|
||||||
|
remark: ''
|
||||||
|
})
|
||||||
|
const rules = {
|
||||||
|
isComplete: [{ required: true, message: '请选择是否转化成功' }]
|
||||||
|
}
|
||||||
|
const statusList = shallowRef([
|
||||||
|
{ label: '账号已添加', value: 1 },
|
||||||
|
{ label: '账号不存在', value: 2 },
|
||||||
|
{ label: '账号未通过', value: 3 }
|
||||||
|
])
|
||||||
|
const parseStatusText = computed(
|
||||||
|
() => statusList.value.find(item => item.value == form.value.status)?.label
|
||||||
|
)
|
||||||
|
|
||||||
|
onLoad(option => {
|
||||||
|
if (option?.id) {
|
||||||
|
id.value = option.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const handleSubmit = () => {
|
||||||
|
tForm.value
|
||||||
|
.validate()
|
||||||
|
.then(valid => {
|
||||||
|
if (valid) {
|
||||||
|
console.log('校验通过', form.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
:deep(.btn) {
|
||||||
|
button {
|
||||||
|
@apply h-[88rpx] mt-[48rpx] mb-[28rpx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,112 @@
|
||||||
|
<template>
|
||||||
|
<view class="bg-[#FAFAFE]">
|
||||||
|
<view class="bg-white px-[32rpx]">
|
||||||
|
<TForm ref="tForm" :model="form" :rules="rules" errorType="toast">
|
||||||
|
<TFormItem prop="publishName">
|
||||||
|
<TInputField
|
||||||
|
v-model="form.publishName"
|
||||||
|
label="发布人"
|
||||||
|
placeholder=""
|
||||||
|
inputAlign="left"
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="100"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="clientName">
|
||||||
|
<TInputField
|
||||||
|
v-model="form.clientName"
|
||||||
|
label="客户姓名"
|
||||||
|
placeholder=""
|
||||||
|
inputAlign="left"
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="100"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="mobile">
|
||||||
|
<TInputField
|
||||||
|
v-model="form.mobile"
|
||||||
|
label="电话"
|
||||||
|
placeholder=""
|
||||||
|
inputAlign="left"
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="100"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="desc">
|
||||||
|
<TTextareaField
|
||||||
|
label="基本情况"
|
||||||
|
placeholder=""
|
||||||
|
autoHeight
|
||||||
|
readonly
|
||||||
|
:required="false"
|
||||||
|
:labelWidth="100"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
<TFormItem prop="status">
|
||||||
|
<TMultiSelect
|
||||||
|
v-model="form.status"
|
||||||
|
label="状态"
|
||||||
|
:groupList="statusList"
|
||||||
|
:labelWidth="100"
|
||||||
|
/>
|
||||||
|
</TFormItem>
|
||||||
|
</TForm>
|
||||||
|
</view>
|
||||||
|
<view class="px-[60rpx]">
|
||||||
|
<u-button class="btn" color="#0E66FB" shape="circle" @click="handleSubmit">
|
||||||
|
提交
|
||||||
|
</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { shallowRef } from 'vue'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const id = ref('')
|
||||||
|
|
||||||
|
const tForm = ref()
|
||||||
|
const form = ref({
|
||||||
|
publishName: '',
|
||||||
|
clientName: '张三',
|
||||||
|
mobile: '',
|
||||||
|
desc: '',
|
||||||
|
status: ''
|
||||||
|
})
|
||||||
|
const rules = {
|
||||||
|
status: [{ required: true, message: '请选择状态' }]
|
||||||
|
}
|
||||||
|
const statusList = shallowRef([
|
||||||
|
{ label: '账号已添加', value: 1 },
|
||||||
|
{ label: '账号不存在', value: 2 },
|
||||||
|
{ label: '账号未通过', value: 3 }
|
||||||
|
])
|
||||||
|
onLoad(option => {
|
||||||
|
if (option?.id) {
|
||||||
|
id.value = option.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const handleSubmit = () => {
|
||||||
|
tForm.value
|
||||||
|
.validate()
|
||||||
|
.then(valid => {
|
||||||
|
if (valid) {
|
||||||
|
console.log('校验通过')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
:deep(.btn) {
|
||||||
|
button {
|
||||||
|
@apply h-[88rpx] mt-[48rpx] mb-[28rpx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -7,7 +7,9 @@
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<view class="design-field" :style="fieldStyle">
|
<view class="design-field" :style="fieldStyle">
|
||||||
<text class="field" :class="{ 'field-required': required }">{{ label }}</text>
|
<text class="field" :class="{ 'field-required': required }" :style="labelStyle">
|
||||||
|
{{ label }}
|
||||||
|
</text>
|
||||||
<u-input
|
<u-input
|
||||||
class="input"
|
class="input"
|
||||||
v-model="innerValue"
|
v-model="innerValue"
|
||||||
|
@ -24,7 +26,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
|
@ -61,10 +63,21 @@ const props = defineProps({
|
||||||
clearable: {
|
clearable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 120
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update:modelValue', 'change', 'blur'])
|
const emit = defineEmits(['update:modelValue', 'change', 'blur'])
|
||||||
const innerValue = ref('')
|
const innerValue = ref('')
|
||||||
|
const labelStyle = computed(() => {
|
||||||
|
const { labelWidth } = props
|
||||||
|
return {
|
||||||
|
width: `${labelWidth * 2}rpx`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const onInput = (value: string) => {
|
const onInput = (value: string) => {
|
||||||
emit('update:modelValue', value)
|
emit('update:modelValue', value)
|
||||||
emit('change', value)
|
emit('change', value)
|
||||||
|
@ -91,7 +104,7 @@ watch(
|
||||||
border-bottom: 1px solid $gray-3;
|
border-bottom: 1px solid $gray-3;
|
||||||
padding: 24rpx 32rpx 24rpx 32rpx;
|
padding: 24rpx 32rpx 24rpx 32rpx;
|
||||||
.field {
|
.field {
|
||||||
width: 240rpx;
|
// width: 240rpx;
|
||||||
}
|
}
|
||||||
.wrapper,
|
.wrapper,
|
||||||
.input {
|
.input {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="design-field">
|
<view class="design-field">
|
||||||
<text class="field">{{ label }}</text>
|
<text class="field" :style="labelStyle">{{ label }}</text>
|
||||||
<view class="wrapper" @click="onClick">
|
<view class="wrapper" @click="onClick">
|
||||||
<view class="input">
|
<view class="input">
|
||||||
<view class="content">
|
<view class="content">
|
||||||
|
@ -33,12 +33,23 @@ const props = defineProps({
|
||||||
address: {
|
address: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 120
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['onClick', 'update:modelValue'])
|
const emit = defineEmits(['onClick', 'update:modelValue'])
|
||||||
|
|
||||||
const innerValue = ref('')
|
const innerValue = ref('')
|
||||||
const isShow = computed(() => innerValue.value === '')
|
const isShow = computed(() => innerValue.value === '')
|
||||||
|
const labelStyle = computed(() => {
|
||||||
|
const { labelWidth } = props
|
||||||
|
return {
|
||||||
|
width: `${labelWidth * 2}rpx`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const onClick = () => {
|
const onClick = () => {
|
||||||
emit('onClick')
|
emit('onClick')
|
||||||
}
|
}
|
||||||
|
@ -57,7 +68,7 @@ watch(
|
||||||
border-bottom: 1px solid $gray-3;
|
border-bottom: 1px solid $gray-3;
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
width: 240rpx;
|
// width: 240rpx;
|
||||||
}
|
}
|
||||||
.wrapper {
|
.wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
<template>
|
||||||
|
<view class="design-field">
|
||||||
|
<text class="field" :class="{ 'field-required': required }" :style="labelStyle">
|
||||||
|
{{ label }}
|
||||||
|
</text>
|
||||||
|
<view class="flex gap-[10rpx] flex-1 flex-wrap">
|
||||||
|
<text
|
||||||
|
v-for="(group, index) in groupList"
|
||||||
|
:key="index"
|
||||||
|
class="px-[24rpx] py-[12rpx] rounded-[16rpx] status"
|
||||||
|
:class="{ active: innerValue == group.value }"
|
||||||
|
@click="handleSelectedItem(group.value)"
|
||||||
|
>
|
||||||
|
{{ group.label }}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { PropType, ref } from 'vue'
|
||||||
|
|
||||||
|
interface IGroup {
|
||||||
|
label: string
|
||||||
|
value: string | number
|
||||||
|
}
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 120
|
||||||
|
},
|
||||||
|
groupList: {
|
||||||
|
type: Array as PropType<IGroup[]>,
|
||||||
|
defaault: () => []
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
const labelStyle = computed(() => {
|
||||||
|
const { labelWidth } = props
|
||||||
|
return {
|
||||||
|
width: `${labelWidth * 2}` + 'rpx'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const innerValue = ref(props.modelValue)
|
||||||
|
const handleSelectedItem = (val: number) => {
|
||||||
|
emit('update:modelValue', val)
|
||||||
|
innerValue.value = val
|
||||||
|
console.log(val)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.design-field {
|
||||||
|
@include flex-align;
|
||||||
|
padding: 24rpx 20rpx 24rpx 32rpx;
|
||||||
|
border-bottom: 1px solid $gray-3;
|
||||||
|
|
||||||
|
.field {
|
||||||
|
// width: 200rpx;
|
||||||
|
}
|
||||||
|
.input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.status {
|
||||||
|
border: 1px solid #d5d5d5;
|
||||||
|
&.active {
|
||||||
|
background-color: #eef6ff;
|
||||||
|
color: #0e66fb;
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -7,7 +7,9 @@
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<view class="design-field">
|
<view class="design-field">
|
||||||
<text class="field" :class="required ? 'field-required' : ''">{{ label }}</text>
|
<text class="field" :class="required ? 'field-required' : ''" :style="labelStyle">
|
||||||
|
{{ label }}
|
||||||
|
</text>
|
||||||
<view @click="toggleShow" class="placeholder">
|
<view @click="toggleShow" class="placeholder">
|
||||||
<text :class="{ light: isSetValue }">
|
<text :class="{ light: isSetValue }">
|
||||||
{{ selectName || placeholder }}
|
{{ selectName || placeholder }}
|
||||||
|
@ -61,6 +63,10 @@ const props = defineProps({
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 120
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const picker = ref()
|
const picker = ref()
|
||||||
|
@ -69,6 +75,12 @@ const selectName = ref('')
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const defaultIndex = ref([0])
|
const defaultIndex = ref([0])
|
||||||
const isSetValue = computed(() => selectName.value.length === 0)
|
const isSetValue = computed(() => selectName.value.length === 0)
|
||||||
|
const labelStyle = computed(() => {
|
||||||
|
const { labelWidth } = props
|
||||||
|
return {
|
||||||
|
width: `${labelWidth * 2}rpx`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const toggleShow = () => {
|
const toggleShow = () => {
|
||||||
if (props.disabled) return
|
if (props.disabled) return
|
||||||
|
@ -100,7 +112,7 @@ defineExpose({
|
||||||
border-bottom: 1px solid $gray-3;
|
border-bottom: 1px solid $gray-3;
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
width: 240rpx;
|
// width: 240rpx;
|
||||||
}
|
}
|
||||||
.placeholder {
|
.placeholder {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="design-field">
|
<view class="design-field">
|
||||||
<text class="field">{{ label }}</text>
|
<text class="field" :style="labelStyle">{{ label }}</text>
|
||||||
<u-radio-group placement="row" v-model="innerValue">
|
<u-radio-group placement="row" v-model="innerValue">
|
||||||
<u-radio
|
<u-radio
|
||||||
v-for="(group, index) in groupList"
|
v-for="(group, index) in groupList"
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PropType, ref } from 'vue'
|
import { PropType, computed, ref } from 'vue'
|
||||||
|
|
||||||
interface IGroup {
|
interface IGroup {
|
||||||
label: string
|
label: string
|
||||||
|
@ -36,10 +36,21 @@ const props = defineProps({
|
||||||
groupList: {
|
groupList: {
|
||||||
type: Array as PropType<IGroup[]>,
|
type: Array as PropType<IGroup[]>,
|
||||||
defaault: () => []
|
defaault: () => []
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 120
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
const innerValue = ref(props.modelValue)
|
const innerValue = ref(props.modelValue)
|
||||||
|
const labelStyle = computed(() => {
|
||||||
|
const { labelWidth } = props
|
||||||
|
return {
|
||||||
|
width: `${labelWidth * 2}rpx`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const handleSelectChange = (name: string) => {
|
const handleSelectChange = (name: string) => {
|
||||||
emit('update:modelValue', name)
|
emit('update:modelValue', name)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +63,7 @@ const handleSelectChange = (name: string) => {
|
||||||
border-bottom: 1px solid $gray-3;
|
border-bottom: 1px solid $gray-3;
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
width: 240rpx;
|
// width: 240rpx;
|
||||||
}
|
}
|
||||||
.input {
|
.input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="design-search">
|
<view class="design-search" :style="borderStyle">
|
||||||
<view class="t-search" :class="inputClass" :style="wrapperStyle">
|
<view class="t-search" :class="inputClass" :style="wrapperStyle">
|
||||||
<i class="iconfont icon-search"></i>
|
<i class="iconfont icon-search"></i>
|
||||||
<input
|
<input
|
||||||
|
@ -52,12 +52,24 @@ const props = defineProps({
|
||||||
backgroundColor: {
|
backgroundColor: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'transparent'
|
default: 'transparent'
|
||||||
|
},
|
||||||
|
showBorder: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const innerValue = ref('')
|
const innerValue = ref('')
|
||||||
|
|
||||||
|
const borderStyle = computed(() => {
|
||||||
|
const style = {}
|
||||||
|
const { showBorder } = props
|
||||||
|
if (showBorder) {
|
||||||
|
style.borderBottom = '1px solid #f1f1f1'
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
})
|
||||||
const inputClass = computed(() => {
|
const inputClass = computed(() => {
|
||||||
let classes = []
|
let classes = []
|
||||||
const { shape, border } = props
|
const { shape, border } = props
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<view class="design-field">
|
<view class="design-field">
|
||||||
<text class="field" :class="required ? 'field-required' : ''">{{ label }}</text>
|
<text class="field" :class="required ? 'field-required' : ''" :style="labelStyle">
|
||||||
|
{{ label }}
|
||||||
|
</text>
|
||||||
<view class="wrapper" @click="onClick">
|
<view class="wrapper" @click="onClick">
|
||||||
<u-input
|
<u-input
|
||||||
class="input"
|
class="input"
|
||||||
|
@ -27,7 +29,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
label: {
|
label: {
|
||||||
|
@ -49,10 +51,21 @@ const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 120
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['onClick'])
|
const emit = defineEmits(['onClick'])
|
||||||
const innerValue = ref('')
|
const innerValue = ref('')
|
||||||
|
const labelStyle = computed(() => {
|
||||||
|
const { labelWidth } = props
|
||||||
|
return {
|
||||||
|
width: `${labelWidth * 2}rpx`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const onClick = () => {
|
const onClick = () => {
|
||||||
emit('onClick')
|
emit('onClick')
|
||||||
}
|
}
|
||||||
|
@ -71,7 +84,7 @@ watch(
|
||||||
border-bottom: 1px solid $gray-3;
|
border-bottom: 1px solid $gray-3;
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
width: 240rpx;
|
// width: 240rpx;
|
||||||
}
|
}
|
||||||
.wrapper,
|
.wrapper,
|
||||||
.input {
|
.input {
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
<!--
|
||||||
|
* @Author: micky
|
||||||
|
* @Date: 2024-08-10 15:24:06
|
||||||
|
* @LastEditors: micky
|
||||||
|
* @LastEditTime: 2024-10-28 18:00:13
|
||||||
|
* @FilePath: \chargingpile-uniapp\src\components\design-input-field.vue
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<view class="design-field" :style="fieldStyle">
|
||||||
|
<text class="field" :class="{ 'field-required': required }" :style="labelStyle">
|
||||||
|
{{ label }}
|
||||||
|
</text>
|
||||||
|
<u-switch
|
||||||
|
v-model="innerValue"
|
||||||
|
:activeValue="1"
|
||||||
|
:inactiveValue="0"
|
||||||
|
@change="handleSwitchChange"
|
||||||
|
></u-switch>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: '请输入'
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
fieldStyle: {
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 120
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
const innerValue = ref('')
|
||||||
|
const labelStyle = computed(() => {
|
||||||
|
const { labelWidth } = props
|
||||||
|
return {
|
||||||
|
width: `${labelWidth * 2}rpx`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleSwitchChange = (value: number) => {
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
val => {
|
||||||
|
innerValue.value = val
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.design-field {
|
||||||
|
@include flex-align;
|
||||||
|
border-bottom: 1px solid $gray-3;
|
||||||
|
padding: 24rpx 32rpx 24rpx 32rpx;
|
||||||
|
.field {
|
||||||
|
// width: 240rpx;
|
||||||
|
}
|
||||||
|
.wrapper,
|
||||||
|
.input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -7,7 +7,9 @@
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<view class="design-field">
|
<view class="design-field">
|
||||||
<text class="field" :class="{ 'field-required': required }">{{ label }}</text>
|
<text class="field" :class="{ 'field-required': required }" :style="labelStyle">
|
||||||
|
{{ label }}
|
||||||
|
</text>
|
||||||
<u-textarea
|
<u-textarea
|
||||||
class="textarea"
|
class="textarea"
|
||||||
v-model="innerValue"
|
v-model="innerValue"
|
||||||
|
@ -30,7 +32,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
|
@ -68,11 +70,22 @@ const props = defineProps({
|
||||||
autoHeight: {
|
autoHeight: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 120
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const innerValue = ref('')
|
const innerValue = ref('')
|
||||||
|
const labelStyle = computed(() => {
|
||||||
|
const { labelWidth } = props
|
||||||
|
return {
|
||||||
|
width: `${labelWidth * 2}rpx`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => innerValue.value,
|
() => innerValue.value,
|
||||||
(newVal: string) => {
|
(newVal: string) => {
|
||||||
|
@ -83,7 +96,8 @@ watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
val => {
|
val => {
|
||||||
innerValue.value = val
|
innerValue.value = val
|
||||||
}
|
},
|
||||||
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -93,7 +107,7 @@ watch(
|
||||||
border-bottom: 1px solid $gray-3;
|
border-bottom: 1px solid $gray-3;
|
||||||
padding: 24rpx 32rpx 24rpx 32rpx;
|
padding: 24rpx 32rpx 24rpx 32rpx;
|
||||||
.field {
|
.field {
|
||||||
width: 240rpx;
|
// width: 240rpx;
|
||||||
}
|
}
|
||||||
.wrapper,
|
.wrapper,
|
||||||
.textarea {
|
.textarea {
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
<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>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<view class="flex flex-col gap-[16rpx]">
|
||||||
|
<view class="flex gap-[8rpx] items-center">
|
||||||
|
<TIcon name="icon-warning" color="#F5222D" />
|
||||||
|
<text class="text-error">待电销老师重新跟进</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex gap-[20rpx]">
|
||||||
|
<text class="text-muted w-[128rpx]">基本情况</text>
|
||||||
|
<view class="flex gap-[4rpx] flex-1 items-end">
|
||||||
|
<text>
|
||||||
|
学生爸爸接电话,学生高三毕业,300多分,家长不清楚学生收到录取通知,家长说学生不读书了,我让家长先问问学生对未来的规划先和学生沟通一下,家长同意我们加他微信发专业资料给他看看,可以在微信上问问学生具体情况。推荐3+2,给家长发一下学校简介和专业资料。
|
||||||
|
</text>
|
||||||
|
<u-copy content="uview-plus is great !">
|
||||||
|
<TIcon name="icon-copy" color="#0E66FB" />
|
||||||
|
</u-copy>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex gap-[20rpx]">
|
||||||
|
<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-error">账号不存在</text>
|
||||||
|
</view>
|
||||||
|
<view class="flex gap-[20rpx]">
|
||||||
|
<text class="text-muted w-[128rpx]">备注</text>
|
||||||
|
<view class="flex gap-[12rpx]">
|
||||||
|
<text class="flex-1 text-error">已交一部分定位金</text>
|
||||||
|
<view class="flex gap-[4rpx] items-center text-primary text-[28rpx]">
|
||||||
|
<TIcon name="icon-edit" color="#0E66FB" />
|
||||||
|
<text>修改</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex gap-[20rpx]">
|
||||||
|
<text class="text-muted w-[128rpx]">成交时间</text>
|
||||||
|
<text class="flex-1">2025-02-10 16:04:00</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template #action>
|
||||||
|
<view class="flex justify-end gap-[16rpx]">
|
||||||
|
<u-button color="#0E66FB" shape="circle" @click="handleGet">领取</u-button>
|
||||||
|
<u-button color="#0E66FB" shape="circle" @click="handleAddProgress">
|
||||||
|
添加进展
|
||||||
|
</u-button>
|
||||||
|
<u-button color="#0E66FB" shape="circle" @click="handleComplete">转化完成</u-button>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</w-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { toast } from '@/utils/util'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
item: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 领取
|
||||||
|
const handleGet = () => {
|
||||||
|
const { item } = props
|
||||||
|
toast('领取成功')
|
||||||
|
}
|
||||||
|
// 添加进展
|
||||||
|
const handleAddProgress = () => {
|
||||||
|
const { item } = props
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/bundle/pages/progress_add/index?id=' + item.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 转化完成
|
||||||
|
const handleComplete = () => {
|
||||||
|
const { item } = props
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/bundle/pages/complete_add/index?id=' + item.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
|
@ -29,6 +29,8 @@ import TProfile from './components/design-profile.vue'
|
||||||
import TTable from './components/design-table.vue'
|
import TTable from './components/design-table.vue'
|
||||||
import TDateTimePicker from './components/datetime-picker.vue'
|
import TDateTimePicker from './components/datetime-picker.vue'
|
||||||
import TFeedBack from './components/design-feedback.vue'
|
import TFeedBack from './components/design-feedback.vue'
|
||||||
|
import TMultiSelect from './components/design-multiselect-field.vue'
|
||||||
|
import TSwitchField from './components/design-switch-field.vue'
|
||||||
export function createApp() {
|
export function createApp() {
|
||||||
const app = createSSRApp(App)
|
const app = createSSRApp(App)
|
||||||
|
|
||||||
|
@ -56,6 +58,8 @@ export function createApp() {
|
||||||
app.component('TTable', TTable)
|
app.component('TTable', TTable)
|
||||||
app.component('TDateTimePicker', TDateTimePicker)
|
app.component('TDateTimePicker', TDateTimePicker)
|
||||||
app.component('TFeedBack', TFeedBack)
|
app.component('TFeedBack', TFeedBack)
|
||||||
|
app.component('TMultiSelect', TMultiSelect)
|
||||||
|
app.component('TSwitchField', TSwitchField)
|
||||||
return {
|
return {
|
||||||
app
|
app
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
{
|
{
|
||||||
"pages": [
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "pages/recruitsale/home/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/telesale/home/index",
|
"path": "pages/telesale/home/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
@ -102,6 +108,18 @@
|
||||||
{
|
{
|
||||||
"root": "bundle",
|
"root": "bundle",
|
||||||
"pages": [
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "pages/complete_add/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "转化完成"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/progress_add/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "添加进展"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/follow_edit/index",
|
"path": "pages/follow_edit/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
<template>
|
||||||
|
<view class="flex-1 h-screen flex flex-col">
|
||||||
|
<TSearch
|
||||||
|
v-model="queryParams.searchValue"
|
||||||
|
placeholder="搜索客户姓名/手机号码"
|
||||||
|
backgroundColor="#F5F5F5"
|
||||||
|
showBorder
|
||||||
|
/>
|
||||||
|
<u-tabs
|
||||||
|
:list="tabs"
|
||||||
|
:scrollable="false"
|
||||||
|
:itemStyle="{ height: '44px', flex: 1 }"
|
||||||
|
:activeStyle="{ color: '#0E66FB' }"
|
||||||
|
lineWidth="49"
|
||||||
|
lineColor="#0E66FB"
|
||||||
|
:current="activeTab"
|
||||||
|
@change="handleChangeTab"
|
||||||
|
></u-tabs>
|
||||||
|
<view class="flex-1 pt-[24rpx] px-[24rpx] overflow-auto bg-[#F8F8F8]">
|
||||||
|
<!-- <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 '@/components/widgets/recruitsale/clue-card.vue'
|
||||||
|
import { shallowRef } from 'vue'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const tabs = shallowRef([
|
||||||
|
{ name: '待领取', value: 0 },
|
||||||
|
{ name: '转化中', value: 1 },
|
||||||
|
{ name: '已成交', value: 2 },
|
||||||
|
{ name: '已战败', value: 3 }
|
||||||
|
])
|
||||||
|
const activeTab = ref(0)
|
||||||
|
const queryParams = computed(() => {
|
||||||
|
const payload = {
|
||||||
|
status: activeTab.value,
|
||||||
|
searchValue: ''
|
||||||
|
}
|
||||||
|
return payload
|
||||||
|
})
|
||||||
|
const dataList = ref([
|
||||||
|
{
|
||||||
|
id: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3
|
||||||
|
}
|
||||||
|
])
|
||||||
|
const { paging, queryList, refresh, changeApi, setParams } = useZPaging(
|
||||||
|
queryParams.value,
|
||||||
|
apiOverhaulPagelist,
|
||||||
|
() => {}
|
||||||
|
)
|
||||||
|
const handleChangeTab = item => {
|
||||||
|
activeTab.value = item.value
|
||||||
|
// refresh(queryParams.value)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
|
@ -1,8 +1,8 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'iconfont'; /* Project id 4837700 */
|
font-family: 'iconfont'; /* Project id 4837700 */
|
||||||
src: url('//at.alicdn.com/t/c/font_4837700_qu0wamoi86a.woff2?t=1740458346519') format('woff2'),
|
src: url('//at.alicdn.com/t/c/font_4837700_qvo1iou9n4.woff2?t=1740471403087') format('woff2'),
|
||||||
url('//at.alicdn.com/t/c/font_4837700_qu0wamoi86a.woff?t=1740458346519') format('woff'),
|
url('//at.alicdn.com/t/c/font_4837700_qvo1iou9n4.woff?t=1740471403087') format('woff'),
|
||||||
url('//at.alicdn.com/t/c/font_4837700_qu0wamoi86a.ttf?t=1740458346519') format('truetype');
|
url('//at.alicdn.com/t/c/font_4837700_qvo1iou9n4.ttf?t=1740471403087') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
|
@ -13,6 +13,14 @@
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-edit:before {
|
||||||
|
content: '\e636';
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-warning:before {
|
||||||
|
content: '\e676';
|
||||||
|
}
|
||||||
|
|
||||||
.icon-copy:before {
|
.icon-copy:before {
|
||||||
content: '\eb4e';
|
content: '\eb4e';
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,8 @@ module.exports = {
|
||||||
gray3: '#F8F8F8',
|
gray3: '#F8F8F8',
|
||||||
lightblack: '#3D3D3D',
|
lightblack: '#3D3D3D',
|
||||||
border: '#F1F1F1',
|
border: '#F1F1F1',
|
||||||
border2: '#F3F3F3'
|
border2: '#F3F3F3',
|
||||||
|
blue2: '#EEF6FF'
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
xs: '24rpx',
|
xs: '24rpx',
|
||||||
|
|
Loading…
Reference in New Issue