移动端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

524
pages/workStudy/add.vue Normal file
View File

@@ -0,0 +1,524 @@
<template>
<view class="work-add">
<view class="form-item tip">
<text>注意每周不超过8小时每月不超过40小时</text>
<text>本月已填报{{ monthTime }}小时(不含拒绝)</text>
</view>
<view class="form-item">
<label><text>*</text> 工作岗位</label>
<input @focus="onFocus" type="text" placeholder="请选择岗位" v-model="stuPostName" />
</view>
<view class="form-item">
<label><text>*</text> 工作日期</label>
<picker @change="onChangeTime" mode="date" :value="formData.workDate">
<view class="uni-input">
<text class="val">{{formData.workDate==''?'请选择日期':formData.workDate}}</text>
<uni-icons type="calendar" size="25" color="#202020"></uni-icons>
</view>
</picker>
</view>
<view class="form-item">
<label><text>*</text> 工作时长(单位:小时)</label>
<input type="number" placeholder="请输入" v-model="formData.workTime" />
</view>
<view class="form-item">
<label><text>*</text>主要工作</label>
<textarea type="text" placeholder="请输入" v-model="formData.mainWork" />
</view>
<view class="form-item">
<label><text>*</text>工作附件</label>
<view class="upload-img" v-if="tempImgs.length==0" @tap="uploadImg">
<view class="add">
+ 上传
</view>
<view class="tip">
要求格式为png/jpg/jpeg的文件 大小不超过0.5M
</view>
<view class="img-list">
</view>
</view>
<view class="img-list" v-else>
<view class="imgs">
<view class="img" v-for="(img,index) in tempImgs">
<image @tap="previewImg(tempImgs)" :src="img.path" mode="aspectFill"></image>
<text class="remove" @tap="onRemoveImg(index,img.path)">X</text>
</view>
</view>
<view v-if="tempImgs.length<3" class="btn" @tap="uploadImg">
+ 添加
</view>
</view>
</view>
<view class="btns">
<button v-if="monthTime>40" :disabled="true">本月填报已超40小时</button>
<button :disabled="isSubmitting" @click="onSubmit" v-else>提交</button>
</view>
<uni-popup class="popup return-dialog" ref="postDialog" type="dialog" background-color="#fff">
<view class="popup-content">
<view class="title">
请选择工作岗位
</view>
<view class="content">
<view class="list" v-if="postList.length>0">
<view class="row">
<text>序号</text>
<text>部门</text>
<text>岗位名称</text>
</view>
<view :class="index==postIndex?'active':''" class="row" @tap="postChange(index,item)"
v-for="(item,index) in postList" :key="item.id">
<text>{{index+1}}</text>
<text>{{item.stuDept}}</text>
<text>{{item.postName}}</text>
</view>
</view>
<view v-else style="text-align: center;margin-top:25px;">
暂无岗位
</view>
</view>
<view class="btns">
<button type="default" @tap="onCancel">取消</button>
<button type="primary" @tap="onConfirm">确定</button>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import {
uploadImg,
previewImg,
removeImg
} from "@/utils/uploadImg.js"
import uploadFile from "@/plugins/upload.js";
import {
checkPic
} from "@/utils/checkPic.js";
import {
baseUrl
} from "@/config.js";
import {
doApply,
computeTimeByStuNo,
listOwnCanSelectPost
} from '@/api/workStudy/workStudy'
export default {
data() {
return {
isSubmitting: false,
tempImgs: [],
stuPostName: "",
formData: {
stuPostId: "",
workDate: "",
workTime: "",
mainWork: "",
workMaterial: "",
},
monthTime: 0,
postList: [], //岗位列表
postIndex: -1, //岗位索引
}
},
onLoad() {
this.computeTimeByStuNo()
},
methods: {
onFocus() {
this.$refs.postDialog.open();
// let selectParams.params = { fuzzyQueryCode: true };
//{reasonable:true,params[fuzzyQueryCode]:true}
let query = {
pageNum: 1,
pageSize: 10,
reasonable: true,
params: {
fuzzyQueryCode: true
}
}
listOwnCanSelectPost(query).then(res => {
this.postList = res.rows;
})
},
postChange(index, item) {
this.postIndex = index;
this.tempItem = item;
},
onConfirm() {
if (this.tempItem) {
this.formData.stuPostId = this.tempItem.id;
this.stuPostName = this.tempItem.postName;
}
this.$refs.postDialog.close();
},
onCancel() {
this.$refs.postDialog.close();
},
dialogConfirm() {
this.$refs.postDialog.close();
},
onChangeTime(e) {
this.formData.workDate = e.detail.value;
},
async computeTimeByStuNo() {
let res = await computeTimeByStuNo();
if (res.code == 200) {
if (res.data) {
this.monthTime = res.data.workTime;
}
}
},
async onSubmit() {
const requiredFields = [
'stuPostId',
'workDate',
'workTime',
'mainWork',
'workMaterial',
];
const emptyField = requiredFields.find(field => this.formData[field] === "");
if (emptyField) {
uni.showToast({
title: `请填写完 * 必填内容`,
icon: "none"
})
return;
}
this.isSubmitting = true; // 设置为正在提交
uni.showLoading({
title: "正在提交",
success: async () => {
try {
let res = await doApply(this.formData);
if (res.code == 200) {
uni.showToast({
title: "提交成功"
});
setTimeout(() => {
uni.navigateBack({
success: () => {
const pages = getCurrentPages();
if (pages.length > 0) {
const prevPage = pages[pages.length -
2]
console.log(prevPage);
if (prevPage && typeof prevPage
.getList ===
'function') {
prevPage.queryParams.pageNum = 1;
prevPage.getList();
}
}
}
})
}, 1000)
}
} catch (error) {} finally {
this.isSubmitting = false;
}
}
})
},
uploadImg() {
uni.chooseImage({
count: 3,
success: async (img) => {
let bool = await checkPic(img.tempFiles[0]);
if (bool) {
uploadFile('/common/upload', img.tempFilePaths[0]).then((res) => {
if (this.formData.workMaterial !== "") {
this.formData.workMaterial = this.formData.workMaterial + "," +
JSON.parse(res)
.fileName;
} else {
this.formData.workMaterial = JSON.parse(res).fileName;
}
this.tempImgs.push({
path: baseUrl + JSON.parse(res).fileName
});
})
}
}
})
},
onRemoveImg(index, path) {
this.tempImgs.splice(index, 1);
let newImgs = this.tempImgs.filter(fileName => fileName.path !== path);
newImgs = newImgs.map(img => img.path.replace(baseUrl, ''))
newImgs = newImgs.join(",");
this.formData.workMaterial = newImgs;
},
previewImg(imgs) {
previewImg(imgs);
}
}
}
</script>
<style lang="scss" scoped>
.work-add {
background-color: #F5F5F7;
padding: 10px;
padding-bottom: 80px;
.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;
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;
}
}
}
.upload-img {
border: 1px solid #E1E1E1;
padding: 20rpx;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
.tip {
margin-top: 15rpx;
color: #7a7a7a;
font-size: 24rpx;
}
}
.img-list {
border: 1px solid #D8D8D8;
border-radius: 20rpx;
.imgs {
padding: 22rpx;
display: flex;
flex-wrap: wrap;
.img {
position: relative;
width: 160rpx;
height: 170rpx;
margin-bottom: 15rpx;
margin-right: 15rpx;
image {
width: 100%;
height: 100%;
}
.remove {
position: absolute;
right: 0;
top: 0;
color: white;
background-color: rgba(0, 0, 0, 0.4);
width: 52rpx;
height: 52rpx;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
}
}
}
.btn {
border-top: 1px solid #D8D8D8;
height: 100rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
}
}
}
&>.btns {
padding: 10px;
display: flex;
background: white;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
// uni-button[disabled] {
// }
button {
flex: 1;
background-color: #1890FF;
color: white;
&[disabled] {
opacity: 0.5;
}
}
}
.popup {
.popup-content {
width: 90vw;
max-height: 86vh;
overflow: scroll;
.title {
font-size: 40rpx;
font-weight: bold;
text-align: center;
margin: 20rpx 0;
}
.content {
padding: 0 40rpx;
.list {
.row {
height: 80rpx;
line-height: 80rpx;
display: flex;
text {
text-align: center;
}
&.active {
background-color: #0092FF;
color: white;
}
&:first-child {
font-weight: bold;
}
text:nth-child(1) {
width: 100rpx;
}
text:nth-child(2) {
flex: 1;
}
text:nth-child(3) {
flex: 1;
}
}
}
}
.btns {
display: flex;
margin-top: 80rpx;
button {
flex: 1;
border-radius: 0;
border-bottom: 0;
&:first-child {
background-color: transparent;
border: 1px solid #4097FE;
border-bottom: 0;
color: #4097FE;
}
}
}
}
}
.return-dialog {
.form-item {
label {
font-weight: bold;
display: inline-block;
margin-bottom: 10px;
}
&:last-child {
margin-top: 15px;
}
.list {
height: auto;
max-height: 200px;
display: flex;
flex-wrap: wrap;
.item {
width: 100%;
height: 40px;
line-height: 40px;
text-align: center;
&.active {
background-color: #0092FF;
color: white;
}
}
}
}
}
}
</style>