123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567 |
- import { defineComponent, nextTick, onMounted, onUnmounted, reactive, ref } from 'vue'
- import styles from './index.module.less'
- import headTitle from './images/header-title.png'
- import headPhone from './images/header-phone.png'
- import headBg from './images/header-bg.png'
- import iconHead from './images/icon-head.png'
- import iconBao from './images/icon-bao.png'
- import iconFree from './images/icon-free.png'
- import icon12 from './images/icon-12.png'
- import iconCheckbox from './images/icon-checkbox-ring.png'
- import iconCheckboxActive from './images/icon-checkbox-active.png'
- import {
- Button,
- Cell,
- CellGroup,
- Field,
- Form,
- Radio,
- RadioGroup,
- Tag,
- showToast,
- Image,
- Checkbox
- } from 'vant'
- import { useRoute, useRouter } from 'vue-router'
- import { moneyFormat } from '@/helpers/utils'
- import request from '@/helpers/request'
- // 乐团交付,乐团停止或关闭,有新的交付团;则不允许报名
- const classList: any = []
- for (let i = 1; i <= 40; i++) {
- classList.push({ text: i + '班', value: i })
- }
- export default defineComponent({
- name: 'pre-goods-apply',
- setup() {
- const route = useRoute()
- // 获取是否已经看过训练工具图片
- const state = reactive({
- code: '' as any, // 微信授权code码
- detail: {} as any, // 学员详情
- toolImgStatus: false,
- currentGrade: [
- { text: '一年级', value: 1 },
- { text: '二年级', value: 2 },
- { text: '三年级', value: 3 },
- { text: '四年级', value: 4 },
- { text: '五年级', value: 5 },
- { text: '六年级', value: 6 },
- { text: '七年级', value: 7 },
- { text: '八年级', value: 8 },
- { text: '九年级', value: 9 }
- ], // 年级数组列表
- classList: classList,
- subjectList: [] as any, // 选报声部列表
- instrumentsInspectionDescribe: '', // 配置信息
- inspectPopupStatus: false, // 查看说明
- gradeStatus: false,
- classStatus: false,
- subjectStatus: false,
- registerInfo: {} as any, // 乐团信息
- goodsInfo: {} as any, // 商品
- textBookInfo: {} as any, // 教材
- inspectInfo: {} as any, // 乐器检查
- vipYearInfo: {} as any, // 学练工具
- inspectStatus: true,
- // 是否开启微信登录(测试使用)默认为false
- testIsWeixin: false,
- details: [] as any, //
- pattern: /^1(3|4|5|6|7|8|9)\d{9}$/,
- nameReg: /^[\u4E00-\u9FA5]+$/,
- paymentType: '',
- musicPaymentType: '', // 乐团中对应支付方式
- studentReadStatus: false, // 学生在读
- dialogStatus: false,
- dialogMessage: '',
- dialogOrchestraStatus: false, // 是否为不同的乐团
- dialogConfig: {} as any,
- orderInfo: {
- needPrice: 0,
- originalPrice: 0
- },
- submitStatus: false
- })
- const forms = reactive({
- username: null,
- sex: null as any,
- currentGrade: null,
- currentGradeTxt: null, // 年级编号
- currentClass: '', // 班级
- currentClassTxt: null, // 年级编号
- registerSubjectId: '',
- registerSubjectTxt: null, // 所在选报声部
- parentName: null,
- groupBuyType: '' as any,
- phone: null as any,
- learningTools: null,
- instrumentsBrand: null
- })
- const otherParams = reactive({
- toolPlan: {
- title: '', // 训练工具准备
- groupTitle: '', // 团购标题
- groupDesc: '', // 团购文案
- selfTitle: '', // 自备标题
- selfDesc: '' // 自备文案
- },
- leBao: {
- // 乐器保障
- show: 1, // 是否显示
- selected: 1 // 是否选择
- }
- })
- const validator = (val: any) => {
- // 校验函数返回 true 表示校验通过,false 表示不通过
- return state.nameReg.test(val) && val.length >= 2 && val.length <= 15
- }
- const message = (value: any) => {
- if (!value) {
- return '请填写学员真实姓名'
- } else if (!state.nameReg.test(value)) {
- return '学员姓名必须为中文'
- } else if (value.length < 2 || value.length > 15) {
- return '学员姓名必须为2~15个字'
- } else {
- return ''
- }
- }
- // 乐团报名
- const onSubmit = async () => {
- //
- }
- const messageContent = ref('')
- const orchestraName = ref(route.query.orchestraName || '') // 乐团名称
- const getMessage = (ev: any) => {
- if (ev.data.api === 'payment-notes') {
- const result = ev.data.data ? JSON.parse(ev.data.data) : {}
- console.log(result, 'result')
- messageContent.value = result.notice
- otherParams.toolPlan = result.toolPlan
- otherParams.leBao = result.leBao
- // document.body
- }
- }
- // 获取入选声部信息
- const getSubjects = async () => {
- try {
- const subjects = await request.post(
- '/api-student/open/orchestraSubjectConfig/pageByOrchestraId',
- {
- data: {
- orchestraId: route.query.id,
- page: 1,
- rows: 100
- }
- }
- )
- const rows = subjects.data.rows || []
- rows.forEach((item: any) => {
- state.subjectList.push({
- text: item.name,
- value: item.subjectId
- })
- })
- if (rows.length > 0) {
- forms.registerSubjectId = rows[0].subjectId // detail.registerSubjectId
- forms.registerSubjectTxt = rows[0].name
- registerGoods()
- }
- } catch {
- //
- }
- }
- // 获取商品信息
- const registerGoods = async () => {
- try {
- const { data } = await request.get(
- '/api-student/orchestraRegister/registerGoods/' + route.query.id,
- {
- params: {
- subjectId: forms.registerSubjectId
- }
- }
- )
- state.musicPaymentType = data.paymentServiceProvider || ''
- // 初始化数据商品数据
- const details = data.details || []
- details.forEach((item: any) => {
- if (item.goodsType === 'INSTRUMENTS') {
- const img = item.goodsUrl ? item.goodsUrl.split(',')[0] : ''
- state.goodsInfo = { ...item, goodsUrl: img }
- state.instrumentsInspectionDescribe = item.instrumentsInspectionDescribe
- } else if (item.goodsType === 'TEXTBOOK') {
- const img = item.goodsUrl ? item.goodsUrl.split(',')[0] : ''
- state.textBookInfo = { ...item, goodsUrl: img }
- } else if (item.goodsType === 'INSTRUMENT_INSPECT') {
- state.inspectInfo = { ...item }
- } else if (item.goodsType === 'VIP_YEAR') {
- state.vipYearInfo = { ...item }
- }
- state.details = details
- })
- } catch {
- //
- }
- }
- onMounted(async () => {
- await getSubjects()
- nextTick(() => {
- // 是否加载完成
- window.parent &&
- window.parent.postMessage(
- {
- api: 'onLoad',
- status: true
- },
- '*'
- )
- })
- window.addEventListener('message', getMessage)
- })
- onUnmounted(() => {
- window.removeEventListener('message', getMessage)
- })
- return () => (
- <div class={styles.goodsApply}>
- <img src={headBg} class={styles.headBg} />
- <div class={styles.goodsHeader}>
- <div class={styles.orchestraTitle}>
- <img class={styles.headTitle} src={headTitle} />
- <p class={[styles.name, 'van-multi-ellipsis--l3']}>{orchestraName.value}</p>
- </div>
- <img src={headPhone} class={styles.headPhone} />
- </div>
- <Form
- validateFirst
- errorMessageAlign="right"
- scrollToError={true}
- onSubmit={onSubmit}
- onFailed={(e: any) => {
- // 获取第一个校验错误的元素
- nextTick(() => {
- const isError = document.getElementsByClassName('van-field__error-message')
- // 滚动到错误元素对应位置
- isError[0]?.scrollIntoView({
- block: 'center',
- behavior: 'smooth'
- })
- })
- }}
- ref="form"
- class={styles.form}
- >
- <CellGroup class={styles.applyCellGroup} border={false}>
- <div class={[styles.title, styles.titleApply]}></div>
- <Field
- required
- label="学员信息"
- placeholder="请填写学员真实姓名"
- inputAlign="right"
- v-model={forms.username}
- maxlength={15}
- rules={[{ validator, message }]}
- />
- <Field
- required
- label="性别"
- inputAlign="right"
- rules={[{ required: true, message: '请选择性别' }]}
- >
- {{
- input: () => (
- <RadioGroup v-model={forms.sex}>
- <Tag
- size="large"
- type="primary"
- class={[styles.radioSection, forms.sex === 1 ? styles.active : '']}
- >
- <Radio class={styles.radioItem} name={1}></Radio>
- 男生
- </Tag>
- <Tag
- size="large"
- type="primary"
- class={[styles.radioSection, forms.sex === 0 ? styles.active : '']}
- >
- <Radio class={styles.radioItem} name={0}></Radio>女生
- </Tag>
- </RadioGroup>
- )
- }}
- </Field>
- <Field
- required
- label="年级"
- inputAlign="right"
- readonly
- isLink
- clickable={false}
- placeholder="请选择年级"
- v-model={forms.currentGradeTxt}
- onClick={() => (state.gradeStatus = true)}
- rules={[{ required: true, message: '请选择年级' }]}
- />
- <Field
- required
- label="班级"
- inputAlign="right"
- readonly
- isLink
- clickable={false}
- placeholder="请选择班级"
- v-model={forms.currentClassTxt}
- onClick={() => (state.classStatus = true)}
- rules={[{ required: true, message: '请选择班级' }]}
- />
- <Field
- required
- label="选报声部"
- inputAlign="right"
- readonly
- isLink
- clickable={false}
- placeholder="请选择选报声部"
- v-model={forms.registerSubjectTxt}
- onClick={() => {
- if (state.subjectList.length <= 0) {
- showToast('暂无报名选报声部')
- return
- }
- state.subjectStatus = true
- }}
- rules={[{ required: true, message: '请选择选报声部' }]}
- />
- </CellGroup>
- <CellGroup class={styles.applyCellGroup} border={false}>
- <div class={[styles.title, styles.titleParent]}></div>
- <Field
- required
- label="家长姓名"
- inputAlign="right"
- placeholder="请填写家长真实姓名"
- v-model={forms.parentName}
- maxlength={15}
- // rules={[{ required: true, message: '请填写家长真实姓名' }]}
- />
- <Field
- required
- label="手机号"
- inputAlign="right"
- placeholder="请输入手机号"
- v-model={forms.phone}
- maxlength={11}
- type="tel"
- // rules={[{ pattern: state.pattern, message: '输入监护人手机号码有误' }]}
- />
- </CellGroup>
- <CellGroup class={styles.applyCellGroup} border={false}>
- <div class={[styles.title, styles.titleTips]}></div>
- <div class={styles.tipsContainer} v-html={messageContent.value}>
- {/* <p class={styles.line}>
- <i class={[styles.num, styles.numOne]}></i>
- 为保障乐团训练质量,开训前,家长务必准备好①乐器和②管乐AI学练工具,准备方式不限;
- </p>
- <p class={styles.line}>
- <i class={[styles.num, styles.numTwo]}></i>
- 为了降低家长投入压力,可参与项目支持方提供的AI学练工具团购,政策如下:
- <p class={[styles.child]}>
- 1、支持方<span style="color: #F67146">免费</span>
- 提供一支全新乐器供学生训练(可带回家) ;<br />
- 2、乐器提供时间为一年,如期满继续训练,乐器将
- <span style="color: #F67146">赠送</span>至学生以作鼓励;
- <br />
- 3、如期间或期满不再训练,家长归还乐器即可,
- <span style="color: #F67146">无需额外支付</span>乐器费用。
- </p>
- </p> */}
- </div>
- </CellGroup>
- <CellGroup class={styles.applyCellGroup} border={false}>
- <div class={[styles.title, styles.titleTool]}></div>
- <Field
- required
- label={otherParams.toolPlan.title}
- labelAlign="top"
- rules={[{ required: true, message: '请选择训练工具的准备方式' }]}
- >
- {{
- input: () => (
- <RadioGroup v-model={forms.groupBuyType} class={styles.toolRadioGroup}>
- <Tag
- size="large"
- type="primary"
- class={[
- styles.radioSectionTag,
- styles.radioSection,
- forms.groupBuyType === 'GROUP_BUY' ? styles.active : ''
- ]}
- >
- <Radio
- class={styles.radioItem}
- name={'GROUP_BUY'}
- disabled={true}
- onClick={() => {
- // if (!forms.registerSubjectId) {
- // showToast('请选择选报声部')
- // return
- // }
- }}
- ></Radio>
- {otherParams.toolPlan.groupTitle}
- <p class={styles.radioTip}>{otherParams.toolPlan.groupDesc}</p>
- </Tag>
- <Tag
- size="large"
- type="primary"
- class={[
- styles.radioSectionTag,
- styles.radioSection,
- forms.groupBuyType === 'SELF' ? styles.active : ''
- ]}
- >
- <Radio class={styles.radioItem} name={'SELF'} disabled></Radio>
- {otherParams.toolPlan.selfTitle}
- <p class={styles.radioTip}>{otherParams.toolPlan.selfDesc}</p>
- </Tag>
- </RadioGroup>
- )
- }}
- </Field>
- </CellGroup>
- <CellGroup class={[styles.applyCellGroup, styles.groupBuy]} border={false}>
- <div class={[styles.title, styles.titleIntrumentTool]}></div>
- <Cell border={false}>
- {{
- icon: () => <Image src={state.vipYearInfo.goodsUrl} class={styles.goodsImg} />,
- value: () => (
- <div class={styles.vipYearInfo}>
- <div class={styles.goodsTitle}>
- {state.vipYearInfo.goodsName} <img src={icon12} />
- </div>
- <p class={styles.goodsTips}>乐团首次训练之日起生效</p>
- <p class={[styles.goodsMemo, 'van-multi-ellipsis--l2']}>
- {state.vipYearInfo.description}
- </p>
- <div class={styles.goodsPrice}>
- <div class={styles.priceGroup}>
- 团购价:
- <p>
- <span>¥</span> {moneyFormat(state.vipYearInfo.currentPrice)}
- </p>
- </div>
- </div>
- </div>
- )
- }}
- </Cell>
- <Cell border={false}>
- {{
- icon: () => <Image src={state.goodsInfo.goodsUrl} class={styles.goodsImg} />,
- value: () => (
- <div class={styles.goodsInfo}>
- <div class={styles.goodsTitle}>
- {state.goodsInfo.goodsName}
- {state.goodsInfo.currentPrice <= 0 ? <img src={iconFree} /> : ''}
- </div>
- <p class={[styles.goodsMemo, 'van-multi-ellipsis--l2']}>
- {state.goodsInfo.description}
- </p>
- <div class={styles.goodsPrice}>
- <div class={styles.priceGroup}>
- 团购价:
- <p>
- <del>
- <span>¥</span> {moneyFormat(state.goodsInfo.groupPrice)}
- </del>
- </p>
- </div>
- </div>
- </div>
- )
- }}
- </Cell>
- {otherParams.leBao.show ? (
- <Cell
- class={styles.inspectCell}
- style={{ backgroundColor: state.inspectStatus ? '#FFF3EA' : '#f4f4f4' }}
- >
- {{
- icon: () => (
- <img
- src={iconBao}
- class={styles.iconBao}
- onClick={() => {
- if (state.instrumentsInspectionDescribe) state.inspectPopupStatus = true
- }}
- />
- ),
- value: () => (
- <div class={styles.baoContainer}>
- <div
- class={styles.baoTitle}
- onClick={() => {
- if (state.instrumentsInspectionDescribe) state.inspectPopupStatus = true
- }}
- >
- 下校检查乐器 1-2次/学期
- </div>
- <div class={styles.baoPrice}>
- <p
- // onClick={() => {
- // state.inspectStatus = !state.inspectStatus
- // calcPrice()
- // }}
- >
- <span class={styles.prefix}>¥</span> {state.inspectInfo.currentPrice}
- <span class={styles.suffix}>/年</span>
- </p>
- <Checkbox
- v-model={otherParams.leBao.selected}
- // onClick={() => {
- // calcPrice()
- // }}
- >
- {{
- icon: (props: any) => (
- <img
- class={styles.checkboxImg}
- src={props.checked ? iconCheckboxActive : iconCheckbox}
- />
- )
- }}
- </Checkbox>
- </div>
- </div>
- )
- }}
- </Cell>
- ) : (
- ''
- )}
- </CellGroup>
- </Form>
- </div>
- )
- }
- })
|