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

View File

@@ -0,0 +1,250 @@
<template>
<view class="audit" v-if="detail.student">
<view style="margin: 40rpx;">
<uni-swiper-dot :info="swiperlist" :current="current" :dots-styles="dotStyles" field="content" mode="round">
<swiper interval="2000" autoplay class="swiper-box" @change="change">
<swiper-item v-for="(item ,index) in swiperlist" :key="index">
<view class="swiper-item" @click="previewImg(swiperlist)">
<image mode="aspectFill" :src="item.path">
</image>
</view>
</swiper-item>
</swiper>
</uni-swiper-dot>
</view>
<form @submit="doProcess">
<view class="form-item">
<label><text class="tip">*</text>学院</label>
<input disabled type="text" name="deptName" v-model="detail.student.dept.deptName" />
</view>
<view class="form-item">
<label><text class="tip">*</text>专业</label>
<input disabled type="text" name="majorName" v-model="detail.student.srsMajors.majorName" />
</view>
<view class="form-item">
<label><text class="tip">*</text>班级</label>
<input disabled type="text" name="className" v-model="detail.student.srsClass.className" />
</view>
<view class="form-item">
<label><text class="tip">*</text>加分学生</label>
<input disabled type="text" name="submitterName" v-model="detail.student.name" />
</view>
<view class="form-item">
<label><text class="tip">*</text>项目名称</label>
<input disabled type="text" name="ruleName" v-model="detail.rules.ruleName" />
</view>
<view class="form-item">
<label><text class="tip">*</text>描述</label>
<input disabled type="text" name="description" v-model="detail.description" />
</view>
<view class="form-item">
<label><text class="tip">*</text>是否通过</label>
<view class="uni-px-5 uni-pb-5">
<uni-data-checkbox v-model="valiFormData.statusCode" :localdata="statelist"></uni-data-checkbox>
</view>
</view>
<view v-if="valiFormData.statusCode!=6" class="form-item">
<label><text class="tip">*</text>未通过理由</label>
<input type="text" v-model="valiFormData.description" />
</view>
<view class="btns">
<button form-type="submit" :disabled="isSubmitting">确定</button>
</view>
</form>
</view>
</template>
<script>
import {
uploadImg,
previewImg,
removeImg
} from "@/utils/uploadImg.js"
import {
myReview,
listOwnProcessed,
getDetailInfo,process
} from '@/api/comprehensive/instructor.js';
import {
baseUrl
} from "@/config.js";
import {
validateFormFields
} from "@/utils/validateForm.js"
export default {
data() {
return {
valiFormData: {
statusCode: 6,
description:''
},
id: '',
detail: {},
isSubmitting: false, //表单提交标志位
swiperlist: [],
baseUrl: baseUrl,
current: 0,
dotStyles: {
width: 12,
backgroundColor: 'rgba(255, 255, 255, 0.4)',
border: '1px rgba(255, 255, 255, 0.4) solid',
color: '#fff',
selectedBackgroundColor: '#1890FF',
selectedBorder: '1px #1890FF solid'
},
statelist: [{
text: '驳回',
value: 10
}, {
text: '通过',
value: 6
}, {
text: '拒绝',
value: 11
}],
processForm:{}
}
},
onLoad(option) {
var arr = JSON.parse(option.item)
this.processForm = arr
this.id = arr.id
this.getDetail()
},
methods: {
change(e) {
this.current = e.detail.current;
},
async getDetail() {
let res = await getDetailInfo(this.id)
if (res.code == 200) {
this.detail = res.data
var arr = res.data.material.split(",")
for (var i = 0; i < arr.length; i++) {
var obj = {}
obj.path=baseUrl+arr[i]
this.swiperlist.push(obj)
}
}
},
previewImg(imgs) {
previewImg(imgs);
},
//审核
async doProcess(e) {
const requiredFields = [
];
if(this.valiFormData.statusCode==6){
requiredFields.push('statusCode')
}else{
requiredFields.push('statusCode')
requiredFields.push('description')
}
if (!validateFormFields(requiredFields, this.valiFormData)) {
return;
}
let sdata = { ...this.processForm };
sdata.statusCode=this.valiFormData.statusCode
sdata.remarks = this.valiFormData.description
console.log(sdata)
uni.showLoading({
title: "正在提交",
success: () => {
process(sdata).then(res => {
if (res.code == 200) {
uni.showToast({
title: "审核成功"
})
this.isSubmitting = false;
uni.navigateBack();
}
})
}
})
},
}
}
</script>
<style lang="scss" scoped>
.audit {
background-color: #F5F5F7;
padding: 10px;
padding-bottom: 80px;
// height: 98vh;
.swiper-box {
width: 100%;
height: 600rpx;
border-radius: 16rpx;
.swiper-item {
border-radius: 16rpx;
height: 600rpx;
image {
width: 100%;
height: 600rpx;
border-radius: 16rpx;
}
}
}
.form-item {
display: flex;
flex-direction: column;
padding: 22rpx 40rpx;
background-color: white;
margin-bottom: 20rpx;
border-radius: 16rpx;
.tip {
color: red;
font-size: 24rpx;
}
label {
margin-bottom: 20rpx;
display: inline-block;
}
input {
border: 1px solid #E1E1E1;
border-radius: 10rpx;
height: 70rpx;
padding-left: 30rpx;
.input-placeholder {
color: #b6b6b6;
}
}
}
.btns {
padding: 10px;
display: flex;
// background: white;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
button {
flex: 1;
background-color: #1890FF;
color: white;
&[disabled] {
opacity: 0.5;
}
}
}
}
</style>

View File

@@ -0,0 +1,196 @@
<template>
<view class="audit" v-if="detail.student">
<view style="margin: 40rpx;">
<uni-swiper-dot :info="swiperlist" :current="current" :dots-styles="dotStyles" field="content" mode="round">
<swiper interval="2000" autoplay class="swiper-box" @change="change">
<swiper-item v-for="(item ,index) in swiperlist" :key="index">
<view class="swiper-item" @click="previewImg(swiperlist)">
<image mode="aspectFill" :src="item.path">
</image>
</view>
</swiper-item>
</swiper>
</uni-swiper-dot>
</view>
<form>
<view class="form-item">
<label><text class="tip">*</text>学院</label>
<input disabled type="text" name="deptName" v-model="detail.student.dept.deptName" />
</view>
<view class="form-item">
<label><text class="tip">*</text>专业</label>
<input disabled type="text" name="majorName" v-model="detail.student.srsMajors.majorName" />
</view>
<view class="form-item">
<label><text class="tip">*</text>班级</label>
<input disabled type="text" name="className" v-model="detail.student.srsClass.className" />
</view>
<view class="form-item">
<label><text class="tip">*</text>加分学生</label>
<input disabled type="text" name="submitterName" v-model="detail.student.name" />
</view>
<view class="form-item">
<label><text class="tip">*</text>项目名称</label>
<input disabled type="text" name="ruleName" v-model="detail.rules.ruleName" />
</view>
<view class="form-item">
<label><text class="tip">*</text>描述</label>
<input disabled type="text" name="description" v-model="detail.description" />
</view>
<!-- <view class="form-item">
<label><text class="tip">*</text>是否通过</label>
<view class="uni-px-5 uni-pb-5">
<uni-data-checkbox v-model="valiFormData.statusCode" :localdata="statelist"></uni-data-checkbox>
</view>
</view> -->
<!-- <view v-if="valiFormData.statusCode!=6" class="form-item">
<label><text class="tip">*</text>未通过理由</label>
<input type="text" v-model="valiFormData.description" />
</view> -->
<!-- <view class="btns">
<button form-type="submit" :disabled="isSubmitting">确定</button>
</view> -->
</form>
</view>
</template>
<script>
import {
uploadImg,
previewImg,
removeImg
} from "@/utils/uploadImg.js"
import {
myReview,
listOwnProcessed,
getDetailInfo,process
} from '@/api/comprehensive/instructor.js';
import {
baseUrl
} from "@/config.js";
import {
validateFormFields
} from "@/utils/validateForm.js"
export default {
data() {
return {
valiFormData: {
statusCode: 6,
description:''
},
id: '',
detail: {},
isSubmitting: false, //表单提交标志位
swiperlist: [],
baseUrl: baseUrl,
current: 0,
dotStyles: {
width: 12,
backgroundColor: 'rgba(255, 255, 255, 0.4)',
border: '1px rgba(255, 255, 255, 0.4) solid',
color: '#fff',
selectedBackgroundColor: '#1890FF',
selectedBorder: '1px #1890FF solid'
},
// statelist: [{
// text: '驳回',
// value: 10
// }, {
// text: '通过',
// value: 6
// }, {
// text: '拒绝',
// value: 11
// }],
// processForm:{}
}
},
onLoad(option) {
var arr = JSON.parse(option.item)
// this.processForm = arr
this.id = arr.id
this.getDetail()
},
methods: {
change(e) {
this.current = e.detail.current;
},
async getDetail() {
let res = await getDetailInfo(this.id)
if (res.code == 200) {
this.detail = res.data
var arr = res.data.material.split(",")
for (var i = 0; i < arr.length; i++) {
var obj = {}
obj.path=baseUrl+arr[i]
this.swiperlist.push(obj)
}
}
console.log(res)
},
previewImg(imgs) {
previewImg(imgs);
},
}
}
</script>
<style lang="scss" scoped>
.audit {
background-color: #F5F5F7;
padding: 10px;
padding-bottom: 80px;
// height: 98vh;
.swiper-box {
width: 100%;
height: 600rpx;
border-radius: 16rpx;
.swiper-item {
border-radius: 16rpx;
height: 600rpx;
image {
width: 100%;
height: 600rpx;
border-radius: 16rpx;
}
}
}
.form-item {
display: flex;
flex-direction: column;
padding: 22rpx 40rpx;
background-color: white;
margin-bottom: 20rpx;
border-radius: 16rpx;
.tip {
color: red;
font-size: 24rpx;
}
label {
margin-bottom: 20rpx;
display: inline-block;
}
input {
border: 1px solid #E1E1E1;
border-radius: 10rpx;
height: 70rpx;
padding-left: 30rpx;
.input-placeholder {
color: #b6b6b6;
}
}
}
}
</style>

View File

@@ -0,0 +1,289 @@
<template>
<view class="index">
<Nav :navs="navs" :loading="loading" @change="navChange" />
<scroll-view scroll-y="true" @scrolltolower="scrolltolower">
<view class="list">
<view class="item" @tap="toDetail(item)" v-for="(item,index) in auditDetailsList" :key="index">
<view class="top">
<view>
姓名:{{item.submitterName?item.submitterName:item.stuName}}
</view>
<view style="background-color: aqua;">
<DictStatus :types="audius_detail_type" :type="item.statusCode?item.statusCode:item.auditStatus" />
</view>
<!-- <DictType :types="rt_penalty_status" :type="item.penaltyStatus" /> -->
<!-- <uni-icons type="right" size="18" color="#202020"></uni-icons> -->
</view>
<view class="content">
<view v-show="Toggleindex==1">项目大类{{item.projectName}}</view>
<view v-show="Toggleindex==1">项目子类{{item.ruleName}}</view>
<view v-show="Toggleindex==1">分数:{{item.operateScore > 0 ? "+" + item.operateScore.toString() : item.operateScore}}</view>
<view>班级{{item.className}}</view>
<view>学号{{item.stuNo}}</view>
<view>项目名称{{item.projectName}}</view>
<!-- <view>分数{{item.operateScore > 0 ? "+" + item.operateScore.toString() : item.operateScore}}</view> -->
<view>提交时间{{item.createTime?item.createTime:item.submitTime}}</view>
</view>
</view>
</view>
<view class="empty" v-if="auditDetailsList.length==0&&topLoading==false">
<image src="@/static/empty.png" mode="widthFix"></image>
暂时没有数据
</view>
<view class="loading-more-top" v-if="topLoading">
<uni-load-more style="padding-top: 90px;" status="loading" />
</view>
<view class="loading-more" v-if="loading">
<uni-load-more status="loading" />
</view>
<view class="no-more" v-if="!loading&&auditDetailsList.length!=0">
到底啦~~
</view>
</scroll-view>
</view>
</template>
<script>
import {
getDicts,
} from '@/api/system/dict/data.js';
import {
myReview,listOwnProcessed
} from '@/api/comprehensive/instructor.js';
import Nav from "@/components/navs/navs.vue"
import DictStatus from "@/components/comprehensive-dict-type/dict-type.vue"
export default {
components: {
Nav,
DictStatus
},
data() {
return {
navs: [{
text: "待办",
val: ""
},
{
text: "已处理",
val: "0"
}
],
audius_detail_type: [],
queryParams: {
pageNum: 1,
pageSize: 10,
projectName: null,
submitterId: null,
submitterName: null,
reviewedById: null,
projectId: null,
projectTypeId: null,
statusCode: null,
remarks: null
},
auditDetailsList:[],
loading: false,
topLoading: true,
Toggleindex:2
}
},
onShow() {
if(this.Toggleindex==2){
this.getList()
}else{
this.getOwnProcessedList()
}
// this.getList();
this.get_audius_detail_type();
},
methods: {
toDetail(item){
if(this.Toggleindex==2){
uni.navigateTo({
url:`./audit?item=`+JSON.stringify(item)
})
}else{
uni.navigateTo({
url:`./detail?item=`+JSON.stringify(item)
})
}
},
navChange(newVal,oldVal) {
if (this.loading) return;
if(newVal.indexOf(0)!=-1){
this.Toggleindex=1
this.queryParams.pageNum = 1
this.auditDetailsList=[]
this.getOwnProcessedList()
}else{
this.Toggleindex=2
this.queryParams.pageNum = 1
this.auditDetailsList=[]
this.getList()
}
},
scrolltolower() {
if (this.queryParams.pageNum < this.totalPages) {
this.queryParams.pageNum++;
this.loading = true;
if(this.Toggleindex==1){
setTimeout(() => {
this.getOwnProcessedList()
}, 1000)
}else{
setTimeout(() => {
this.getList()
}, 1000)
}
} else {
}
},
async get_audius_detail_type() {
let res = await getDicts('audius_detail_type');
this.audius_detail_type = res.data;
},
async getList() {
let res = await myReview(this.queryParams);
if (res.code == 200) {
this.loading = false;
if (this.queryParams.pageNum == 1) {
this.auditDetailsList=[]
this.auditDetailsList = res.rows; // 如果是第一页,直接显示新数据
} else {
this.auditDetailsList = this.auditDetailsList.concat(res.rows); // 否则追加新数据到列表中
}
this.totalPages = Math.ceil(res.total / this.queryParams.pageSize);
this.topLoading = false;
}
},
async getOwnProcessedList() {
let res = await listOwnProcessed(this.queryParams);
if (res.code == 200) {
this.loading = false;
if (this.queryParams.pageNum == 1) {
this.auditDetailsList=[]
this.auditDetailsList = res.rows; // 如果是第一页,直接显示新数据
} else {
this.auditDetailsList = this.auditDetailsList.concat(res.rows); // 否则追加新数据到列表中
}
this.totalPages = Math.ceil(res.total / this.queryParams.pageSize);
this.topLoading = false;
}
},
}
}
</script>
<style lang="scss" scoped>
.index{
background-color: #F5F5F7;
scroll-view {
height: calc(100vh - 10px);
padding-top:100rpx;
.list {
padding: 20rpx 40rpx 15rpx 40rpx;
.item {
background-color: white;
margin-bottom: 20rpx;
padding: 40rpx;
border-radius:16px;
border-bottom-right-radius: 0;
position: relative;
.top {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #F5F5F7;
padding-bottom: 20rpx;
.uni-icons {
opacity: 0.5;
}
}
.content {
padding-top: 20rpx;
&>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;
}
}
}
}
}
}
.no-more {
text-align: center;
color: gray;
padding-bottom: 10px;
}
.empty{
display: flex;
flex-direction: column;
align-items: center;
margin-top: 200rpx;
color: #9E9E9E;
font-size: 36rpx;
image{
width: 250rpx;
margin-bottom: 50rpx;
}
}
}
}
</style>