javascript
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="1006px" class="dialogs">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<div style="padding: 8px 0; background: #f8fbff; margin-top: 10px">
<el-row :gutter="24">
<el-form-item label="学员姓名" prop="stsStudentName" class="student">
<el-input v-model="formData.stsStudentName" placeholder="请输入学员姓名" />
</el-form-item>
<el-form-item label="手机号" class="phone" prop="stsPhoneRealation">
<el-input
v-model="formData.stsPhone"
placeholder="请输入手机号"
class="input-with-select"
>
<template #prepend>
<el-select
v-model="formData.stsPhoneRealation"
placeholder="家长"
style="width: 110px"
>
<el-option
v-for="item in getStrDictOptions(DICT_TYPE.RELATIONSHIP)"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-input>
</el-form-item>
<el-form-item label="当前年级" prop="stsSenior">
<el-select v-model="formData.stsSenior" placeholder="请选择当前年级">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.GRADE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="年龄" prop="stsAge">
<el-input-number v-model="formData.stsAge" :step="2" />
</el-form-item>
<el-form-item label="性别" prop="stsSex">
<el-select v-model="formData.stsSex" placeholder="请选择性别">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="出生日期" prop="stsBirthDate">
<el-date-picker
v-model="formData.stsBirthDate"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择日期"
/>
</el-form-item>
<el-form-item label="备用手机号" class="stsAlterPhone" >
<el-input
v-model="formData.stsAlterPhone"
placeholder="请输入手机号"
class="input-with-select"
>
<template #prepend>
<el-select
v-model="formData.stsAlterRealation"
placeholder="家长"
style="width: 110px"
>
<el-option
v-for="item in getStrDictOptions(DICT_TYPE.RELATIONSHIP)"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-input>
</el-form-item>
</el-row>
<el-row :gutter="24">
<el-form-item label="就读学校" prop="stsReadSchool">
<el-input v-model="formData.stsReadSchool" placeholder="请输入就读学校" />
</el-form-item>
</el-row>
<el-row :gutter="24">
<el-form-item label="家庭住址" prop="stsHome" >
<el-input v-model="formData.stsHome" placeholder="请输入家庭住址" />
</el-form-item>
</el-row>
</div>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
<el-button @click="dialogVisible = false">取 消</el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { VisitManageApi, VisitManageVO,UserVO } from '@/api/sale/visitmanage'
import { useUserStore } from '@/store/modules/user'
import { InfoApi, InfoVO } from '@/api/study/info'
import * as UserApi from '@/api/system/user'
import { TotalStudentApi, TotalStudentVO } from '@/api/study/totalstudent'
const userStore = useUserStore()
/** 到访管理 表单 */
defineOptions({ name: 'VisitManageForm' })
const userList = ref<UserApi.UserVO[]>([]) // 用户列表
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const formRules = reactive({
stsStudentName: [{ required: true, message: '学员姓名不能为空', trigger: 'blur' }],
stsPhoneRealation: [{ required: true, message: '关系不能为空', trigger: 'blur' }],
stsPhone: [{ required: true, message: '手机号不能为空', trigger: 'blur' }],
studentSource: [{ required: true, message: '学员来源不能为空', trigger: 'blur' }],
intentionLevel: [{ required: true, message: '意向级别不能为空', trigger: 'blur' }],
stsSenior: [{ required: true, message: '当前年级不能为空', trigger: 'blur' }],
followUpType: [{ required: true, message: '跟进方式不能为空', trigger: 'blur' }]
})
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const formType = ref('') // 表单的类型:create - 新增;update - 修改
const formData = ref({
id: undefined, // 主键id
stsStudentName: undefined ,// 学员姓名
stsAge: undefined, // 年龄
stsSex: undefined, // 性别
stsPhone: undefined ,// 手机号
stsPhoneRealation: undefined , // 手机号关系
stsBirthDate: undefined , // 出生日期
stsSenior: undefined , // 当前年级
stsSchool: undefined , // 就读学校
stsAlterPhone: undefined , // 备用号码
stsAlterRealation: undefined , // 备用号码关系
stsHome: undefined , // 家庭地址
stsWeixinStatus: undefined , // 绑定微信状态
stsWeixinNumber: undefined , // 微信号
stsReadClass: undefined , // 报读所在班级
stsReadPhone: undefined , // 报读手机号
stsReadSorce: undefined , // 报读课程
stsDueDate: undefined , // 到期日期
stsTeacher: undefined ,// 学管师
stsPaySornumer: undefined , // 购买课程数量
stsGiftSornum: undefined , // 赠送数量
stsReturnNum: undefined , // 退转数量
stsAttendClass: undefined , // 已上课数量
stsSurplusNum: undefined , // 剩余数量
stsAbsenceNum: undefined , // 缺课数量
stsCanceldecimal: undefined , // 消课金额
stsCorseRemain: undefined , // 剩余报课金额
stsFollowPeople: undefined , // 跟进人
stsFollowDate: undefined , // 跟进日期
stsFollowText: undefined , // 跟进内容
stsMethod: undefined , // 跟进方式
stsFollowPhase: undefined , // 跟进阶段
stsFollowNextdate: undefined , // 下次跟进日期
stsRollTime: undefined , // 点名时间
stsReadSchool: undefined , // 就读校区
stsStartClass: undefined , // 上课开始日期
stsEndDate: undefined , // 上课结束日期
stsClassTeacher: undefined , // 任课教师
stsClassStatus: undefined , // 到课状态
stsMakeState: undefined , // 补课状态
})
const formRef = ref() // 表单 Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
userList.value = await UserApi.getSimpleUserList()
// 修改时,设置数据
if (id) {
formLoading.value = true
try {
formData.value = await VisitManageApi.getVisitManage(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
await formRef.value.validate()
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as TotalStudentVO
const studentId = await TotalStudentApi.createTotalStudent(data)
message.success(t('common.createSuccess'))
// 发送操作成功的事件
emit('success',studentId)
dialogVisible.value = false
console.log('studentId',studentId)
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined, // 主键id
stsStudentName: undefined ,// 学员姓名
stsAge: undefined, // 年龄
stsSex: undefined, // 性别
stsPhone: undefined ,// 手机号
stsPhoneRealation: undefined , // 手机号关系
stsBirthDate: undefined , // 出生日期
stsSenior: undefined , // 当前年级
stsSchool: undefined , // 就读学校
stsAlterPhone: undefined , // 备用号码
stsAlterRealation: undefined , // 备用号码关系
stsHome: undefined , // 家庭地址
stsWeixinStatus: undefined , // 绑定微信状态
stsWeixinNumber: undefined , // 微信号
stsReadClass: undefined , // 报读所在班级
stsReadPhone: undefined , // 报读手机号
stsReadSorce: undefined , // 报读课程
stsDueDate: undefined , // 到期日期
stsTeacher: undefined ,// 学管师
stsPaySornumer: undefined , // 购买课程数量
stsGiftSornum: undefined , // 赠送数量
stsReturnNum: undefined , // 退转数量
stsAttendClass: undefined , // 已上课数量
stsSurplusNum: undefined , // 剩余数量
stsAbsenceNum: undefined , // 缺课数量
stsCanceldecimal: undefined , // 消课金额
stsCorseRemain: undefined , // 剩余报课金额
stsFollowPeople: undefined , // 跟进人
stsFollowDate: undefined , // 跟进日期
stsFollowText: undefined , // 跟进内容
stsMethod: undefined , // 跟进方式
stsFollowPhase: undefined , // 跟进阶段
stsFollowNextdate: undefined , // 下次跟进日期
stsRollTime: undefined , // 点名时间
stsReadSchool: undefined , // 就读校区
stsStartClass: undefined , // 上课开始日期
stsEndDate: undefined , // 上课结束日期
stsClassTeacher: undefined , // 任课教师
stsClassStatus: undefined , // 到课状态
stsMakeState: undefined , // 补课状态
}
formRef.value?.resetFields()
}
</script>
<style scoped>
:deep(.input-textarea) {
width: 950px !important;
}
.el-form-item {
width: 47%;
}
:deep(.el-form-item__label) {
width: 130px !important;
}
.bold {
width: 20px;
height: 20px;
border-radius: 50%;
background: #85afd5;
text-align: center;
margin-top: 5px;
margin-left: -10px;
color: #fff;
}
.btitle {
line-height: 30px;
margin-left: 10px;
color: #84b0d5;
}
.tip {
border: 1px solid #84b0d5;
border-radius: 0 20px 20px 0;
width: 140px;
height: 30px;
display: flex;
margin-left: 30px;
margin-bottom: 20px;
}
:deep(.el-input) {
width: 100%;
}
:deep(.el-select) {
width: 100%;
}
:deep(.el-select) {
--el-select-width: 80%;
}
</style>
const emit = defineEmits(['success']) // 定义 success 事件,你也可以定义成别的名字,这里我定义为success;用于操作成功后的回调
emit('success',studentId),需要把你定义的事件名发射给父组件,还有你需要传的值,这里我需要传studentId;
javascript
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="1006px" class="dialogs">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<div style="padding: 8px 0; background: #f8fbff; margin-top: 10px">
<div class="tip">
<div class="bold">1</div>
<span class="btitle">基本信息</span>
</div>
<el-row :gutter="24">
<el-col :span="18">
<el-form-item label="学员姓名" prop="studentId" class="sname">
<el-select
v-model="formData.studentId"
filterable
remote
reserve-keyword
placeholder="请输入学员姓名或手机号"
:remote-method="remoteMethod"
:loading="stuAllLoading"
@change="findStudentSource"
>
<el-option
v-for="item in studentList"
:key="item.id"
:label="item.stsStudentName"
:value="item.id"
>
<span style="float: left">{{ item.stsStudentName }}</span>
<span style="float: left; margin-left: 5px"
><el-tag size="small">{{
getDictLabel(DICT_TYPE.STUDENT_STATUS, item.studentStatus)
}}</el-tag></span
>
<span style="float: right; color: #8492a6; font-size: 13px">{{
item.stsPhone
}}</span>
</el-option>
</el-select>
<span
style="
margin-left: 10px;
float: left;
color: #8492a6;
font-size: 13px;
display: flex;
width: 500px;
"
>学员未找到?去<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['sale:visit-manage:create']"
link
>
新增学员
</el-button>
</span>
</el-form-item>
</el-col>
</el-row>
</div>
<div style="padding: 8px 0; background: #f8fbff; margin-top: 10px">
<div class="tip">
<div class="bold">2</div>
<span class="btitle">到访记录</span>
</div>
<el-row :gutter="24">
<el-form-item label="渠道" prop="studentSource">
<el-select v-model="formData.studentSource" placeholder="请选择渠道">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.SOURCE_STUDENT)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="到访时间" prop="visitTime">
<el-date-picker
v-model="formData.visitTime"
type="datetime"
format="YYYY/MM/DD hh:mm"
value-format="x"
placeholder="选择到访时间"
/>
</el-form-item>
<!-- <el-form-item label="接待人员" prop="receptionPerson">
<el-select v-model="formData.receptionPerson" placeholder="请选择跟进人">
<el-option
v-for="dict in userList"
:key="dict.id"
:label="dict.nickname"
:value="dict.id"
/>
</el-select>
</el-form-item> -->
<el-form-item label="是否试听" prop="listenStatus">
<el-select v-model="formData.listenStatus" placeholder="请选择是否试听">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.AUDITION_OR_NOT)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="是否签约" prop="signUpStatus">
<el-select v-model="formData.signUpStatus" placeholder="请选择是否签约">
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.SIGN_OR_NOT)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-row>
<el-row :gutter="24">
<el-form-item label="备注" prop="remark" class="input-textarea">
<el-input
v-model="formData.remark"
:rows="3"
type="textarea"
placeholder="请输入备注"
/>
</el-form-item>
</el-row>
</div>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
<el-button @click="dialogVisible = false">取 消</el-button>
</template>
</Dialog>
<!-- 表单弹窗:添加/修改 -->
<VisitManageForm2 @success="handleSuccess" ref="formRef2" />
</template>
<script setup lang="ts">
import { getStrDictOptions, DICT_TYPE, getDictLabel } from '@/utils/dict'
import { VisitManageApi, VisitManageVO } from '@/api/sale/visitmanage'
import { useUserStore } from '@/store/modules/user'
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
import * as UserApi from '@/api/system/user'
import VisitManageForm2 from './VisitManageForm2.vue'
import { TotalStudentApi, TotalStudentVO } from '@/api/study/totalstudent'
const studentList = ref<TotalStudentVO[]>([]) // 学生列表
const userStore = useUserStore()
/** 到访管理 表单 */
defineOptions({ name: 'VisitManageForm' })
const stuAllLoading = ref(false) // 输入学员关键词加载
const userList = ref<UserApi.UserVO[]>([]) // 用户列表
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const formRules = reactive({
studentId: [{ required: true, message: '学员姓名不能为空', trigger: 'blur' }],
studentSource: [{ required: true, message: '渠道不能为空', trigger: 'blur' }],
})
const handleSuccess = async (e: any) => {
formData.value.studentId = e
const dataStudent = await TotalStudentApi.getTotalStudent(e)
studentList.value = [dataStudent]
}
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const formType = ref('') // 表单的类型:create - 新增;update - 修改
const formData = ref({
id: undefined,
visitTime: undefined,
receptionPerson: userStore.user.id,
intentionLevel: undefined,
listenStatus: undefined,
signUpStatus: undefined,
visitTimeBegin: undefined,
visitTimeEnd: undefined,
remark: undefined,
studentId: undefined,
studentSource: undefined
})
const formRef = ref() // 表单 Ref
const formRef2 = ref()
/** 添加/修改操作 */
const openForm = (type: string, id?: number) => {
formRef2.value.open(type, id)
}
const findStudentSource = async (event) => {
const data = await VisitManageApi.getVisitManageByStudentId(event)
formData.value.studentSource = String(data)
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
remoteMethod('')
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
userList.value = await UserApi.getSimpleUserList()
// 修改时,设置数据
if (id) {
formLoading.value = true
try {
formData.value = await VisitManageApi.getVisitManage(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
await formRef.value.validate()
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as VisitManageVO
if (formType.value === 'create') {
await VisitManageApi.createVisitManage(data)
message.success(t('common.createSuccess'))
} else {
await VisitManageApi.updateVisitManage(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
// 发送操作成功的事件
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
visitTime: undefined,
receptionPerson: userStore.user.id,
intentionLevel: undefined,
listenStatus: undefined,
signUpStatus: undefined,
visitTimeBegin: undefined,
visitTimeEnd: undefined,
remark: undefined,
studentId: undefined,
studentSource: undefined
}
formRef.value?.resetFields()
}
const remoteMethod = async (query) => {
stuAllLoading.value = true
studentList.value = []
stuAllLoading.value = false
studentList.value = await TotalStudentApi.getSimpleUserList(query)
}
</script>
<style scoped>
:deep(.input-textarea) {
width: 950px !important;
}
.el-form-item {
width: 47%;
}
:deep(.el-form-item__label) {
width: 130px !important;
}
.bold {
width: 20px;
height: 20px;
border-radius: 50%;
background: #85afd5;
text-align: center;
margin-top: 5px;
margin-left: -10px;
color: #fff;
}
.btitle {
line-height: 30px;
margin-left: 10px;
color: #84b0d5;
}
.tip {
border: 1px solid #84b0d5;
border-radius: 0 20px 20px 0;
width: 140px;
height: 30px;
display: flex;
margin-left: 30px;
margin-bottom: 20px;
}
:deep(.el-input) {
width: 100%;
}
:deep(.el-select) {
width: 100%;
}
:deep(.el-select) {
--el-select-width: 80%;
}
:deep(.sname) {
width: 100% !important;
}
:deep(.sname .el-form-item__content) {
flex-wrap: nowrap;
}
</style>
<!-- 表单弹窗:添加/修改 -->
在这里接受子组件传来的值
<VisitManageForm2 @success="handleSuccess" ref="formRef2" />
这里接受到子组件传来的值可以做数据处理:
const handleSuccess = async (e: any) => {
formData.value.studentId = e
const dataStudent = await TotalStudentApi.getTotalStudent(e)
studentList.value = [dataStudent]
}