移动端V1.0

This commit is contained in:
2025-07-16 15:34:34 +08:00
commit 194b0750fd
1083 changed files with 178295 additions and 0 deletions

703
pages/sub/StudoEdit.vue Normal file
View File

@@ -0,0 +1,703 @@
<template>
<view>
<view class="container">
<!-- <view v-if="formData.leaveStatus == '2'" class="header-btn">
<view class="back-school" @tap="toReturn">
<u--text text="点我返校" size="20" color="white"></u--text>
<u-icon name="arrow-right" size="20" color="white"></u-icon>
</view>
</view> -->
<!-- 内容部分 -->
<view class="content">
<view class="card" v-if="[1, 2, 10].includes(Number(formData.leaveStatus))">
<view class="form-item">
<view class="status-flex">
<label>审核状态</label>
<view>
<u-tag :text="leaveStatusText"></u-tag>
</view>
</view>
</view>
</view>
<view class="card">
<view class="form-item" @tap="showDeptPicker = true">
<label>学院</label>
<u-input v-model="formData.moreDeptName" placeholder="请选择学院"
:disabled="formData.leaveStatus == '2'" readonly></u-input>
<!-- <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>
<u-input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.className"></u-input>
</view>
<view class="form-item">
<label>学号</label>
<u-input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.stuNo"></u-input>
</view>
<view class="form-item">
<label>姓名</label>
<u-input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.name"></u-input>
</view>
<view class="form-item">
<label>辅导员</label>
<u-input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.stuFdyName"></u-input>
</view>
</view>
<view class="card" v-if="formData.leaveStatus == 2">
<view class="form-item">
<view class="status-flex">
<label>是否离校</label>
<u-tag :text='formData.isLeave== "1" ?"是":"否"'></u-tag>
</view>
</view>
</view>
<view class="card">
<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 class="radio-flex">
<radio :checked="formData.isLeave=='1'" :value="'1'" /> 离校
</view>
</label>
<label style="margin-left: 80rpx;" class="uni-list-cell uni-list-cell-pd">
<view class="radio-flex">
<radio :checked="formData.isLeave=='0'" :value="'0'" /> 留校
</view>
</label>
</radio-group>
</view>
</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 class="radio-flex">
<radio :checked="formData.famKnow=='是'" :value="'是'" />
</view>
</label>
<label style="margin-left: 80rpx;" class="uni-list-cell uni-list-cell-pd">
<view class="radio-flex">
<radio :checked="formData.famKnow=='否'" :value="'否'" />
</view>
</label>
</radio-group>
</view>
<view v-if="formData.leaveStatus == 2" class="form-item">
<view class="status-flex">
<label>家长是否知晓</label>
<u-tag :text="formData.famKnow"></u-tag>
</view>
</view>
</view>
<view class="card">
<view class="form-item">
<label>家长姓名</label>
<u-input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.famName"></u-input>
</view>
<view class="form-item">
<label>家长电话</label>
<u-input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.famPhone"></u-input>
</view>
<view class="form-item">
<label>学生电话</label>
<u-input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.phone"></u-input>
</view>
<view class="form-item">
<label>紧急联系人姓名</label>
<u-input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.emergencyContact"></u-input>
</view>
<view class="form-item">
<label>紧急联系人电话</label>
<u-input :disabled="formData.leaveStatus == 2" placeholder="请输入"
v-model="formData.emergencyContactPhone"></u-input>
</view>
</view>
<view v-if="formData.isLeave == '1'" class="card-list">
<view class="card">
<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>
<view v-if="formData.leaveStatus == '2' && formData.isLeave == '1'" class="card">
<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 class="radio-flex">
<radio :checked="formData.isHome=='是'" :value="'是'" />
</view>
</label>
<label style="margin-left: 80rpx;" class="uni-list-cell uni-list-cell-pd">
<view class="radio-flex">
<radio :checked="formData.isHome=='否'" :value="'否'" />
</view>
</label>
</radio-group>
</view>
<view class="form-item" v-if="formData.homeSubmit == '1'">
<view class="status-flex">
<label>是否到家</label>
<u-tag :text='formData.isHome'></u-tag>
</view>
</view>
<view class="form-item" v-if="formData.isHome == '是'">
<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'" class="card">
<view class="form-item" @tap="showCalendar = true">
<label>预计留校时间 <text style="color: red;">*xxxx年x月x日至xxxx年x月x日</text> </label>
<u-input placeholder="请输入xxxx年x月x日至xxxx年x月x日" v-model="formData.willStayTime"></u-input>
</view>
<view class="form-item">
<label>留校事由</label>
<u--textarea v-model="formData.stayReason" placeholder="请输入留校事由" maxlength="-1"
:autoHeight="true"></u--textarea>
</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>
<!-- 弹窗 -->
<u-picker :show="showDeptPicker" :columns="[moreDeptList.map(item => item.dictValue)]" @confirm="onDeptConfirm"
@cancel="showDeptPicker = false"></u-picker>
<!-- 日期范围 -->
<u-calendar :show="showCalendar" :mode="modeCalendar" @close="showCalendar=false"
@confirm="confirmCalendar"></u-calendar>
</view>
</template>
<script>
import DateTimePicker from "@/components/DateTimePicker.vue";
import {
stuGetRecordBySvId,
stuLeaveApply,
stuHomeUpdate,
} from '@/api/sur';
import {
getWxConfig
} from "@/api/common/wechat";
import {
getDicts
} from "@/api/system/dict/data.js";
import {
isEmpty,
isValidPhone
} from "@/api/helpFunc/index.js";
import * as ww from '@wecom/jssdk'
export default {
components: {
DateTimePicker
},
data() {
return {
isSubmit: '否',
formData: {},
moreDeptList: [],
isEmpty,
covers: [{
latitude: null,
longitude: null,
iconPath: '../../static/images/applyrelieve/location.png'
}],
showDeptPicker: false, //院校选择器
showCalendar: false, //离校日期选择器
modeCalendar: "range",
}
},
computed: {
leaveStatusText() {
const statusMap = {
1: "已提交",
2: "通过",
10: "打回"
};
return statusMap[this.formData.leaveStatus] || "";
}
},
onLoad(params) {
// console.log("StuApply参数", params)
this.formData = params
this.formData.surveyId = Number(this.formData.surveyId); //转换数据类型
if (this.formData.isSubmit == "是") {
this.getstuGetRecordBySvId()
}
this.initWxConfig(); // 初始化微信配置
},
async onShow() {
this.getDicts();
},
methods: {
//获取学院列表
async getDicts() {
let res = await getDicts("more_dept_name");
if (res.code == 200) {
this.moreDeptList = [...res.data];
}
},
//触发返校
toReturn() {
uni.navigateTo({
url: "/pages/sub/StuReturn?id=" + this.formData.returnSchoolId
});
},
//选择学院
onDeptConfirm(e) {
// console.log(e)
this.formData.moreDeptName = e.value[0];
this.showDeptPicker = false;
// console.log(this.formData)
},
//家长是否知晓
radioChange1(evt) {
this.formData.famKnow = evt.detail.value;
this.$forceUpdate();
},
//是否返校
radioChange2(evt) {
this.formData.isHome = evt.detail.value;
this.$forceUpdate();
},
//是否留校
radioChange3(evt) {
this.formData.isLeave = evt.detail.value;
this.$forceUpdate();
},
//预计留校时间
confirmCalendar(e) {
this.formData.willStayTime = e[0] + "至" + e[e.length - 1];
this.showCalendar = false;
this.$forceUpdate();
},
//提交填写
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.stuFdyName)) {
uni.showToast({
title: "请填写辅导员",
icon: "none",
mask: true
});
return;
}
if (!isValidPhone(sdata.phone)) {
uni.showToast({
title: "学生电话格式不正确",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.emergencyContact)) {
uni.showToast({
title: "请输入紧急联系人姓名",
icon: "none",
mask: true
});
return;
}
// 使用示例
if (isEmpty(sdata.emergencyContactPhone)) {
uni.showToast({
title: "请输入紧急联系人电话",
icon: "none",
mask: true
});
return;
}
if (!isValidPhone(sdata.emergencyContactPhone)) {
uni.showToast({
title: "紧急联系人电话格式不正确",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.famName)) {
uni.showToast({
title: "请输入家长姓名",
icon: "none",
mask: true
});
return;
}
// 使用示例
if (isEmpty(sdata.famPhone)) {
uni.showToast({
title: "请输入家长电话",
icon: "none",
mask: true
});
return;
}
if (!isValidPhone(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;
}
}
if (sdata.isLeave == "0") {
if (isEmpty(sdata.willStayTime)) {
uni.showToast({
title: "请填写预计留校时间",
icon: "none",
mask: true
});
return;
}
if (isEmpty(sdata.stayReason)) {
uni.showToast({
title: "请填写留校事由",
icon: "none",
mask: true
});
return;
}
}
// console.log("表单", sdata)
uni.showLoading({
mask: true
});
await stuLeaveApply(sdata).then(res => {
uni.hideLoading();
if (res.code == 200) {
uni.showToast({
title: res.msg,
mask: true
});
//返回上一页
uni.navigateBack({
delta: 1
});
}
});
},
//到家提交
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).then(res => {
uni.hideLoading();
if (res.code == 200) {
uni.showToast({
title: res.msg,
mask: true
});
this.lookV = false;
//返回上一页
uni.navigateBack({
delta: 1
});
}
});
},
//获取已经填写的信息
getstuGetRecordBySvId() {
let that = this;
uni.showLoading({
mask: true
});
stuGetRecordBySvId(that.formData.surveyId).then(res => {
uni.hideLoading();
if (res.code == 200) {
that.formData = {
...res.data
};
that.$forceUpdate();
}
});
},
//关于定位
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'
})
// console.error('Location fail:', err);
}
});
},
}
}
</script>
<style lang="scss">
page {
background-color: #F5F5F7;
/* 设置背景颜色为浅灰色 */
}
.container {
padding: 20rpx;
box-sizing: border-box;
}
.header-btn {
display: flex;
justify-content: end;
.back-school {
display: flex;
justify-content: space-evenly;
align-items: center;
background: #2979ff;
border-radius: 10rpx;
padding: 10rpx;
}
}
.content {
margin-top: 40rpx;
display: flex;
flex-direction: column;
gap: 40rpx;
}
.card-list {
display: flex;
flex-direction: column;
gap: 40rpx;
}
.card {
background-color: white;
padding: 40rpx 20rpx;
border-radius: 20rpx;
display: flex;
flex-direction: column;
gap: 40rpx;
.form-item {
display: flex;
flex-direction: column;
gap: 10rpx;
}
}
.status-flex {
display: flex;
}
.radio-flex {
display: flex;
gap: 20rpx;
align-items: center;
}
</style>