YingXingAI/pages/my/BackApply/BackApply.vue

800 lines
23 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view style="background-color: white; height: 100vh">
<u-navbar title="返校预约申请"></u-navbar>
<!-- 内容 -->
<scroll-view
scroll-y="true"
style="
height: calc(100vh - 240rpx);
width: 100%;
border-top: 1px solid #edf2fa;
background-color: #fff;
box-sizing: border-box;
"
>
<!-- 基础信息 -->
<view class="base-box">
<view class="item-line">
<text class="line-label"> 预约人</text>
<text class="line-value"> {{ baseMsg.name || "-" }} </text>
</view>
<view class="item-line">
<text class="line-label"> 学院专业</text>
<text class="line-value"> {{ baseMsg.college + "-" + baseMsg.major }} </text>
</view>
<view class="item-line">
<text class="line-label"> 学历层次</text>
<text class="line-value"> {{ baseMsg.educationStr || "-" }} </text>
</view>
<view class="item-line">
<text class="line-label"> 毕业年份</text>
<text class="line-value"> {{ baseMsg.endYear || "-" }} </text>
</view>
</view>
<!-- 表单 -->
<view class="form-box">
<!-- 返校日期 -->
<view class="item-date" @click="dateShowFn">
<text class="line-label must"> 返校日期</text>
<u-input
:custom-style="inputStyle"
type="text"
input-align="right"
:border="false"
v-model="formData.date"
@click.native="dateShowFn"
placeholder="请选择"
disabled
/>
<view class="img">
<image
style="width:15rpx; height: 25rpx; margin-left: 20rpx"
src="/static/common/img/row_right.png"
/>
</view>
<!-- 点击盒子 -->
<view class="input-mask"></view>
</view>
<!-- 提示 -->
<view class="item-tip" v-if="weekSet.length">
<text class="line-label"> 提示:每周{{ dateTip }}暂停开放返校服务</text>
</view>
<!-- 车牌号 -->
<view class="item-line" style="border: none;">
<text class="line-label"> 车牌号</text>
<u-input
:custom-style="inputStyle"
type="text"
input-align="right"
:border="false"
maxlength="10"
v-model="formData.carNumber"
placeholder="如果车辆入校请务必填写"
/>
</view>
<!-- 联系电话 -->
<view class="item-line" style="border: none;">
<text class="line-label must"> 联系电话</text>
<u-input
:custom-style="inputStyle"
type="number"
input-align="right"
:border="false"
maxlength="20"
v-model="formData.phone"
placeholder="请输入"
/>
</view>
<!-- 随行人信息 -->
<view class="item-line">
<text class="line-label"> 随行人信息</text>
<text @click="addPersonFn" style="color: #3cb5fb"> 添加随行人 </text>
</view>
<!-- 动态随行人 -->
<view class="item-box">
<view class="item-for" v-for="(x, xIndex) in sxList" :key="xIndex">
<!-- 左侧内容 -->
<view class="for-left">
<view class="each">
<text class="must"> 随行人{{ xIndex + 1 }}</text>
<u-input
:custom-style="eachStyle"
type="text"
input-align="right"
:border="false"
maxlength="20"
v-model="x.name"
placeholder="请输入"
/>
</view>
<view class="each">
<text class="must"> 手机号</text>
<u-input
:custom-style="eachStyle"
type="number"
input-align="right"
:border="false"
maxlength="20"
v-model="x.phone"
placeholder="请输入"
/>
</view>
</view>
<!-- 右侧删除 -->
<view class="del">
<!-- <u-icon
@click="delFn(xIndex)"
name="trash"
color="#2799f6"
size="45"
></u-icon> -->
<image style="width: 32rpx;height: 32rpx;" src="/static/common/img/delete.svg" @click="delFn(xIndex)"></image>
</view>
</view>
</view>
<!-- 返校事由 -->
<view class="item-line">
<text class="line-label must"> 返校事由</text>
</view>
<view class="item-text">
<u-input
type="textarea"
height="200"
:border="false"
v-model="formData.retuenSchoolReason"
placeholder="请输入"
/>
</view>
<!-- 同意区域 -->
<view class="item-agree">
<view class="agree-left">
<u-checkbox-group>
<u-checkbox v-model="formData.checked"></u-checkbox>
</u-checkbox-group>
</view>
<view class="agree-right">{{ desc }}</view>
</view>
</view>
<view style="height: 50rpx"></view>
</scroll-view>
<!-- 按钮 -->
<view class="btn-box">
<u-button style="width: 80%" shape="circle" type="primary" @click="btnSubmitFn"
>提交</u-button
>
</view>
<u-top-tips ref="uTips" :navbar-height="50"></u-top-tips>
<!-- 选择日期范围 -->
<!-- date 单个日期范围 range 多个日期范围 min-date="" -->
<u-calendarWeek
max-year="2030"
min-year="2020"
max-date="2030"
:min-date="minDate"
:max-date="maxDate"
v-model="dateShow"
:filterWeek="weekSet"
:filterDate="filterDate"
mode="range"
@change="dateChangeFn"
></u-calendarWeek>
<u-toast ref="uToast" />
</view>
</template>
<script>
export default {
data() {
return {
// 表单
formData: {
carNumber: "", // 车牌号
phone: "", // 联系电话
checked: false, //是否同意
retuenSchoolReason: "", //返校事由
date: "", //返校日期
},
// 日期的值
dateList: [],
// 随行人
sxList: [
{
name: "",
phone: "",
},
],
// 选择日期
dateShow: false,
//
inputStyle: {
lineHeight: "90rpx",
height: "90rpx",
width: "400rpx",
},
eachStyle: {
lineHeight: "80rpx",
height: "80rpx",
width: "400rpx",
},
desc:
"本人承诺进校期间,遵守国家相关规律法规和校园管理相关规定,服从工作人员的指挥和管理",
// 基础信息
baseMsg: {
id: "",
name: "", //姓名
schoolName: "",
schoolLogo: "",
startYear: "", //入学年份
college: "", //学院
educationStr: "", //学历层次
major: "", //专业
endYear: "", //毕业年份
},
// 星期设置
weekSet: [],
// 已预约的日期 这里需要两个格式 2025-2-19 2025/2/19
filterDate:[],
// 选择日期提示
dateTip: "",
// 最小日期
minDate: "",
// 最大日期
maxDate: "",
};
},
async onLoad(e) {
await this.getSchoolFn();
// 获取返校设置
this.getSetFn();
// 获取已预约的日期
this.getFilterDate();
},
created() {},
methods: {
async getFilterDate(){
const req = {
// userId: this.vuex_user.id,
educationId: this.baseMsg.id,
}
// return
const res = await this.$u.apiList.GetDateTimeReturnApi(req);
console.log(res,'res--获取已预约日期')
// 截取一下
const result = res.map(x=>x.retuenSchoolTime.slice(0,10))
// 保存一份不去0的
this.filterDateSource = [...result];
// 去0 [2025-2-18]
const arr1 = result.map(x=>x.replace(/(?<=-)0/g, ''))
// 在生成一个 [2025/02/18]
const arr2 = arr1.map(x=>x.replaceAll('-','/'))
// 已预约的日期
this.filterDate = [...arr1,...arr2];
},
arrayToString(arr) {
let result = "";
const map = new Map([
[0, "周日"],
[1, "周一"],
[2, "周二"],
[3, "周三"],
[4, "周四"],
[5, "周五"],
[6, "周六"],
]);
arr.forEach((x) => {
if (map.has(x)) {
result += map.get(x) + "、";
}
});
return arr.length ? result.slice(0, result.length - 1) : result;
},
//获取返校设置
async getSetFn() {
const req = {
schoolId: this.baseMsg.schoolId,
}
const res = await this.$u.apiList.SelectInfoSetApi(req);
console.log(res, "res--");
let AllArr = [0, 1, 2, 3, 4, 5, 6];
// 星期设置
if (res.isDayOfWeek) {
let result = res.dayOfWeek.split(",").map((x) => Number(x));
this.weekSet = AllArr.filter((x) => {
return !result.includes(x);
});
// 处理tip提示
this.dateTip = this.arrayToString(this.weekSet);
}
// 限制选择日期
// 在用户需要提前几天申请预约
if (res.isBefore) {
const date = new Date();
date.setDate(date.getDate() + res.beforeDay);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
this.minDate = `${year}-${month}-${day}`;
} else {
// 默认最小日期是今天
const date = new Date();
date.setDate(date.getDate());
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
this.minDate = `${year}-${month}-${day}`;
}
// 用户最大可选日期 默认180天
const dateRes = new Date();
// 在用户需要提前几天申请预约
let maxDay = res.isDayOfWeek ? res.returnSchoolDays : 180
dateRes.setDate(dateRes.getDate() + maxDay);
const year1 = dateRes.getFullYear();
const month1 = String(dateRes.getMonth() + 1).padStart(2, "0");
const day1 = String(dateRes.getDate()).padStart(2, "0");
this.maxDate = `${year1}-${month1}-${day1}`;
},
async getSchoolFn() {
const req = {
userId: this.vuex_user.id,
};
const res = await this.$u.apiList.MyEducations(req);
console.log(res, "res--");
const findRow = res.find((x) => x.isSelected === true);
if (!findRow) {
/* uni.showToast({
title: "未查询到当前教育经历",
icon: "none",
}); */
this.$refs.uToast.show({
title: "未查询到当前教育经历",
type: "error",
});
return;
}
Object.assign(this.baseMsg, findRow);
this.baseMsg.name = this.vuex_user.name;
},
// 添加随行人
addPersonFn() {
this.sxList.push({
name: "",
phone: "",
});
},
// 删除随行人
delFn(index) {
uni.showModal({
// title: "提示",
content: `确定删除随行人${index + 1}`,
success: (res) => {
if (res.confirm) {
this.sxList.splice(index, 1);
}
if (res.cancel) {
// console.log('用户点击取消');
}
},
});
},
// 选择日期
dateShowFn() {
this.dateShow = true;
},
// 日期change
dateChangeFn(e) {
console.log(e, "e--");
this.currentList = this.getDatesArray(e.startDate, e.endDate);
console.log(JSON.parse(JSON.stringify(this.currentList)),'this.currentList--1');
// 判断是否包含不可选中日期
let flag = this.currentList.some(function(x){
// 包含禁用的日期
if (this.disArr.includes(new Date(x).getDay())) {
return true;
}
// 包含已预约的日期
if(this.selectArr.includes(x)){
return true;
}
return false;
},{
disArr:this.weekSet, // 禁用的星期
selectArr:this.filterDateSource // 已预约的日期
})
// 过滤一下禁用的星期
// this.currentList = this.currentList.filter((x) => {
// // 当天的星期
// const dateWeek = new Date(x).getDay();
// // 包含禁用的星期过滤掉
// if (this.weekSet.includes(dateWeek)) {
// return false;
// }
// return true;
// });
// 过滤掉已预约的日期
// this.currentList = this.currentList.filter((x) => {
// if(this.filterDateSource.includes(x)){
// return false;
// }else{
// return true;
// }
// });
if(flag){
/* uni.showToast({
icon:'none',
title: `当前返校时间包含不可预约的日期,请重新选择!`,
duration: 2000,
}); */
this.$refs.uToast.show({
title: `当前返校时间包含不可预约的日期,请重新选择!`,
type: "error",
});
this.dateShow = true;
return
}
// 显示的值
this.formData.date = e.startDate + " ~ " + e.endDate;
console.log(JSON.parse(JSON.stringify(this.currentList)),'this.currentList--2');
// 处理成后端要的格式
this.dateList = this.currentList.map((x) => {
return {
time: x,
};
});
console.log(JSON.parse(JSON.stringify(this.dateList)),'this.dateList');
},
// 校验表单信息
validate() {
// 校验手机号的正则表达式
const phoneReg = /^[1][3-9][0-9]{9}$/;
return new Promise((resolve, reject) => {
// 校验返校日期
if (!this.formData.date) {
// this.$tips("返校日期不能为空", "error");
this.$refs.uToast.show({
title: "返校日期不能为空",
type: "error",
});
return reject(false);
}
// 校验联系电话
if (!this.formData.phone) {
// this.$tips("联系电话不能为空", "error");
this.$refs.uToast.show({
title: "联系电话不能为空",
type: "error",
});
return reject(false);
}
if (!phoneReg.test(this.formData.phone)) {
// this.$tips("联系电话格式不正确,请输入有效的手机号", "error");
this.$refs.uToast.show({
title: "联系电话格式不正确,请输入有效的手机号",
type: "error",
});
return reject(false);
}
// 校验随行人信息
if (this.sxList.length) {
for (let i = 0; i < this.sxList.length; i++) {
const item = this.sxList[i];
// 校验随行人名称
if (!item.name) {
// this.$tips(`随行人${i + 1}的名称不能为空`, "error");
this.$refs.uToast.show({
title: `随行人${i + 1}的名称不能为空`,
type: "error",
});
return reject(false);
}
// 校验随行人手机号
if (!item.phone) {
// this.$tips(`随行人${i + 1}的手机号不能为空`, "error");
this.$refs.uToast.show({
title: `随行人${i + 1}的手机号不能为空`,
type: "error",
});
return reject(false);
}
if (!phoneReg.test(item.phone)) {
// this.$tips(`随行人${i + 1}的手机号格式不正确,请输入有效的手机号`, "error");
this.$refs.uToast.show({
title: `随行人${i + 1}的手机号格式不正确,请输入有效的手机号`,
type: "error",
});
return reject(false);
}
}
}
// 校验返校事由
if (!this.formData.retuenSchoolReason) {
// this.$tips("返校事由不能为空", "error");
this.$refs.uToast.show({
title: "返校事由不能为空",
type: "error",
});
return reject(false);
}
resolve(true);
});
},
// 日期转换数组
getDatesArray(startDate, endDate) {
// 将输入的字符串转换为 Date 对象
const start = new Date(startDate);
const end = new Date(endDate);
// 创建一个用于存储结果的数组
let datesArray = [];
// 复制开始日期,以免修改原始对象
let currentDate = new Date(start);
// 使用循环从开始日期遍历到结束日期
while (currentDate <= end) {
// 将当前日期添加到数组中
// 使用 toISOString 方法去掉 T 后面的时间部分并去掉最后的 Z 和小数秒
datesArray.push(new Date(currentDate).toISOString().split("T")[0]);
// 增加一天
currentDate.setDate(currentDate.getDate() + 1);
}
return datesArray;
},
// 我要预约
async btnSubmitFn() {
const result = await this.validate().catch((e) => e);
console.log(result, "result");
if (!result) {
return;
}
// 校验是否勾选了同意
if (!this.formData.checked) {
return uni.showModal({
// title: "提示",
content: this.desc,
success: (res) => {
if (res.confirm) {
// 默认帮用户勾选上 提交
this.formData.checked = true;
this.submit();
}
if (res.cancel) {
// console.log('用户点击取消');
}
},
});
}
this.submit();
},
// 提交的函数
async submit() {
// this.$tips("开发中", "success");
const req = {
userId: this.vuex_user.id,
educationId: this.baseMsg.id,
carNumber: this.formData.carNumber, //车牌号
phone: String(this.formData.phone), //联系电话
retuenSchoolReason: this.formData.retuenSchoolReason, //返校事由
// 随行人
TogetherPersonDtoList: this.sxList.map((x, xIndex) => {
x.index = xIndex;
x.phone = String(x.phone);
return x;
}),
// 日期
TimeList: this.dateList,
};
const res = await this.$u.apiList.AddReturnSchoolApi(req).catch(e=>e);
console.log(res, "res---");
if (res?.succeed === false) {
/* uni.showToast({
icon:'none',
title: res.error || "提交失败",
duration: 2000,
}); */
this.$refs.uToast.show({
title: res.error || "提交失败",
type: "error",
});
return;
}
/* uni.showToast({
title: "提交成功",
duration: 2000,
}); */
this.$refs.uToast.show({
title: "提交成功",
type: "success",
});
setTimeout(() => {
// 返回上一页
/* this.$u.route({
url: "pages/my/BackSchool/BackSchool",
}); */
uni.navigateBack({
delta: 1
});
}, 1000);
},
},
};
</script>
<style lang="scss" scoped>
// 必填的样式
.must {
position: relative;
&::before {
content: "*";
color: red;
position: absolute;
top: -10rpx;
right: -17rpx;
transform: scale(0.8);
/* 相对于父元素的左上角定位 */
}
}
.body-box {
max-height: calc(100vh - 250rpx);
overflow-y: auto;
border: 1px solid red;
}
// 基础信息
.base-box {
background-color: white;
// 单行样式
.item-line {
text-align: left;
padding-left: 30rpx;
padding-right: 30rpx;
font-size: 30rpx;
line-height: 90rpx;
height: 90rpx;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #f1f2f6;
.line-label {
// font-size: 30rpx;
color: black;
}
.line-value {
// font-weight: 700;
color: #969696;
}
}
}
// 表单
.form-box {
margin-top: 20rpx;
background-color: white;
// 返校日期
.item-date {
padding-left: 30rpx;
padding-right: 30rpx;
font-size: 30rpx;
line-height: 90rpx;
height: 90rpx;
display: flex;
position: relative;
.input-mask {
position: absolute;
width: 100%;
height: 90rpx;
// background-color: red;
}
.img {
display: flex;
align-items: center;
justify-content: center;
width: 30rpx;
// padding-right: 30rpx;
}
}
// 单行样式
.item-line {
text-align: left;
padding-left: 30rpx;
padding-right: 30rpx;
font-size: 30rpx;
line-height: 90rpx;
height: 90rpx;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #f1f2f6;
.line-label {
// font-size: 30rpx;
color: black;
}
}
// 提示
.item-tip {
text-align: left;
padding-left: 30rpx;
padding-right: 30rpx;
padding-bottom: 10rpx;
font-size: 22rpx;
// line-height: 90rpx;
// height: 90rpx;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #f1f2f6;
.line-label {
// font-size: 30rpx;
color: red;
}
}
// 随行人样式
.item-for {
background-color: #f7f6f9;
padding-left: 30rpx;
display: flex;
width: 100%;
border-bottom: 1px solid #e1e1e1 ;
.for-left {
// border: 1px solid blue;
width: calc(100% - 50rpx);
.each {
flex: 1;
display: flex;
justify-content: space-between;
line-height: 80rpx;
height: 80rpx;
padding-right: 30rpx;
}
}
.del {
// border: 1px solid red;
width: 40rpx;
display: flex;
justify-content: center;
align-items: center;
}
&:last-of-type{
border-bottom: none;
}
}
// 文本框
.item-text {
padding-left: 30rpx;
padding-right: 30rpx;
}
// 同意样式
.item-agree {
padding-left: 30rpx;
padding-right: 30rpx;
display: flex;
padding-bottom: 20rpx;
padding-top: 20rpx;
border-top: 1px solid #f1f2f6;
// margin-bottom: 50rpx;
// flex-wrap: wrap;
.agree-left {
width: 50rpx;
}
.agree-right {
color: black;
flex: 1;
}
}
}
// 按钮
.btn-box {
position: fixed;
width: 100%;
bottom: 0;
height: 150rpx;
border-top: 1px solid #f1f2f6;
display: flex;
align-items: center;
justify-content: center;
}
</style>