Files
zhxg_app_v1.0/pages/sub/StuApply.vue

1012 lines
25 KiB
Vue
Raw Normal View History

2025-07-16 15:34:34 +08:00
<template>
<view class="StuApply">
<Nav :navs="navs" @change="navChange" />
<!-- 离校留校申请 -->
<view v-if="navIndex==0">
<view v-if="!lookV">
<view>
<view class="list" v-if="surList.length>0">
<view class="item" v-for="(v,i) in surList" :key="i" @tap="doEdit(v)">
<view class="top">
主题{{v.surveyName}}
<uni-icons type="right" size="18" color="#202020"></uni-icons>
<view class="fill">
<!-- <uni-icons type="compose" color="#1890FF" size="18"></uni-icons>
<text>
<span v-if='v.isSubmit == ""'>{{isEmpty(v.homeGps) ? "到家" : "详情"}}&nbsp;&nbsp;&nbsp;&nbsp;< </span>
<span v-else>填写&nbsp;&nbsp;&nbsp;&nbsp;< </span>
</text> -->
<u-icon name="edit-pen-fill" color="#2b85e4"></u-icon>
<u--text v-if='v.isSubmit == ""' :text='isEmpty(v.homeGps) ? "到家" : "详情"'
color="#2b85e4"></u--text>
<u--text v-else text='填写' color="#2b85e4"></u--text>
<!-- <u-icon name="arrow-right" color="#2b85e4"></u-icon> -->
</view>
</view>
<view class="content">
<view>截止时间{{v.cutoffTime}}</view>
<view class="level">是否填写:
<!-- <text
:class="v.isSubmit=='是'?'finish':'underway'">{{v.isSubmit == "是" ? "已填写" : "未填写"}}</text> -->
<u-tag :text='v.isSubmit == "是" ? "已填写" : "未填写"'
:type="v.isSubmit=='是'?'success':'error'" plain></u-tag>
</view>
<view class="level">
审核状态
<!-- {{getApplyStatus(v.leaveStatus)}} -->
<u-tag :text="getApplyStatus(v.leaveStatus).text"
:type="getApplyStatus(v.leaveStatus).type"></u-tag>
</view>
</view>
</view>
</view>
</view>
</view>
<view v-else>
<view class="container">
<view class="top-div">
<span style="height: 40rpx;line-height: 40rpx;" @click="lookV=false">
<返回 </span>
</view>
<view style="text-align: center;font-size: 40rpx;color:rgba(0, 0, 0, 0)">
<span>申请</span>
</view>
<view v-if="formData.leaveStatus == '2'" style="position: absolute;top: 0;right: 0;">
<span style="height: 40rpx;line-height: 40rpx;" @click="toReturn">
点我返校> </span>
</view>
</view>
<view>
<view class="form-item"
v-if="formData.leaveStatus == 1 || formData.leaveStatus == 2 ||formData.leaveStatus == 10">
<label>审核状态</label>
<view style="color: red;border-bottom: 1px solid black;"> {{formData.leaveStatus == 1 ? "已提交"
: formData.leaveStatus == 2 ? "通过"
:formData.leaveStatus == 10 ? "打回" :""}}
</view>
</view>
<view class="form-item">
<label>学院</label>
<select v-model="formData.moreDeptName" :disabled="formData.leaveStatus == 2">
<option v-for="(v,i) in moreDeptList" :key="i">{{v.dictValue}}</option>
</select>
</view>
<view class="form-item">
<label>学生电话</label>
<input :disabled="formData.leaveStatus == 2" placeholder="请输入" v-model="formData.phone" />
</view>
<view class="form-item">
<label>紧急联系人姓名</label>
<input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.emergencyContact" />
</view>
<view class="form-item">
<label>紧急联系人电话</label>
<input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.emergencyContactPhone" />
</view>
<view class="form-item">
<label>家长姓名</label>
<input :disabled="formData.leaveStatus == 2" placeholder="请输入" v-model="formData.famName" />
</view>
<view class="form-item">
<label>家长电话</label>
<input :disabled="formData.leaveStatus == 2" placeholder="请输入" v-model="formData.famPhone" />
</view>
<view v-if="formData.leaveStatus != 2" class="form-item">
<label>家长是否知晓</label>
<radio-group :disabled="formData.leaveStatus == 2" @change="radioChange1">
<label class="uni-list-cell uni-list-cell-pd">
<view>
<radio :checked="formData.famKnow=='是'" :value="'是'" />
</view>
<view></view>
</label>
<label style="margin-left: 80rpx;" class="uni-list-cell uni-list-cell-pd">
<view>
<radio :checked="formData.famKnow=='否'" :value="'否'" />
</view>
<view></view>
</label>
</radio-group>
</view>
<view v-if="formData.leaveStatus == 2" class="form-item">
<label>家长是否知晓{{formData.famKnow}}</label>
</view>
<view v-if="formData.leaveStatus != 2">
<view class="form-item">
<label>是否离校</label>
<radio-group @change="radioChange3">
<label class="uni-list-cell uni-list-cell-pd">
<view>
<radio :checked="formData.isLeave=='1'" :value="'1'" />
</view>
<view>离校</view>
</label>
<label style="margin-left: 80rpx;" class="uni-list-cell uni-list-cell-pd">
<view>
<radio :checked="formData.isLeave=='0'" :value="'0'" />
</view>
<view>留校</view>
</label>
</radio-group>
</view>
</view>
<view v-if="formData.leaveStatus == 2" class="form-item">
<label>是否离校{{formData.isLeave== "1" ?"是":"否"}}</label>
</view>
<view v-if="formData.isLeave == '1'">
<view class="form-item">
<label>预计离校时间</label>
<DateTimePicker :disabled="formData.leaveStatus == 2" v-model="formData.willLeaveTime" />
</view>
<view class="form-item">
<label>预计返校时间</label>
<DateTimePicker :disabled="formData.leaveStatus == 2"
v-model="formData.scheduledReturnTime" />
</view>
<view v-if="formData.leaveStatus == '2' && formData.isLeave == '1'">
<view v-if="isEmpty(formData.homeGps)" class="form-item">
<label>是否到家 <text style="color: red;">*请在到达目的地后填写</text> </label>
<radio-group @change="radioChange2">
<label class="uni-list-cell uni-list-cell-pd">
<view>
<radio :checked="formData.isHome=='是'" :value="'是'" />
</view>
<view></view>
</label>
<label style="margin-left: 80rpx;" class="uni-list-cell uni-list-cell-pd">
<view>
<radio :checked="formData.isHome=='否'" :value="'否'" />
</view>
<view></view>
</label>
</radio-group>
</view>
<view v-if="formData.homeSubmit == '1'" class="form-item">
<label>是否到家{{formData.isHome}}</label>
</view>
<view v-if="formData.isHome == '是'" class="form-item">
<view v-if="formData.homeSubmit != '1'">
<label>到家定位 <text style="color: red;">*请在到家后获取</text> </label>
<view>
<button style="display: inline-block;" @click="getLocation">获取定位</button>
<button type="primary" style="display: inline-block;margin-left: 30rpx;"
@click="stuHomeUpdate">点我提交</button>
</view>
</view>
<view v-if="formData.homeSubmit != '1'">
<map style="width:100%;height:300px;" :latitude="latitude" :longitude="longitude"
:markers="covers" show-location></map>
</view>
<view v-else>
<label>到家定位 </label>
<map style="width:100%;height:300px;" :latitude="formData.homeGps.split(',')[0]"
:longitude="formData.homeGps.split(',')[1]" :markers="covers"
show-location></map>
</view>
</view>
<view v-if="formData.isHome == '否'" class="form-item">
<view v-if="formData.homeSubmit != '1'">
<label>到目的地定位 <text style="color: red;">*请在到达目的地后获取</text> </label>
<view>
<button style="display: inline-block;" @click="getLocation">获取定位</button>
<button type="primary" style="display: inline-block;margin-left: 30rpx;"
@click="stuHomeUpdate">点我提交</button>
</view>
</view>
<view v-if="formData.homeSubmit != '1'">
<map style="width:100%;height:300px;" :latitude="latitude" :longitude="longitude"
:markers="covers" show-location></map>
</view>
<view v-else>
<label>到目的地定位 </label>
<map style="width:100%;height:300px;" :latitude="formData.homeGps.split(',')[0]"
:longitude="formData.homeGps.split(',')[1]" :markers="covers"
show-location></map>
</view>
</view>
</view>
</view>
<view v-if="formData.isLeave == '0'">
<view class="form-item">
<label>预计留校时间 <text style="color: red;">*xxxx年x月x日至xxxx年x月x日</text> </label>
<input placeholder="请输入xxxx年x月x日至xxxx年x月x日" v-model="formData.willStayTime" />
</view>
<view class="form-item">
<label>留校事由</label>
<textarea placeholder="请输入留校事由" v-model="formData.stayReason" />
</view>
</view>
<view v-if="formData.leaveStatus != '2'" style="text-align: center;">
<button type="primary" @click="doApply" style="width: 80%;display: inline-block;">
{{ formData.leaveStatus == 1 || formData.leaveStatus == 10 ? "修改" :"提交" }}
</button>
</view>
</view>
</view>
</view>
<!-- 返校填写 -->
<view v-if="navIndex==1">
<view class="list" v-if="surList.length>0">
<view class="item" v-for="(v,i) in returnList" :key="i"
@tap.stop="()=>{formData.returnSchoolId = v.returnSchoolId;toReturn();}">
<view class="top">
主题{{v.surveyName}}
<uni-icons type="right" size="18" color="#202020"></uni-icons>
<view class="fill" @tap.stop="()=>{formData.returnSchoolId = v.returnSchoolId;toReturn();}">
<!-- <uni-icons type="compose" color="#1890FF" size="18"></uni-icons>
<text>
<span v-if='isEmpty(v.scheduledReturnTime)'>填写&nbsp;&nbsp;&nbsp;&nbsp;< </span>
<span v-else>{{v.status == "2" ? "到校" : "详情"}} &nbsp;&nbsp;&nbsp;&nbsp;< </span>
</text> -->
<u-icon name="edit-pen-fill" color="#2b85e4"></u-icon>
<u--text v-if='isEmpty(v.scheduledReturnTime)' text="填写" color="#2b85e4"></u--text>
<u--text v-else :text='v.status == "2" ? "到校" : "详情"' color="#2b85e4"></u--text>
<!-- <u-icon name="arrow-right" color="#2b85e4"></u-icon> -->
</view>
</view>
<view class="content">
<!-- <view>收假时间{{v.cutoffTime}}</view> -->
<view class="level">状态:
<u-tag :text='getApplyStatus(v.status).text' :type="getApplyStatus(v.status).type"
plain></u-tag>
<!-- <text class="finish">{{getApplyStatus(v.status)}}</text> -->
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import DateTimePicker from "@/components/DateTimePicker.vue";
import {
getOwnInfo,
getOwnFamily
} from "@/api/person/person.js";
import {
getDicts
} from "@/api/system/dict/data.js";
import {
getWxConfig
} from "@/api/common/wechat";
import wx from "weixin-js-sdk"; // 引入微信 JS-SDK
import * as ww from '@wecom/jssdk'
import Nav from "@/components/navs/navs.vue";
import {
listStu,
getAddr,
stuLeaveApply,
stuGetRecordBySvId,
stuHomeUpdate,
listOwnReturn
} from '@/api/sur';
import {
isEmpty,
isValidPhone
} from "@/api/helpFunc/index.js";
export default {
components: {
Nav,
DateTimePicker
},
data() {
return {
covers: [{
latitude: null,
longitude: null,
iconPath: '../../static/images/applyrelieve/location.png'
}],
isEmpty,
searchValue: "",
surList: [],
lookV: false,
formData: {
willLeaveTime: "",
scheduledReturnTime: "",
isLeave: "1",
homeGps: ""
},
latitude: '',
longitude: '',
accuracy: '',
navIndex: 0,
navs: [{
text: "离校留校申请",
val: 0
},
{
text: "返校填写",
val: 1
}
],
returnList: [],
ownPhone: null,
ownParentName: null,
ownParentPhone: null,
ownClassName: null,
ownCtuName: null,
ownStuNo: null,
moreDeptList: [],
ownDeptName: "",
ownFdyName: ""
}
},
async onShow() {
await this.initWxConfig(); // 初始化微信配置
this.getLocation();
this.listStu();
this.listOwnReturn();
this.getOwnInfo();
this.getOwnFamily();
this.getDicts();
},
methods: {
async getDicts() {
let res = await getDicts("more_dept_name");
if (res.code == 200) {
this.moreDeptList = [...res.data];
}
},
async getOwnFamily() {
uni.showLoading();
let res = await getOwnFamily();
uni.hideLoading();
if (res.code == 200) {
let data = [...res.data];
if (!isEmpty(data)) {
this.ownParentName = data[0].familyName;
this.ownParentPhone = data[0].phone;
}
}
},
async getOwnInfo() {
uni.showLoading();
let res = await getOwnInfo();
uni.hideLoading();
if (res.code == 200) {
this.ownPhone = res.data.stuPhone;
this.ownDeptName = res.data.deptName;
this.ownFdyName = res.data.teacherName;
this.ownClassName = res.data.className;
this.ownName = res.data.stuName;
this.ownStuNo = res.data.stuNo;
}
},
radioChange3(evt) {
this.formData.isLeave = evt.detail.value;
this.$forceUpdate();
},
async listOwnReturn() {
uni.showLoading();
let res = await listOwnReturn();
uni.hideLoading();
if (res.code == 200) {
this.returnList = [...res.data];
}
},
getApplyStatus(status) {
if (isEmpty(status)) {
return {
text: "未填写",
type: "info"
};
}
if (status == 0) {
return {
text: "未提交",
type: "warning"
};
}
if (status == 1) {
return {
text: "已提交",
type: "primary"
};
}
if (status == 2) {
return {
text: "已审核",
type: "success "
};
}
if (status == 10) {
return {
text: "打回",
type: "error"
};
}
},
onClear() {
},
onSearch() {
},
navChange(index) {
this.navIndex = index;
if (index == 1) {
this.listOwnReturn();
} else {
this.listStu();
}
},
toReturn() {
uni.navigateTo({
url: "/pages/sub/StuReturn?id=" + this.formData.returnSchoolId
});
},
async stuHomeUpdate() {
let sdata = {
...this.formData
};
if (isEmpty(sdata.isHome)) {
uni.showToast({
title: "请选择是否到家",
icon: "none",
mask: true
});
return;
}
if (isEmpty(this.formData.tempHomeGps)) {
uni.showToast({
title: "请点击定位",
icon: "none",
mask: true
});
return;
} else {
sdata.homeGps = this.formData.tempHomeGps;
}
uni.showLoading({
mask: true
});
let res = await stuHomeUpdate(sdata);
uni.hideLoading();
if (res.code == 200) {
uni.showToast({
title: res.msg,
mask: true
});
this.lookV = false;
this.listStu();
}
},
async doApply(val) {
let sdata = {
...this.formData
};
if (isEmpty(sdata.moreDeptName)) {
uni.showToast({
title: "请选择学院",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.phone)) {
uni.showToast({
title: "请输入学生电话",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.emergencyContact)) {
uni.showToast({
title: "请输入紧急联系人姓名",
icon: "none",
mask: true
});
return;
}
// 使用示例
if (!isValidPhone(sdata.emergencyContactPhone)) {
uni.showToast({
title: "请输入正确的紧急联系人电话",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.emergencyContactPhone)) {
uni.showToast({
title: "请输入紧急联系人电话",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.famName)) {
uni.showToast({
title: "请输入家长姓名",
icon: "none",
mask: true
});
return;
}
// 使用示例
if (!isValidPhone(sdata.famPhone)) {
uni.showToast({
title: "请输入正确的家长电话",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.famPhone)) {
uni.showToast({
title: "请输入家长电话",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.famKnow)) {
uni.showToast({
title: "请选择家长是否知晓",
icon: "none",
mask: true
});
return;
}
if (sdata.isLeave == "1") {
if (isEmpty(sdata.willLeaveTime)) {
uni.showToast({
title: "请选择离校时间",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.scheduledReturnTime)) {
uni.showToast({
title: "请选择预计返校时间",
icon: "none",
mask: true
});
return;
}
}
// console.log("表单", sdata)
return;
uni.showLoading({
mask: true
});
let res = await stuLeaveApply(sdata);
uni.hideLoading();
if (res.code == 200) {
uni.showToast({
title: res.msg,
mask: true
});
this.lookV = false;
this.listStu();
}
},
async initWxConfig() {
let that = this;
let res = await that.getConfigSignature();
that.info += JSON.stringify(res)
ww.register({
corpId: 'wx129e6bf0f36b8b3d', // 必填当前用户企业所属企业ID
agentId: 1000093, // 必填当前应用的AgentID
jsApiList: ["getLocation", "openLocation"], // 必填需要使用的JSAPI列表
// getAgentConfigSignature: that.getAgentConfigSignature, // 必填根据url生成应用签名的回调函数
getConfigSignature() {
// console.log(res)
return res
}
})
},
// 初始化微信 JS-SDK
async getConfigSignature() {
return new Promise((resolve, reject) => {
// 调用后端接口获取签名信息(需要后端支持)
getWxConfig("corpId").then(res => {
const {
timestamp,
nonceStr,
signature
} = res;
resolve({
timestamp,
nonceStr,
signature
});
}).catch(err => {
reject(err);
});
});
},
async getAgentConfigSignature() {
return new Promise((resolve, reject) => {
// 调用后端接口获取签名信息(需要后端支持)
getWxConfig("agentId").then(res => {
const {
timestamp,
nonceStr,
signature
} = res;
resolve({
timestamp,
nonceStr,
signature
});
}).catch(err => {
reject(err);
});
});
},
getLocation() {
ww.getLocation({
isHighAccuracy: true,
type: 'gcj02',
success: async (res) => {
this.covers[0].latitude = res.latitude
this.covers[0].longitude = res.longitude
this.latitude = res.latitude;
this.longitude = res.longitude;
this.accuracy = res.accuracy;
this.formData.tempHomeGps = this.latitude + "," + this.longitude;
},
fail: (err) => {
uni.showToast({
title: "获取定位失败",
icon: 'fail'
})
}
});
},
radioChange2(evt) {
this.formData.isHome = evt.detail.value;
this.$forceUpdate();
},
radioChange1(evt) {
this.formData.famKnow = evt.detail.value;
this.$forceUpdate();
},
onChangeTime(e) {
this.formData.willLeaveTime = e.detail.value;
this.$forceUpdate();
},
async doEdit(v) {
let that = this;
this.formData = {};
this.formData.surveyId = v.surveyId;
this.formData.isSubmit = v.isSubmit;
if (v.isSubmit == "是") {
// uni.showLoading({
// mask: true
// });
// await stuGetRecordBySvId(v.surveyId).then(res => {
// uni.hideLoading();
// if (res.code == 200) {
// that.formData = {
// ...res.data
// };
// that.$set(that.formData, 'willLeaveTime', res.data.willLeaveTime);
// that.$forceUpdate();
// }
// });
} else {
this.formData.phone = this.ownPhone;
this.formData.famName = this.ownParentName;
this.formData.famPhone = this.ownParentPhone;
this.formData.stuFdyName = this.ownFdyName;
this.formData.className = this.ownClassName;
this.formData.name = this.ownName;
this.formData.stuNo = this.ownStuNo;
this.formData.moreDeptName = this.moreDeptList.filter(x => x.dictValue.includes(this.ownDeptName))[0].dictValue;
}
// console.log("doEdit", this.formData)
// this.lookV = true;
//跳转StudoEdit
uni.$u.route({
url: '/pages/sub/StudoEdit',
params: this.formData
})
},
iconClick() {
this.listStu();
},
async listStu() {
uni.showLoading({
mask: true
});
let res = await listStu({
surveyName: this.searchValue
});
uni.hideLoading();
if (res.code == 200) {
this.surList = [...res.data];
}
},
beforeDestroy() {
this.cleanup();
}
}
}
</script>
<style scoped lang="scss">
page {
background-color: #F5F5F7;
/* 设置背景颜色为浅灰色 */
}
.StuApply {
background-color: #F5F5F7;
// height: calc(100vh - 44px);
/* overflow: hidden; */
box-sizing: border-box;
box-sizing: border-box;
padding: 0 40rpx;
padding-top: 60px;
/deep/ .navs {
text {
padding-bottom: 8px;
}
}
}
.container {
position: relative;
/* 容器需要相对定位 */
}
.top-div {
position: absolute;
/* 上面的div绝对定位 */
top: 0;
/* 顶部对齐 */
left: 0;
/* 左侧对齐 */
}
.bottom-div {
/* 此处不需要特别设置,因为它默认就在下面的位置 */
}
.form-item {
display: flex;
flex-direction: column;
padding: 22rpx 40rpx;
background-color: white;
margin-bottom: 20rpx;
border-radius: 16rpx;
&.tip {
justify-content: center;
text:first-child {
color: red;
}
text:last-child {
margin-top: 10rpx;
color: #FFBA00;
}
}
.tip {
color: red;
font-size: 24rpx;
}
label {
margin-bottom: 20rpx;
display: inline-block;
font-weight: bold;
text {
color: red;
}
}
textarea {
height: 200rpx;
border: 1px solid #E1E1E1;
padding: 20rpx;
width: 100%;
}
input {
border: 1px solid #E1E1E1;
border-radius: 10rpx;
height: 70rpx;
padding-left: 30rpx;
}
picker {
border: 1px solid #E1E1E1;
height: 70rpx;
line-height: 70rpx;
padding: 0 30rpx;
.uni-input {
display: flex;
color: #797979;
.val {
flex: 1;
}
}
}
}
.list {
.item {
background-color: white;
margin-bottom: 40rpx;
padding: 40rpx;
border-radius: 16rpx;
position: relative;
.top {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #F5F5F7;
padding-bottom: 20rpx;
.uni-icons {
opacity: 0.5;
}
.fill {
position: absolute;
right: 0;
bottom: 0;
display: flex;
color: #1890FF;
border: 1px solid #A3D3FF;
background-color: #E8F4FF;
padding: 5px 15px;
border-radius: 16rpx 0 16rpx 0;
gap: 10rpx;
}
}
.content {
padding-top: 20rpx;
.level {
display: flex;
align-items: center;
margin-top: 15px;
text {
padding: 0;
display: inline-block;
width: 50px;
height: 20px;
text-align: center;
line-height: 20px;
margin-left: 5px;
border-radius: 8rpx;
}
.underway {
background-color: #F5F5F7;
color: #A7A8AC;
border: 1px solid #A7A8AC;
}
.finish {
background-color: #F5F5F7;
color: lime;
border: 1px solid lime;
}
}
&>view:not(:last-child) {
margin-bottom: 15rpx;
.progress {
color: #1890FF;
}
}
.status {
position: absolute;
bottom: 0;
right: 0;
color: white;
.status-text {
position: absolute;
bottom: 15px;
right: 8%;
font-size: 35rpx;
}
.triangle-right {
width: 0;
height: 0;
/* 上边框设置为透明 */
border-left: 120px solid transparent;
}
&.submit {
color: #202020;
.triangle-right {
/* 左边框设置为与文本相同的颜色 */
border-bottom: 100px solid #D7D7D7;
}
}
&.agree {
.triangle-right {
/* 左边框设置为与文本相同的颜色 */
border-bottom: 100px solid #2FB15B;
}
}
&.refuse {
.triangle-right {
/* 左边框设置为与文本相同的颜色 */
border-bottom: 100px solid #FF759F;
}
}
}
}
}
}
.search {
box-shadow: 0 0 5px #e6e6e6;
position: fixed;
top: 100px;
z-index: 999;
left: 40rpx;
right: 40rpx;
.uni-searchbar {
padding: 0;
}
}
</style>