Files
zhxg_app_v1.0/pages/sub/StuApply.vue
2025-07-16 15:34:34 +08:00

1012 lines
25 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 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>