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

525 lines
11 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="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>