级位审核
Showing
4 changed files
with
1077 additions
and
351 deletions
| 1 | <template> | 1 | <template> |
| 2 | <view> | 2 | <view class="add-apply-page"> |
| 3 | <view class="pd30"> | 3 | <!-- 顶部步骤条 --> |
| 4 | <uni-steps :options="list1" :active="active" /> | 4 | <view class="steps-bar"> |
| 5 | <view class="hasfixedbottom"> | 5 | <view class="step-item" :class="{ active: active >= 0, current: active == 0 }"> |
| 6 | <view class="step-circle">1</view> | ||
| 7 | <view class="step-text">考级基本信息</view> | ||
| 8 | </view> | ||
| 9 | <view class="step-line" :class="{ active: active >= 1 }"></view> | ||
| 10 | <view class="step-item" :class="{ active: active >= 1, current: active == 1 }"> | ||
| 11 | <view class="step-circle">2</view> | ||
| 12 | <view class="step-text">添加考生</view> | ||
| 13 | </view> | ||
| 14 | </view> | ||
| 15 | |||
| 16 | <view class="page-content"> | ||
| 17 | <!-- 步骤1:考级基本信息 --> | ||
| 6 | <view class="wBox" v-if="active == 0"> | 18 | <view class="wBox" v-if="active == 0"> |
| 7 | <uni-forms ref="baseForm" :modelValue="form" label-width="100"> | 19 | <uni-forms ref="baseForm" :modelValue="form" label-width="100"> |
| 8 | <uni-forms-item label="考试名称"> | 20 | <uni-forms-item label="考试名称"> |
| ... | @@ -24,182 +36,148 @@ | ... | @@ -24,182 +36,148 @@ |
| 24 | <uni-forms-item label="考级地点" required> | 36 | <uni-forms-item label="考级地点" required> |
| 25 | <uni-easyinput v-model="form.examLocation" placeholder="考级地点" /> | 37 | <uni-easyinput v-model="form.examLocation" placeholder="考级地点" /> |
| 26 | </uni-forms-item> | 38 | </uni-forms-item> |
| 27 | <uni-forms-item @updateData="updateData" :label="`考官${ec}`" v-for="ec in examinerForChoose" | 39 | <uni-forms-item :label="`考官${ec}`" v-for="ec in examinerForChoose" :key="ec"> |
| 28 | :key="ec"> | ||
| 29 | <view class="maskbox"> | 40 | <view class="maskbox"> |
| 30 | <view class="mask" @click="selectFN(ec)"></view> | 41 | <view class="mask" @click="selectFN(ec)"></view> |
| 31 | <uni-easyinput v-model="form[`examiner_${ec}`]" clearable placeholder="点击选择考官" /> | 42 | <uni-easyinput v-model="form[`examiner_${ec}`]" clearable placeholder="点击选择考官" /> |
| 32 | </view> | 43 | </view> |
| 33 | </uni-forms-item> | 44 | </uni-forms-item> |
| 34 | |||
| 35 | </uni-forms> | 45 | </uni-forms> |
| 36 | |||
| 37 | </view> | ||
| 38 | <view class="wBox" v-if="active == 1"> | ||
| 39 | <!-- 添加考生 --> | ||
| 40 | <view class="flexbox"> | ||
| 41 | <button class="btn-red-kx mini w100" @click="chooseOnline"> | ||
| 42 | <uni-icons type="personadd" size="16" color="#AD181F"></uni-icons> | ||
| 43 | 在线选择</button> | ||
| 44 | <!-- <button class="btn-red-kx mini w45" @click="handleUpdate"> | ||
| 45 | <uni-icons type="upload" size="16" color="#AD181F"></uni-icons> | ||
| 46 | 上传成绩单</button> --> | ||
| 47 | </view> | 46 | </view> |
| 48 | <view class="vipData mt30" style="flex-wrap:wrap"> | 47 | |
| 49 | <view class="w25">合计:<text>{{tablePersonInfo.total}}</text>人</view> | 48 | <!-- 步骤2:添加考生 --> |
| 50 | <view class="w25" v-for="l in tablePersonInfo.levelArr" :key="l.level"> | 49 | <view class="step2-content" v-if="active == 1"> |
| 51 | {{ szToHz(l.level) }}级:<text>{{l.num}}</text>人 | 50 | <!-- 考级信息卡片 --> |
| 51 | <view class="exam-info-card"> | ||
| 52 | <view class="card-header"> | ||
| 53 | <text class="card-title">考级信息</text> | ||
| 52 | </view> | 54 | </view> |
| 55 | <view class="info-grid"> | ||
| 56 | <view class="info-item"> | ||
| 57 | <text class="info-label">考试名称</text> | ||
| 58 | <text class="info-value">{{form.name || '-'}}</text> | ||
| 53 | </view> | 59 | </view> |
| 54 | <view class="userlist"> | 60 | <view class="info-item"> |
| 55 | <view class="item" v-for="(n,index) in infoList" :key="index" | 61 | <text class="info-label">申请单位</text> |
| 56 | style="background-color: #fffafa;"> | 62 | <text class="info-value">{{form.memberName || '-'}}</text> |
| 57 | <view class="w100"> | ||
| 58 | <view class="del" @click="handleDelete(n)">删除</view> | ||
| 59 | <view style="display: flex;"> | ||
| 60 | <!-- | ||
| 61 | <view class="photobox"> | ||
| 62 | <image class="photo" v-if="n.photo" :src="n.photo" mode='aspectFill'></image> | ||
| 63 | <view class="colorful" v-else>{{n.realName?.slice(0,1)}}</view> | ||
| 64 | </view> --> | ||
| 65 | <view> | ||
| 66 | <view class="name">{{n.realName}} <text>{{n.perCode}}</text></view> | ||
| 67 | <view class="date">{{n.idcTypeStr}}:{{n.idcCode}}</view> | ||
| 68 | </view> | 63 | </view> |
| 64 | <view class="info-item"> | ||
| 65 | <text class="info-label">考试地点</text> | ||
| 66 | <text class="info-value">{{form.examLocation || '-'}}</text> | ||
| 69 | </view> | 67 | </view> |
| 70 | <view class="flexbox mt30"> | 68 | <view class="info-item"> |
| 71 | <view> | 69 | <text class="info-label">考试时间</text> |
| 72 | 原有级别 | 70 | <text class="info-value">{{formatDateTime(form.startTime)}} - {{formatDateTime(form.endTime)}}</text> |
| 73 | <text style="padding: 15rpx 0;">{{ szToHz(n.levelOld) }}级</text> | ||
| 74 | </view> | 71 | </view> |
| 75 | <view style="width: 40%;"> | ||
| 76 | 考试级别 | ||
| 77 | <!-- <text style="padding: 15rpx 0;">{{ szToHz(n.levelNew) }}级</text> --> | ||
| 78 | <view @click="changeLevelfather(n)"> | ||
| 79 | <uni-data-select v-model="n.levelNew" :localdata="levelArr" | ||
| 80 | @change="changeLevel"></uni-data-select> | ||
| 81 | </view> | 72 | </view> |
| 82 | |||
| 83 | </view> | 73 | </view> |
| 84 | 74 | ||
| 85 | <view style="width: 30%;"> | 75 | <!-- 操作栏(红框顶部统计+添加按钮) --> |
| 86 | 是否通过 | 76 | <button class="btn-add-student" @click="goChooseStudent"> |
| 87 | <view> | 77 | <uni-icons type="plus" size="16" color="#fff"></uni-icons> |
| 88 | <uni-data-select :clear="false" v-model="n.isPass" | 78 | 添加考生 |
| 89 | :localdata="range"></uni-data-select> | 79 | </button> |
| 90 | </view> | 80 | <view class="action-bar"> |
| 81 | <view class="stat-info"> | ||
| 82 | <text class="stat-total">共 {{tablePersonInfo.total || 0}} 人</text> | ||
| 83 | <view class="level-tags"> | ||
| 84 | <view class="level-tag" v-for="l in tablePersonInfo.levelArr" :key="l.level"> | ||
| 85 | {{ szToHz(l.level) }}级:{{l.num}}人 | ||
| 91 | </view> | 86 | </view> |
| 92 | </view> | 87 | </view> |
| 93 | </view> | 88 | </view> |
| 94 | 89 | ||
| 95 | </view> | 90 | </view> |
| 96 | <view class="nodata" v-if="infoList.length==0"> | 91 | |
| 97 | <image mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image> | 92 | <!-- 考生列表(红框主体) --> |
| 98 | <text>待添加考生</text> | 93 | <view class="student-list"> |
| 94 | <view class="student-card" v-for="(n,index) in infoList" :key="index"> | ||
| 95 | <!-- 左侧:头像+考生信息 --> | ||
| 96 | <view class="card-left"> | ||
| 97 | <view class="avatar"> | ||
| 98 | <image v-if="n.photo" :src="n.photo" mode="aspectFill" /> | ||
| 99 | <image v-else :src="config.baseUrl_api + '/fs/static/tx@2x.png'" | ||
| 100 | mode="aspectFill"> | ||
| 101 | </image> | ||
| 102 | <!-- <text v-else class="avatar-text">{{(n.realName || '').slice(0,1)}}</text> --> | ||
| 99 | </view> | 103 | </view> |
| 104 | <view class="student-info"> | ||
| 105 | <view class="student-name">{{n.realName}} <text class="per-code">{{n.perCode}}</text></view> | ||
| 106 | <view class="student-idcard">{{n.idcTypeStr}}:{{n.idcCode}}</view> | ||
| 100 | </view> | 107 | </view> |
| 101 | </view> | 108 | </view> |
| 109 | |||
| 110 | <!-- 右侧:原级别/考试级别/是否通过 --> | ||
| 111 | <view class="card-right"> | ||
| 112 | <view class="level-item"> | ||
| 113 | <text class="level-label">原级别</text> | ||
| 114 | <text class="level-value">{{ szToHz(n.levelOld) }}级</text> | ||
| 102 | </view> | 115 | </view> |
| 116 | <view class="level-item"> | ||
| 117 | <text class="level-label">考试级别</text> | ||
| 118 | <view class="select-wrapper" @click="changeLevelfather(n)"> | ||
| 119 | <uni-data-select v-model="n.levelNew" :localdata="levelArr" @change="changeLevel" :clear="false" /> | ||
| 103 | </view> | 120 | </view> |
| 104 | <view class="fixedBottom" v-if="active == 0"> | ||
| 105 | <button class="btn-red-kx" style="width: 40%;" @click="submitForm(0)">保存</button> | ||
| 106 | <button class="btn-red" style="width: 40%;" @click="submitForm(1)">下一步</button> | ||
| 107 | </view> | 121 | </view> |
| 108 | <view class="fixedBottom" v-if="active == 1"> | 122 | <view class="level-item"> |
| 109 | <button class="btn-red-kx" style="width: 25%;" @click="active=0">上一步</button> | 123 | <text class="level-label">是否通过</text> |
| 110 | <button class="btn-red-kx" style="width: 25%;" @click="submitForm2(0)">保存</button> | 124 | <view class="select-wrapper"> |
| 111 | <button class="btn-red" style="width: 30%;" @click="submitForm2(1)">提交审核</button> | 125 | <uni-data-select v-model="n.isPass" :localdata="range" :clear="false" /> |
| 112 | </view> | 126 | </view> |
| 113 | |||
| 114 | |||
| 115 | <uni-popup ref="choseStudent" type="bottom" background-color="#fff" animation> | ||
| 116 | <view class="popBody"> | ||
| 117 | <view class="searchbar"> | ||
| 118 | <uni-easyinput placeholderStyle="font-size:30rpx" :input-border="false" prefixIcon="search" | ||
| 119 | v-model="studentQuery.name" placeholder="搜索姓名" @blur="chooseOnline" @clear="chooseOnline"> | ||
| 120 | </uni-easyinput> | ||
| 121 | </view> | 127 | </view> |
| 122 | <view class="userlist" style="height:80vh;overflow: auto;"> | ||
| 123 | <view class="item" v-for=" (n,index) in studentList" :key="index"> | ||
| 124 | <view @click="checkThis(n)"> | ||
| 125 | <image class="icon" v-if="n.checked" | ||
| 126 | :src="config.baseUrl_api+'/fs/static/member/dx_dwn.png'" /> | ||
| 127 | <image class="icon" v-else :src="config.baseUrl_api+'/fs/static/member/dx.png'" /> | ||
| 128 | </view> | 128 | </view> |
| 129 | <view class="photobox"> | 129 | |
| 130 | <image class="photo" v-if="n.photo" :src="n.photo" mode='aspectFill'> | 130 | <!-- 删除按钮 --> |
| 131 | </image> | 131 | <view class="delete-btn" @click="handleDelete(n)"> |
| 132 | <view class="colorful" v-else>{{n.name.slice(0,1)}}</view> | 132 | <uni-icons type="trash" size="18" color="#dd524d"></uni-icons> |
| 133 | </view> | 133 | </view> |
| 134 | <view> | ||
| 135 | <view class="name">{{n.name}} <text>{{n.perCode}}</text></view> | ||
| 136 | <view class="date">到期时间:{{n.validityDate}}</view> | ||
| 137 | <view class="date" style="color: #1561CB;" v-if="n.levelJi&&n.levelJi!=0"> | ||
| 138 | 级位:{{szToHz(n.levelJi)}}级</view> | ||
| 139 | <view class="date" v-else>级位:十级</view> | ||
| 140 | </view> | 134 | </view> |
| 135 | |||
| 136 | <!-- 空状态 --> | ||
| 137 | <view class="empty" v-if="infoList.length==0"> | ||
| 138 | <image class="empty-img" mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'" /> | ||
| 139 | <text class="empty-text">暂无考生信息</text> | ||
| 141 | </view> | 140 | </view> |
| 142 | <view class="nodata" v-if="studentList.length==0"> | ||
| 143 | <image mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image> | ||
| 144 | <text>无可参加考试会员</text> | ||
| 145 | </view> | 141 | </view> |
| 146 | </view> | 142 | </view> |
| 147 | <button class="btn-red-kx" v-if="studentList.length!=0" @click="submitStudents">确定</button> | ||
| 148 | </view> | 143 | </view> |
| 149 | </uni-popup> | ||
| 150 | |||
| 151 | <uni-popup ref="UpPop" type="bottom" background-color="#fff" animation> | ||
| 152 | <view class="popBody"> | ||
| 153 | <view class="h3 text-center">上传成绩单</view> | ||
| 154 | <text class="must">*请上传大小不超过 10MB 格式为 png/jpg/jpeg/pdf/zip 的文件</text> | ||
| 155 | <uni-file-picker v-model="transcript" class="mtb30" file-mediatype="all" | ||
| 156 | file-extname="png,jpg,jpeg,pdf,zip" @select="selectFile" @progress="fileProgress" | ||
| 157 | @delete="delSupplementFile"></uni-file-picker> | ||
| 158 | 144 | ||
| 159 | <button class="btn-red" @click="uploadSure">确定</button> | 145 | <!-- 底部按钮 --> |
| 146 | <view class="fixedBottom" v-if="active == 0"> | ||
| 147 | <button class="btn-red-kx" style="width: 40%;" @click="submitForm(0)">保存</button> | ||
| 148 | <button class="btn-red" style="width: 40%;" @click="submitForm(1)">下一步</button> | ||
| 149 | </view> | ||
| 150 | <view class="fixedBottom" v-if="active == 1"> | ||
| 151 | <button class="btn-red-kx" style="width: 25%;" @click="prev">上一步</button> | ||
| 152 | <button class="btn-red-kx" style="width: 25%;" @click="submitForm2(0)">保存</button> | ||
| 153 | <button class="btn-red" style="width: 30%;" @click="submitForm2(1)">提交审核</button> | ||
| 160 | </view> | 154 | </view> |
| 161 | </uni-popup> | ||
| 162 | 155 | ||
| 163 | </view> | 156 | </view> |
| 164 | </template> | 157 | </template> |
| 165 | 158 | ||
| 166 | <script setup> | 159 | <script setup> |
| 167 | import { | 160 | import { ref } from 'vue'; |
| 168 | ref | ||
| 169 | } from 'vue'; | ||
| 170 | import * as api from '@/common/api.js'; | 161 | import * as api from '@/common/api.js'; |
| 171 | import { | 162 | import { onLoad, onShow } from '@dcloudio/uni-app'; |
| 172 | onLoad, | ||
| 173 | onShow | ||
| 174 | } from '@dcloudio/uni-app'; | ||
| 175 | import config from '@/config.js' | 163 | import config from '@/config.js' |
| 176 | import dayjs from 'dayjs' | 164 | import dayjs from 'dayjs' |
| 177 | import _ from 'underscore' | 165 | import _ from 'underscore' |
| 166 | |||
| 178 | const app = getApp(); | 167 | const app = getApp(); |
| 179 | const memberInfo = app.globalData.memberInfo | 168 | const memberInfo = app.globalData.memberInfo |
| 169 | |||
| 180 | const form = ref({ | 170 | const form = ref({ |
| 181 | type: 1 | 171 | type: '1' |
| 182 | }); | 172 | }); |
| 183 | const dataList = ref([]); | 173 | |
| 184 | const examinerForChoose = ['A', 'B', 'C'] | 174 | const examinerForChoose = ['A', 'B', 'C'] |
| 185 | const examinerArr = [] | 175 | let examinerArr = [] |
| 186 | const active = ref(0) | 176 | const active = ref(0) |
| 187 | const total = ref(0) | ||
| 188 | const list1 = ref([{ | ||
| 189 | title: '考级基本信息' | ||
| 190 | }, { | ||
| 191 | title: '添加考生' | ||
| 192 | }]) | ||
| 193 | const choseStudent = ref(null) | ||
| 194 | const UpPop = ref(null) | ||
| 195 | const studentList = ref([]) | ||
| 196 | const infoList = ref([]) | 177 | const infoList = ref([]) |
| 197 | const ids = ref([]) | ||
| 198 | const tablePersonInfo = ref({}) | 178 | const tablePersonInfo = ref({}) |
| 199 | const transcript = ref([]) | 179 | const transcript = ref([]) // 补全缺失变量 |
| 200 | const studentQuery = ref({ | 180 | |
| 201 | name: '' | ||
| 202 | }) | ||
| 203 | const levelArr = ref([{ | 181 | const levelArr = ref([{ |
| 204 | value: '10', | 182 | value: '10', |
| 205 | text: '十级' | 183 | text: '十级' |
| ... | @@ -231,6 +209,7 @@ | ... | @@ -231,6 +209,7 @@ |
| 231 | value: '1', | 209 | value: '1', |
| 232 | text: '一级' | 210 | text: '一级' |
| 233 | }]) | 211 | }]) |
| 212 | |||
| 234 | const range = ref([{ | 213 | const range = ref([{ |
| 235 | value: '1', | 214 | value: '1', |
| 236 | text: '是' | 215 | text: '是' |
| ... | @@ -238,41 +217,41 @@ | ... | @@ -238,41 +217,41 @@ |
| 238 | value: '0', | 217 | value: '0', |
| 239 | text: '否' | 218 | text: '否' |
| 240 | }]) | 219 | }]) |
| 220 | |||
| 241 | let examId | 221 | let examId |
| 222 | |||
| 242 | onLoad(option => { | 223 | onLoad(option => { |
| 243 | console.log(option) | ||
| 244 | if (app.globalData.isLogin) { | 224 | if (app.globalData.isLogin) { |
| 245 | form.value.memberName = app.globalData.memberInfo.name | 225 | initData(option) |
| 246 | form.value.applyTime = dayjs().format('YYYY-MM-DD') | ||
| 247 | |||
| 248 | _.each(examinerForChoose, ec => { | ||
| 249 | form.value[`examiner_${ec}`] = null | ||
| 250 | }) | ||
| 251 | if (option.examId) { | ||
| 252 | examId = option.examId | ||
| 253 | |||
| 254 | getDetail() | ||
| 255 | } | ||
| 256 | } else { | 226 | } else { |
| 257 | |||
| 258 | app.firstLoadCallback = () => { | 227 | app.firstLoadCallback = () => { |
| 228 | initData(option) | ||
| 229 | }; | ||
| 230 | } | ||
| 231 | }); | ||
| 232 | |||
| 233 | function initData(option) { | ||
| 259 | form.value.memberName = app.globalData.memberInfo.name | 234 | form.value.memberName = app.globalData.memberInfo.name |
| 260 | form.value.applyTime = dayjs().format('YYYY-MM-DD') | 235 | form.value.applyTime = dayjs().format('YYYY-MM-DD') |
| 261 | 236 | ||
| 262 | _.each(examinerForChoose, ec => { | 237 | _.each(examinerForChoose, ec => { |
| 263 | form.value[`examiner_${ec}`] = null | 238 | form.value[`examiner_${ec}`] = null |
| 264 | }) | 239 | }) |
| 240 | |||
| 265 | if (option.examId) { | 241 | if (option.examId) { |
| 266 | examId = option.examId | 242 | examId = option.examId |
| 243 | // 如果是编辑模式,从URL参数获取active | ||
| 244 | if (option.step == '2') { | ||
| 245 | active.value = 1 | ||
| 246 | getDetail() | ||
| 247 | getChosedStudentList() | ||
| 248 | } else { | ||
| 267 | getDetail() | 249 | getDetail() |
| 268 | } | 250 | } |
| 269 | }; | ||
| 270 | } | 251 | } |
| 271 | }); | 252 | } |
| 272 | onShow(option => { | 253 | |
| 273 | // if(!!option){ | 254 | onShow(() => { |
| 274 | // console.log(option) | ||
| 275 | // } | ||
| 276 | uni.$on('chosen', updateData) | 255 | uni.$on('chosen', updateData) |
| 277 | }) | 256 | }) |
| 278 | 257 | ||
| ... | @@ -282,30 +261,28 @@ | ... | @@ -282,30 +261,28 @@ |
| 282 | } | 261 | } |
| 283 | 262 | ||
| 284 | function getDetail() { | 263 | function getDetail() { |
| 285 | api.getLevelApplyInfo(examId).then(res => { | 264 | api.getLevelApplyInfo(examId || form.value.examId).then(res => { |
| 286 | const data = res.data | 265 | const data = res.data |
| 287 | if (data.examiner) { | 266 | if (data.examiner) { |
| 288 | _.each(data.examiner.split(','), (id) => { | 267 | _.each(data.examiner.split(','), (id, i) => { |
| 289 | examinerArr.push({ | 268 | examinerArr[i] = { perId: id } |
| 290 | perId: id | ||
| 291 | }) | ||
| 292 | }) | 269 | }) |
| 293 | 270 | ||
| 294 | _.each(data.examinerNames.split(','), (name, i) => { | 271 | _.each(data.examinerNames.split(','), (name, i) => { |
| 295 | data[`examiner_${examinerForChoose[i]}`] = name | 272 | data[`examiner_${examinerForChoose[i]}`] = name |
| 273 | if (examinerArr[i]) { | ||
| 296 | examinerArr[i].name = name | 274 | examinerArr[i].name = name |
| 275 | } | ||
| 297 | }) | 276 | }) |
| 298 | } | 277 | } |
| 299 | |||
| 300 | form.value = data | 278 | form.value = data |
| 301 | }) | 279 | }) |
| 302 | } | 280 | } |
| 303 | 281 | ||
| 304 | function selectFN(ec) { | 282 | function selectFN(ec) { |
| 305 | const chosen = [] | 283 | const chosen = [] |
| 306 | const type = form.value.type | 284 | _.each(examinerForChoose, ecKey => { |
| 307 | _.each(examinerForChoose, ec => { | 285 | const key = `examiner_${ecKey}` |
| 308 | const key = `examiner_${ec}` | ||
| 309 | if (form.value[key]) { | 286 | if (form.value[key]) { |
| 310 | const examiner = _.find(examinerArr, (e) => { | 287 | const examiner = _.find(examinerArr, (e) => { |
| 311 | return e.name == form.value[key] | 288 | return e.name == form.value[key] |
| ... | @@ -316,8 +293,7 @@ | ... | @@ -316,8 +293,7 @@ |
| 316 | } | 293 | } |
| 317 | }) | 294 | }) |
| 318 | const arr = encodeURIComponent(JSON.stringify(chosen)) | 295 | const arr = encodeURIComponent(JSON.stringify(chosen)) |
| 319 | console.log(ec, chosen, type) | 296 | let path = `/level/chooseExaminer?type=${form.value.type}&chosen=${arr}&ec=${ec}` |
| 320 | let path = `/level/chooseExaminer?type=${type}&chosen=${arr}&ec=${ec}` | ||
| 321 | uni.navigateTo({ | 297 | uni.navigateTo({ |
| 322 | url: path | 298 | url: path |
| 323 | }); | 299 | }); |
| ... | @@ -347,33 +323,45 @@ | ... | @@ -347,33 +323,45 @@ |
| 347 | form.value.examiner = null | 323 | form.value.examiner = null |
| 348 | form.value.examinerNames = null | 324 | form.value.examinerNames = null |
| 349 | } | 325 | } |
| 326 | |||
| 327 | // draftFlag: 0-保存 1-保存并下一步 | ||
| 350 | form.value.draftFlag = flag === 0 ? '1' : '0' | 328 | form.value.draftFlag = flag === 0 ? '1' : '0' |
| 329 | |||
| 351 | if (flag === 0) { | 330 | if (flag === 0) { |
| 331 | // 仅保存 | ||
| 352 | save() | 332 | save() |
| 353 | } else { | 333 | } else { |
| 334 | // 保存并下一步 - 需校验 | ||
| 335 | if (!form.value.applyTime) { | ||
| 336 | uni.showToast({ title: '请选择申请日期', icon: 'none' }) | ||
| 337 | return | ||
| 338 | } | ||
| 339 | if (!form.value.startTime) { | ||
| 340 | uni.showToast({ title: '请选择考试开始时间', icon: 'none' }) | ||
| 341 | return | ||
| 342 | } | ||
| 343 | if (!form.value.endTime) { | ||
| 344 | uni.showToast({ title: '请选择考试结束时间', icon: 'none' }) | ||
| 345 | return | ||
| 346 | } | ||
| 347 | if (!form.value.examLocation) { | ||
| 348 | uni.showToast({ title: '请输入考级地点', icon: 'none' }) | ||
| 349 | return | ||
| 350 | } | ||
| 354 | if (dayjs(form.value.startTime).valueOf() < dayjs(form.value.applyTime).valueOf()) { | 351 | if (dayjs(form.value.startTime).valueOf() < dayjs(form.value.applyTime).valueOf()) { |
| 355 | uni.showToast({ | 352 | uni.showToast({ title: '考试开始时间应大于申请日期', icon: 'none' }) |
| 356 | title: `考试开始时间应大于申请日期`, | ||
| 357 | icon: 'none' | ||
| 358 | }) | ||
| 359 | return | 353 | return |
| 360 | } | 354 | } |
| 361 | if (dayjs(form.value.endTime).valueOf() <= dayjs(form.value.startTime).valueOf()) { | 355 | if (dayjs(form.value.endTime).valueOf() <= dayjs(form.value.startTime).valueOf()) { |
| 362 | uni.showToast({ | 356 | uni.showToast({ title: '考试结束时间应大于考试开始时间', icon: 'none' }) |
| 363 | title: `考试结束时间应大于考试开始时间`, | ||
| 364 | icon: 'none' | ||
| 365 | }) | ||
| 366 | return | 357 | return |
| 367 | } | 358 | } |
| 368 | if (examinerIds.length % 2 === 0) { | 359 | if (examinerIds.length % 2 === 0) { |
| 369 | uni.showToast({ | 360 | uni.showToast({ title: '录入的考官人数必须为单数', icon: 'none' }) |
| 370 | title: `录入的考官人数必须为单数`, | ||
| 371 | icon: 'none' | ||
| 372 | }) | ||
| 373 | return | 361 | return |
| 374 | } | 362 | } |
| 363 | |||
| 375 | save().then(() => { | 364 | save().then(() => { |
| 376 | // form.value.examId 下一步 | ||
| 377 | active.value = 1 | 365 | active.value = 1 |
| 378 | getChosedStudentList() | 366 | getChosedStudentList() |
| 379 | if (form.value.examId) { | 367 | if (form.value.examId) { |
| ... | @@ -390,77 +378,31 @@ | ... | @@ -390,77 +378,31 @@ |
| 390 | function save() { | 378 | function save() { |
| 391 | if (form.value.examId) { | 379 | if (form.value.examId) { |
| 392 | return api.updateLevelInfo(form.value).then(() => { | 380 | return api.updateLevelInfo(form.value).then(() => { |
| 393 | uni.showToast({ | 381 | uni.showToast({ title: '保存成功', icon: 'none' }) |
| 394 | title: `保存成功`, | ||
| 395 | icon: 'none' | ||
| 396 | }) | ||
| 397 | }) | 382 | }) |
| 398 | } else { | 383 | } else { |
| 399 | return api.addLevelInfo(form.value).then((res) => { | 384 | return api.addLevelInfo(form.value).then((res) => { |
| 400 | form.value.examId = res.data.examId | 385 | form.value.examId = res.data.examId |
| 401 | form.value.name = res.data.name | 386 | form.value.name = res.data.name |
| 402 | uni.showToast({ | 387 | uni.showToast({ title: '保存成功', icon: 'none' }) |
| 403 | title: `保存成功`, | ||
| 404 | icon: 'none' | ||
| 405 | }) | ||
| 406 | }) | 388 | }) |
| 407 | } | 389 | } |
| 408 | } | 390 | } |
| 409 | 391 | ||
| 410 | function chooseOnline() { | 392 | function prev() { |
| 411 | uni.showLoading({ | 393 | active.value = 0 |
| 412 | title: '加载中', | ||
| 413 | icon: 'none' | ||
| 414 | }) | ||
| 415 | var obj = { | ||
| 416 | memId: memberInfo.memId, | ||
| 417 | examId: form.value.examId, | ||
| 418 | examType: form.value.type, | ||
| 419 | name: studentQuery.value.name | ||
| 420 | } | ||
| 421 | api.chooseStudentsList(obj).then(response => { | ||
| 422 | studentList.value = response.rows | ||
| 423 | for (var s of studentList.value) { | ||
| 424 | s.checked = false | ||
| 425 | if (s.photo && s.photo.indexOf('http') == -1) { | ||
| 426 | s.photo = config.baseUrl_api + s.photo | ||
| 427 | } | 394 | } |
| 428 | 395 | ||
| 429 | } | 396 | function goChooseStudent() { |
| 430 | uni.hideLoading() | 397 | uni.navigateTo({ |
| 431 | choseStudent.value.open() | 398 | url: `/level/chooseStudent?examId=${form.value.examId}&memId=${memberInfo.memId}&examType=${form.value.type}` |
| 432 | }) | 399 | }) |
| 433 | } | 400 | } |
| 434 | 401 | ||
| 435 | function checkThis(item) { | 402 | // 格式化日期时间 |
| 436 | if (item.checked) { | 403 | function formatDateTime(dateStr) { |
| 437 | item.checked = false | 404 | if (!dateStr) return '-' |
| 438 | } else { | 405 | return dateStr.substring(0, 10) |
| 439 | item.checked = true | ||
| 440 | } | ||
| 441 | } | ||
| 442 | |||
| 443 | function submitStudents() { | ||
| 444 | ids.value = [] | ||
| 445 | for (var s of studentList.value) { | ||
| 446 | if (s.checked) { | ||
| 447 | ids.value.push(s.perId) | ||
| 448 | } | ||
| 449 | } | ||
| 450 | if (ids.value.length == 0) { | ||
| 451 | uni.showToast({ | ||
| 452 | title: '请选择考生', | ||
| 453 | icon: 'none' | ||
| 454 | }) | ||
| 455 | return | ||
| 456 | } | ||
| 457 | api.batchChoose({ | ||
| 458 | examId: form.value.examId, | ||
| 459 | perIds: ids.value | ||
| 460 | }).then(() => { | ||
| 461 | getChosedStudentList() | ||
| 462 | choseStudent.value.close() | ||
| 463 | }) | ||
| 464 | } | 406 | } |
| 465 | 407 | ||
| 466 | function getChosedStudentList() { | 408 | function getChosedStudentList() { |
| ... | @@ -491,21 +433,20 @@ | ... | @@ -491,21 +433,20 @@ |
| 491 | }) | 433 | }) |
| 492 | 434 | ||
| 493 | infoList.value = res.rows | 435 | infoList.value = res.rows |
| 494 | |||
| 495 | }).then(getTablePersonInfo) | 436 | }).then(getTablePersonInfo) |
| 496 | } | 437 | } |
| 497 | 438 | ||
| 498 | function getTablePersonInfo() { | 439 | function getTablePersonInfo() { |
| 499 | const total = infoList.value.length | 440 | const total = infoList.value.length |
| 500 | const levelArr = [] | 441 | const levelArrData = [] |
| 501 | _.each(infoList.value, (d) => { | 442 | _.each(infoList.value, (d) => { |
| 502 | const temp = _.find(levelArr, (l) => { | 443 | const temp = _.find(levelArrData, (l) => { |
| 503 | return l.level == d.levelNew | 444 | return l.level == d.levelNew |
| 504 | }) | 445 | }) |
| 505 | if (temp) { | 446 | if (temp) { |
| 506 | temp.num++ | 447 | temp.num++ |
| 507 | } else { | 448 | } else { |
| 508 | levelArr.push({ | 449 | levelArrData.push({ |
| 509 | level: d.levelNew, | 450 | level: d.levelNew, |
| 510 | num: 1 | 451 | num: 1 |
| 511 | }) | 452 | }) |
| ... | @@ -514,7 +455,7 @@ | ... | @@ -514,7 +455,7 @@ |
| 514 | 455 | ||
| 515 | tablePersonInfo.value = { | 456 | tablePersonInfo.value = { |
| 516 | total: total, | 457 | total: total, |
| 517 | levelArr: _.sortBy(levelArr, (l) => { | 458 | levelArr: _.sortBy(levelArrData, (l) => { |
| 518 | return l.level | 459 | return l.level |
| 519 | }) | 460 | }) |
| 520 | } | 461 | } |
| ... | @@ -540,13 +481,9 @@ | ... | @@ -540,13 +481,9 @@ |
| 540 | }) | 481 | }) |
| 541 | } | 482 | } |
| 542 | 483 | ||
| 543 | |||
| 544 | function changeLevel(e) { | 484 | function changeLevel(e) { |
| 545 | if (e == nowRow.levelOld) { | 485 | if (e == nowRow.levelOld) { |
| 546 | uni.showToast({ | 486 | uni.showToast({ title: '考试级别重复,请重新选择!', icon: 'none' }) |
| 547 | title: `考试级别重复,请重新选择!`, | ||
| 548 | icon: 'none' | ||
| 549 | }) | ||
| 550 | nowRow.levelNew = nowRow.levelRecommend | 487 | nowRow.levelNew = nowRow.levelRecommend |
| 551 | return | 488 | return |
| 552 | } | 489 | } |
| ... | @@ -557,7 +494,7 @@ | ... | @@ -557,7 +494,7 @@ |
| 557 | success: function(res) { | 494 | success: function(res) { |
| 558 | if (res.confirm) { | 495 | if (res.confirm) { |
| 559 | getTablePersonInfo() | 496 | getTablePersonInfo() |
| 560 | }else{ | 497 | } else { |
| 561 | nowRow.levelNew = nowRow.levelRecommend | 498 | nowRow.levelNew = nowRow.levelRecommend |
| 562 | } | 499 | } |
| 563 | }, | 500 | }, |
| ... | @@ -569,71 +506,41 @@ | ... | @@ -569,71 +506,41 @@ |
| 569 | } | 506 | } |
| 570 | 507 | ||
| 571 | function submitForm2(flag) { | 508 | function submitForm2(flag) { |
| 572 | //循环infoList.value 如果item.levelNew == item.levelOld 提示错误 | 509 | // 循环校验考试级别 |
| 573 | for (var item of infoList.value) { | 510 | for (var item of infoList.value) { |
| 574 | if (item.levelNew == item.levelOld) { | 511 | if (item.levelNew == item.levelOld) { |
| 575 | uni.showToast({ | 512 | uni.showToast({ title: `${item.realName}考试级别重复,请重新选择!`, icon: 'none' }) |
| 576 | title: `${item.realName}考试级别重复,请重新选择!`, | ||
| 577 | icon: 'none' | ||
| 578 | }) | ||
| 579 | return | 513 | return |
| 580 | } | 514 | } |
| 581 | if (!item.levelNew) { | 515 | if (!item.levelNew) { |
| 582 | uni.showToast({ | 516 | uni.showToast({ title: `${item.realName}请选择考试级别!`, icon: 'none' }) |
| 583 | title: `${item.realName}请选择考试级别!`, | ||
| 584 | icon: 'none' | ||
| 585 | }) | ||
| 586 | return | 517 | return |
| 587 | } | 518 | } |
| 588 | } | 519 | } |
| 520 | |||
| 589 | if (flag === 1) { | 521 | if (flag === 1) { |
| 590 | if (infoList.value.length == 0) { | 522 | if (infoList.value.length == 0) { |
| 591 | uni.showToast({ | 523 | uni.showToast({ title: '请选择考生', icon: 'none' }) |
| 592 | title: '请选择考生', | ||
| 593 | icon: 'none' | ||
| 594 | }) | ||
| 595 | return | 524 | return |
| 596 | } | 525 | } |
| 597 | 526 | ||
| 598 | // if (!form.value.transcript) { | ||
| 599 | // uni.showToast({ | ||
| 600 | // title: '请上传成绩单', | ||
| 601 | // icon: 'none' | ||
| 602 | // }) | ||
| 603 | // return | ||
| 604 | // } | ||
| 605 | |||
| 606 | uni.showModal({ | 527 | uni.showModal({ |
| 607 | title: '提示', | 528 | title: '提示', |
| 608 | content: `请确认人员照片是否已更新?`, | 529 | content: `请确认人员照片是否已更新?`, |
| 609 | success: function(res) { | 530 | success: function(res) { |
| 610 | if (res.confirm) { | 531 | if (res.confirm) { |
| 611 | console.log('用户点击确定'); | 532 | saveStep2(flag).then(() => { |
| 612 | saveStep2(flag).then(Response => { | 533 | uni.showToast({ title: '提交成功', icon: 'none' }) |
| 613 | if (flag === 1) { | ||
| 614 | uni.showToast({ | ||
| 615 | title: `提交成功` | ||
| 616 | }) | ||
| 617 | uni.navigateTo({ | 534 | uni.navigateTo({ |
| 618 | url: `/level/paymentDetail?examId=${form.value.examId}` | 535 | url: `/level/paymentDetail?examId=${form.value.examId}` |
| 619 | }) | 536 | }) |
| 620 | } else { | ||
| 621 | uni.showToast({ | ||
| 622 | title: `操作成功` | ||
| 623 | }) | 537 | }) |
| 624 | } | 538 | } |
| 625 | }) | ||
| 626 | } else if (res.cancel) { | ||
| 627 | console.log('用户点击取消'); | ||
| 628 | } | ||
| 629 | |||
| 630 | } | 539 | } |
| 631 | }) | 540 | }) |
| 632 | } else { | 541 | } else { |
| 633 | saveStep2(flag).then(res => { | 542 | saveStep2(flag).then(() => { |
| 634 | uni.showToast({ | 543 | uni.showToast({ title: '操作成功', icon: 'none' }) |
| 635 | title: `操作成功` | ||
| 636 | }) | ||
| 637 | }) | 544 | }) |
| 638 | } | 545 | } |
| 639 | } | 546 | } |
| ... | @@ -643,7 +550,6 @@ | ... | @@ -643,7 +550,6 @@ |
| 643 | return { | 550 | return { |
| 644 | id: d.id, | 551 | id: d.id, |
| 645 | levelNew: d.levelNew, | 552 | levelNew: d.levelNew, |
| 646 | // score: d.score, | ||
| 647 | isPass: d.isPass | 553 | isPass: d.isPass |
| 648 | } | 554 | } |
| 649 | }) | 555 | }) |
| ... | @@ -655,88 +561,332 @@ | ... | @@ -655,88 +561,332 @@ |
| 655 | }) | 561 | }) |
| 656 | } | 562 | } |
| 657 | 563 | ||
| 658 | function handleUpdate() { | 564 | function handleDelete(row) { |
| 659 | UpPop.value.open() | 565 | uni.showModal({ |
| 566 | title: '提示', | ||
| 567 | content: `确定删除${row.realName}?`, | ||
| 568 | success: function(res) { | ||
| 569 | if (res.confirm) { | ||
| 570 | api.dellevelPerson(row.id).then(() => { | ||
| 571 | uni.showToast({ title: '操作成功', icon: 'none' }) | ||
| 572 | getChosedStudentList() | ||
| 573 | }) | ||
| 574 | } | ||
| 575 | } | ||
| 576 | }) | ||
| 577 | } | ||
| 578 | </script> | ||
| 579 | <style lang="scss" scoped> | ||
| 580 | .add-apply-page { | ||
| 581 | min-height: 100vh; | ||
| 582 | background: #f5f5f5; | ||
| 583 | padding-bottom: 120rpx; | ||
| 584 | } | ||
| 585 | |||
| 586 | /* 顶部步骤条 */ | ||
| 587 | .steps-bar { | ||
| 588 | display: flex; | ||
| 589 | align-items: center; | ||
| 590 | justify-content: center; | ||
| 591 | padding: 15rpx 60rpx; | ||
| 592 | background: #fff; | ||
| 593 | margin-top: 20rpx; | ||
| 594 | |||
| 595 | .step-item { | ||
| 596 | display: flex; | ||
| 597 | align-items: center; | ||
| 598 | |||
| 599 | .step-circle { | ||
| 600 | width: 48rpx; | ||
| 601 | height: 48rpx; | ||
| 602 | border-radius: 50%; | ||
| 603 | background: #fff; | ||
| 604 | border: 2rpx solid #666; | ||
| 605 | color: #666; | ||
| 606 | font-size: 24rpx; | ||
| 607 | display: flex; | ||
| 608 | align-items: center; | ||
| 609 | justify-content: center; | ||
| 610 | margin-right: 10rpx; | ||
| 611 | transition: all 0.3s; | ||
| 612 | } | ||
| 613 | |||
| 614 | .step-text { | ||
| 615 | font-size: 24rpx; | ||
| 616 | color: #666; | ||
| 617 | transition: all 0.3s; | ||
| 618 | } | ||
| 619 | |||
| 620 | &.active .step-circle { | ||
| 621 | background: #fff; | ||
| 622 | color: #AD181F; | ||
| 623 | border-color: #AD181F; | ||
| 660 | } | 624 | } |
| 661 | let selectFileValue = {} | ||
| 662 | 625 | ||
| 663 | function selectFile(e) { | 626 | &.active .step-text { |
| 664 | let file = e.tempFiles[0] | 627 | color: #AD181F; |
| 665 | if (!file) { | 628 | font-weight: 600; |
| 666 | return | ||
| 667 | } | 629 | } |
| 668 | for (const n in e.tempFiles) { | 630 | |
| 669 | api.uploadFileList(e.tempFilePaths[n]).then(data => { | 631 | &.current .step-circle { |
| 670 | selectFileValue = { | 632 | background: #AD181F; |
| 671 | url: data, | 633 | color: #fff; |
| 672 | name: e.tempFiles[n].name, | 634 | box-shadow: 0 4rpx 12rpx rgba(173, 24, 31, 0.3); |
| 673 | extname: e.tempFiles[n].extname | ||
| 674 | } | 635 | } |
| 675 | 636 | ||
| 676 | transcript.value.push(selectFileValue) | 637 | &.current .step-text { |
| 677 | }); | 638 | color: #AD181F; |
| 639 | font-weight: 600; | ||
| 640 | } | ||
| 678 | } | 641 | } |
| 679 | 642 | ||
| 643 | .step-line { | ||
| 644 | width: 120rpx; | ||
| 645 | height: 4rpx; | ||
| 646 | background: #e0e0e0; | ||
| 647 | margin: 0 20rpx; | ||
| 648 | transition: all 0.3s; | ||
| 649 | |||
| 650 | &.active { | ||
| 651 | background: #AD181F; | ||
| 652 | } | ||
| 653 | } | ||
| 680 | } | 654 | } |
| 681 | 655 | ||
| 682 | function fileProgress(e) { | 656 | /* 步骤2样式 */ |
| 683 | console.log('progress:' + e) | 657 | .step2-content { |
| 658 | padding: 0 20rpx; | ||
| 659 | margin-top: 20rpx; | ||
| 684 | } | 660 | } |
| 685 | 661 | ||
| 686 | function delSupplementFile(e) { | 662 | /* 考级信息卡片 */ |
| 687 | transcript.value = _.remove(transcript.value, function(n) { | 663 | .exam-info-card { |
| 688 | return n.name != e.tempFile.name; | 664 | background: #fff; |
| 689 | }); | 665 | border-radius: 16rpx; |
| 666 | margin-bottom: 20rpx; | ||
| 667 | overflow: hidden; | ||
| 668 | box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05); | ||
| 669 | |||
| 670 | .card-header { | ||
| 671 | padding: 24rpx 30rpx; | ||
| 672 | background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%); | ||
| 673 | |||
| 674 | .card-title { | ||
| 675 | font-size: 28rpx; | ||
| 676 | font-weight: 600; | ||
| 677 | color: #fff; | ||
| 678 | } | ||
| 690 | } | 679 | } |
| 691 | 680 | ||
| 692 | function uploadSure() { | 681 | .info-grid { |
| 693 | // 上传确定 | 682 | display: flex; |
| 694 | if (transcript.value.length == 0) { | 683 | flex-wrap: wrap; |
| 695 | uni.showToast({ | 684 | padding: 20rpx 0; |
| 696 | title: `请上传成绩单`, | 685 | |
| 697 | icon: 'error' | 686 | .info-item { |
| 698 | }) | 687 | width: 100%; |
| 699 | return | 688 | padding: 12rpx 30rpx; |
| 689 | box-sizing: border-box; | ||
| 690 | display: flex; | ||
| 691 | |||
| 692 | .info-label { | ||
| 693 | display: block; | ||
| 694 | font-size: 24rpx; | ||
| 695 | color: #666; | ||
| 696 | margin-bottom: 8rpx; | ||
| 697 | |||
| 700 | } | 698 | } |
| 701 | 699 | ||
| 702 | form.value.transcript = JSON.stringify(_.map(transcript.value, (t) => { | 700 | .info-value { |
| 703 | return { | 701 | display: block; |
| 704 | name: t.name, | 702 | font-size: 26rpx; |
| 705 | url: t.url | 703 | color: #333; |
| 704 | font-weight: 500; | ||
| 705 | margin-left: 20rpx; | ||
| 706 | } | ||
| 707 | } | ||
| 706 | } | 708 | } |
| 707 | })) | ||
| 708 | UpPop.value.close() | ||
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | function handleDelete(row) { | 711 | /* 操作栏(统计+添加按钮) */ |
| 712 | uni.showModal({ | 712 | .action-bar { |
| 713 | title: '提示', | 713 | display: flex; |
| 714 | content: `确定删除${row.realName}?`, | 714 | justify-content: space-between; |
| 715 | success: function(res) { | 715 | align-items: center; |
| 716 | if (res.confirm) { | 716 | padding: 20rpx 24rpx; |
| 717 | api.dellevelPerson(row.id).then(res => { | 717 | background: #fff; |
| 718 | uni.showToast({ | 718 | border-radius: 16rpx; |
| 719 | title: `操作成功` | 719 | margin: 20rpx 0; |
| 720 | }) | 720 | |
| 721 | getChosedStudentList() | 721 | .stat-info { |
| 722 | }) | 722 | display: flex; |
| 723 | align-items: center; | ||
| 724 | // justify-self: unset; | ||
| 725 | .stat-total { | ||
| 726 | font-size: 28rpx; | ||
| 727 | font-weight: 600; | ||
| 728 | color: #333; | ||
| 729 | } | ||
| 730 | |||
| 731 | .level-tags { | ||
| 732 | display: flex; | ||
| 733 | flex-wrap: wrap; | ||
| 734 | margin-left: 10rpx; | ||
| 735 | gap: 10rpx; | ||
| 736 | |||
| 737 | .level-tag { | ||
| 738 | padding: 4rpx 12rpx; | ||
| 739 | background: #FFF5F5; | ||
| 740 | border: 1rpx solid #FFDDDD; | ||
| 741 | border-radius: 6rpx; | ||
| 742 | font-size: 24rpx; | ||
| 743 | color: #AD181F; | ||
| 723 | } | 744 | } |
| 724 | } | 745 | } |
| 725 | }) | ||
| 726 | } | 746 | } |
| 727 | </script> | ||
| 728 | 747 | ||
| 729 | <style lang="scss" scoped> | 748 | |
| 730 | :deep(.uni-progress-bar) { | 749 | } |
| 731 | display: none; | 750 | .btn-add-student { |
| 751 | display: flex; | ||
| 752 | align-items: center; | ||
| 753 | justify-content: center; | ||
| 754 | padding: 0 30rpx; | ||
| 755 | height: 64rpx; | ||
| 756 | background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%); | ||
| 757 | border-radius: 32rpx; | ||
| 758 | font-size: 26rpx; | ||
| 759 | color: #fff; | ||
| 760 | box-shadow: 0 4rpx 16rpx rgba(173, 24, 31, 0.3); | ||
| 761 | } | ||
| 762 | /* 考生列表(核心优化) */ | ||
| 763 | .student-list { | ||
| 764 | .student-card { | ||
| 765 | position: relative; | ||
| 766 | // display: flex; | ||
| 767 | |||
| 768 | // align-items: center; | ||
| 769 | // justify-content: space-between; | ||
| 770 | padding: 24rpx; | ||
| 771 | background: #fff; | ||
| 772 | border-radius: 16rpx; | ||
| 773 | margin-bottom: 20rpx; | ||
| 774 | box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04); | ||
| 775 | |||
| 776 | /* 左侧:头像+考生信息 */ | ||
| 777 | .card-left { | ||
| 778 | display: flex; | ||
| 779 | align-items: center; | ||
| 780 | flex: 1; | ||
| 781 | |||
| 782 | .avatar { | ||
| 783 | width: 80rpx; | ||
| 784 | height: 80rpx; | ||
| 785 | border-radius: 50%; | ||
| 786 | background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%); | ||
| 787 | display: flex; | ||
| 788 | align-items: center; | ||
| 789 | justify-content: center; | ||
| 790 | margin-right: 20rpx; | ||
| 791 | overflow: hidden; | ||
| 792 | |||
| 793 | .avatar-text { | ||
| 794 | font-size: 32rpx; | ||
| 795 | color: #fff; | ||
| 796 | font-weight: 600; | ||
| 797 | } | ||
| 798 | |||
| 799 | image { | ||
| 800 | width: 100%; | ||
| 801 | height: 100%; | ||
| 802 | } | ||
| 732 | } | 803 | } |
| 733 | 804 | ||
| 734 | .item { | 805 | .student-info { |
| 735 | .del { | 806 | .student-name { |
| 736 | color: #AD181F; | 807 | font-size: 28rpx; |
| 737 | position: absolute; | 808 | font-weight: 600; |
| 738 | right: 30rpx; | 809 | color: #333; |
| 810 | margin-bottom: 8rpx; | ||
| 811 | |||
| 812 | .per-code { | ||
| 813 | font-size: 24rpx; | ||
| 814 | color: #666; | ||
| 815 | font-weight: normal; | ||
| 816 | margin-left: 12rpx; | ||
| 817 | } | ||
| 818 | } | ||
| 819 | |||
| 820 | .student-idcard { | ||
| 821 | font-size: 24rpx; | ||
| 822 | color: #666; | ||
| 823 | } | ||
| 824 | } | ||
| 825 | } | ||
| 826 | |||
| 827 | /* 右侧:原级别/考试级别/是否通过(垂直布局,完美对齐) */ | ||
| 828 | .card-right { | ||
| 829 | display: flex; | ||
| 830 | justify-content: space-between; | ||
| 831 | // padding:0 30px; | ||
| 832 | margin-top: 20rpx; | ||
| 833 | margin-left:100rpx; | ||
| 834 | // flex-direction: column; | ||
| 835 | // align-items: flex-end; | ||
| 836 | // gap: 16rpx; | ||
| 837 | |||
| 838 | .level-item { | ||
| 839 | display: flex; | ||
| 840 | flex-direction: column; | ||
| 841 | align-items: flex-end; | ||
| 842 | |||
| 843 | .level-label { | ||
| 844 | font-size: 24rpx; | ||
| 845 | color: #666; | ||
| 846 | margin-bottom: 6rpx; | ||
| 847 | } | ||
| 848 | |||
| 849 | .level-value { | ||
| 739 | font-size: 28rpx; | 850 | font-size: 28rpx; |
| 851 | color: #333; | ||
| 852 | font-weight: 500; | ||
| 853 | } | ||
| 854 | |||
| 855 | .select-wrapper { | ||
| 856 | width: 120rpx; | ||
| 857 | } | ||
| 858 | } | ||
| 859 | } | ||
| 860 | |||
| 861 | /* 删除按钮 */ | ||
| 862 | .delete-btn { | ||
| 863 | position: absolute; | ||
| 864 | top: 16rpx; | ||
| 865 | right: 16rpx; | ||
| 866 | padding: 8rpx; | ||
| 867 | } | ||
| 868 | } | ||
| 869 | |||
| 870 | /* 空状态 */ | ||
| 871 | .empty-state { | ||
| 872 | display: flex; | ||
| 873 | flex-direction: column; | ||
| 874 | align-items: center; | ||
| 875 | justify-content: center; | ||
| 876 | padding: 80rpx 0; | ||
| 877 | background: #fff; | ||
| 878 | border-radius: 16rpx; | ||
| 879 | |||
| 880 | image { | ||
| 881 | width: 240rpx; | ||
| 882 | height: 240rpx; | ||
| 883 | margin-bottom: 20rpx; | ||
| 884 | } | ||
| 885 | |||
| 886 | text { | ||
| 887 | font-size: 26rpx; | ||
| 888 | color: #666; | ||
| 889 | } | ||
| 740 | } | 890 | } |
| 741 | } | 891 | } |
| 742 | 892 | ||
| ... | @@ -753,10 +903,6 @@ | ... | @@ -753,10 +903,6 @@ |
| 753 | padding-bottom: 20rpx; | 903 | padding-bottom: 20rpx; |
| 754 | } | 904 | } |
| 755 | 905 | ||
| 756 | .popBody { | ||
| 757 | padding: 40rpx 30rpx; | ||
| 758 | } | ||
| 759 | |||
| 760 | .maskbox { | 906 | .maskbox { |
| 761 | position: relative; | 907 | position: relative; |
| 762 | 908 | ||
| ... | @@ -770,7 +916,38 @@ | ... | @@ -770,7 +916,38 @@ |
| 770 | } | 916 | } |
| 771 | } | 917 | } |
| 772 | 918 | ||
| 773 | :deep(.file-picker__progress) { | 919 | /* 底部按钮 */ |
| 774 | opacity: 0; | 920 | .fixedBottom { |
| 921 | position: fixed; | ||
| 922 | bottom: 0; | ||
| 923 | left: 0; | ||
| 924 | right: 0; | ||
| 925 | display: flex; | ||
| 926 | justify-content: space-around; | ||
| 927 | align-items: center; | ||
| 928 | padding: 20rpx 0; | ||
| 929 | background: #fff; | ||
| 930 | border-top: 1rpx solid #f0f0f0; | ||
| 931 | z-index: 999; | ||
| 932 | |||
| 933 | .btn-red { | ||
| 934 | background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%); | ||
| 935 | color: #fff; | ||
| 936 | border: none; | ||
| 937 | border-radius: 32rpx; | ||
| 938 | height: 72rpx; | ||
| 939 | font-size: 28rpx; | ||
| 940 | font-weight: 600; | ||
| 941 | } | ||
| 942 | |||
| 943 | .btn-red-kx { | ||
| 944 | background: #fff; | ||
| 945 | color: #AD181F; | ||
| 946 | border: 2rpx solid #AD181F; | ||
| 947 | border-radius: 32rpx; | ||
| 948 | height: 72rpx; | ||
| 949 | font-size: 28rpx; | ||
| 950 | font-weight: 600; | ||
| 951 | } | ||
| 775 | } | 952 | } |
| 776 | </style> | 953 | </style> |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -11,24 +11,27 @@ | ... | @@ -11,24 +11,27 @@ |
| 11 | <view class="indexboxre"> | 11 | <view class="indexboxre"> |
| 12 | <view class="userlist"> | 12 | <view class="userlist"> |
| 13 | <view class="item" v-for="(n,index) in list" :key="index"> | 13 | <view class="item" v-for="(n,index) in list" :key="index"> |
| 14 | <view> | 14 | <view class="item-content"> |
| 15 | <view class="name-row"> | ||
| 15 | <view class="name">{{n.perName}}</view> | 16 | <view class="name">{{n.perName}}</view> |
| 17 | <view class="expired-tag" v-if="n.canChoose != 1"> | ||
| 18 | <text class="expired-text">已过期</text> | ||
| 19 | </view> | ||
| 20 | </view> | ||
| 16 | <view class="date">会员号:{{n.perCode||'-'}}</view> | 21 | <view class="date">会员号:{{n.perCode||'-'}}</view> |
| 17 | <view class="date">有效日期:{{n.roleInfo && n.roleInfo.validTime ? n.roleInfo.validTime : '-'}}</view> | 22 | <view class="date">有效日期:{{ formatDate(n.roleInfo && n.roleInfo.validTime ? n.roleInfo.validTime : '-') }}</view> |
| 18 | <view class="date">注册地:{{n.memName||'-'}}</view> | 23 | <view class="date">注册地:{{n.memName||'-'}}</view> |
| 19 | <view class="date" :class="{'text-danger': n.canChoose != 1}"> | ||
| 20 | 状态:{{ n.canChoose == 1 ? '正常' : '资质已过期' }} | ||
| 21 | </view> | ||
| 22 | </view> | 24 | </view> |
| 23 | <view class="status"> | 25 | <view class="status"> |
| 24 | <text v-if="isChosen(n)" class="text-gray">已选</text> | 26 | <text v-if="isChosen(n)" class="text-gray">已选</text> |
| 25 | <text v-else class="text-primary" @click="handleChoose(n)">选择</text> | 27 | <!-- <text v-else-if="n.canChoose != 1" class="text-gray">不可选</text> --> |
| 28 | <text v-if="n.canChoose == 1" class="text-primary" @click="handleChoose(n)">选择</text> | ||
| 26 | </view> | 29 | </view> |
| 27 | </view> | 30 | </view> |
| 28 | </view> | 31 | </view> |
| 29 | <view class="nodata" v-if="list.length==0 && !loading"> | 32 | <view class="empty" v-if="list.length==0 && !loading"> |
| 30 | <image mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image> | 33 | <image class="empty-img" mode="aspectFit" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image> |
| 31 | <text>暂无考官数据</text> | 34 | <text class="empty-text">暂无考官数据</text> |
| 32 | </view> | 35 | </view> |
| 33 | </view> | 36 | </view> |
| 34 | 37 | ||
| ... | @@ -132,6 +135,16 @@ | ... | @@ -132,6 +135,16 @@ |
| 132 | return chosen.some(c => c.perId == n.perId) | 135 | return chosen.some(c => c.perId == n.perId) |
| 133 | } | 136 | } |
| 134 | 137 | ||
| 138 | // 格式化日期,去掉时间部分 | ||
| 139 | function formatDate(dateStr) { | ||
| 140 | if (!dateStr || dateStr === '-') return '-' | ||
| 141 | // 如果是完整日期时间格式,截取日期部分 | ||
| 142 | if (dateStr.length > 10) { | ||
| 143 | return dateStr.substring(0, 10) | ||
| 144 | } | ||
| 145 | return dateStr | ||
| 146 | } | ||
| 147 | |||
| 135 | function handleChoose(row) { | 148 | function handleChoose(row) { |
| 136 | if (row.canChoose != 1) { | 149 | if (row.canChoose != 1) { |
| 137 | uni.showToast({ | 150 | uni.showToast({ |
| ... | @@ -252,10 +265,33 @@ | ... | @@ -252,10 +265,33 @@ |
| 252 | background: #fff; | 265 | background: #fff; |
| 253 | border-radius: 10rpx; | 266 | border-radius: 10rpx; |
| 254 | 267 | ||
| 268 | .item-content { | ||
| 269 | flex: 1; | ||
| 270 | } | ||
| 271 | |||
| 272 | .name-row { | ||
| 273 | display: flex; | ||
| 274 | align-items: center; | ||
| 275 | margin-bottom: 10rpx; | ||
| 276 | justify-content: space-between; | ||
| 277 | } | ||
| 278 | |||
| 255 | .name { | 279 | .name { |
| 256 | font-size: 32rpx; | 280 | font-size: 32rpx; |
| 257 | font-weight: bold; | 281 | font-weight: bold; |
| 258 | margin-bottom: 10rpx; | 282 | } |
| 283 | |||
| 284 | .expired-tag { | ||
| 285 | // margin-left: 15rpx; | ||
| 286 | // padding: 0 12rpx; | ||
| 287 | // background: #fff0f0; | ||
| 288 | // border: 1px solid #ffcccc; | ||
| 289 | // border-radius: 6rpx; | ||
| 290 | } | ||
| 291 | |||
| 292 | .expired-text { | ||
| 293 | font-size: 22rpx; | ||
| 294 | color: #dd524d; | ||
| 259 | } | 295 | } |
| 260 | 296 | ||
| 261 | .date { | 297 | .date { | ... | ... |
level/chooseStudent.vue
0 → 100644
| 1 | <template> | ||
| 2 | <view class="choose-student-page"> | ||
| 3 | <!-- 顶部搜索栏 --> | ||
| 4 | <view class="search-header"> | ||
| 5 | <view class="search-box"> | ||
| 6 | <uni-icons type="search" size="18" color="#999"></uni-icons> | ||
| 7 | <input | ||
| 8 | class="search-input" | ||
| 9 | v-model="searchName" | ||
| 10 | placeholder="搜索考生姓名" | ||
| 11 | @confirm="searchStudents" | ||
| 12 | /> | ||
| 13 | <uni-icons v-if="searchName" type="clear" size="16" color="#999" @click="clearSearch"></uni-icons> | ||
| 14 | </view> | ||
| 15 | <text class="cancel-btn" @click="goBack">取消</text> | ||
| 16 | </view> | ||
| 17 | |||
| 18 | <!-- 已选考生 --> | ||
| 19 | <view class="selected-section" v-if="selectedList.length > 0"> | ||
| 20 | <view class="section-header"> | ||
| 21 | <text class="section-title">已选考生</text> | ||
| 22 | <text class="section-count">{{selectedList.length}}人</text> | ||
| 23 | </view> | ||
| 24 | <scroll-view class="selected-scroll" scroll-x> | ||
| 25 | <view class="selected-item" v-for="(item, index) in selectedList" :key="index"> | ||
| 26 | <view class="avatar-small"> | ||
| 27 | <image v-if="item.photo" :src="item.photo" mode="aspectFill"></image> | ||
| 28 | <text v-else>{{(item.name || '').slice(0,1)}}</text> | ||
| 29 | </view> | ||
| 30 | <text class="name-small">{{item.name}}</text> | ||
| 31 | <view class="remove-btn" @click="removeSelected(index)"> | ||
| 32 | <uni-icons type="closeempty" size="12" color="#fff"></uni-icons> | ||
| 33 | </view> | ||
| 34 | </view> | ||
| 35 | </scroll-view> | ||
| 36 | </view> | ||
| 37 | |||
| 38 | <!-- 考生列表 --> | ||
| 39 | <scroll-view class="student-scroll" scroll-y @scrolltolower="loadMore"> | ||
| 40 | <view class="student-list"> | ||
| 41 | <view class="student-card" v-for="(item, index) in studentList" :key="index" @click="toggleSelect(item)"> | ||
| 42 | <view class="checkbox"> | ||
| 43 | <image v-if="item.checked" src="/static/member/dx_dwn.png" mode="aspectFit"></image> | ||
| 44 | <view v-else class="checkbox-empty"></view> | ||
| 45 | </view> | ||
| 46 | <view class="avatar"> | ||
| 47 | <image v-if="item.photo" :src="item.photo" mode="aspectFill"></image> | ||
| 48 | <image v-else :src="config.baseUrl_api + '/fs/static/tx@2x.png'" | ||
| 49 | mode="aspectFill"> | ||
| 50 | </image> | ||
| 51 | <!-- <text v-else class="avatar-text">{{(item.name || '').slice(0,1)}}</text> --> | ||
| 52 | </view> | ||
| 53 | <view class="student-info"> | ||
| 54 | <view class="student-name"> | ||
| 55 | {{item.name}} | ||
| 56 | <text class="per-code">{{item.perCode}}</text> | ||
| 57 | </view> | ||
| 58 | <view class="student-detail"> | ||
| 59 | <text class="level-info">级位:{{ formatLevel(item.levelJi) }}</text> | ||
| 60 | <text class="validity">到期:{{ formatDate(item.validityDate) }}</text> | ||
| 61 | </view> | ||
| 62 | </view> | ||
| 63 | </view> | ||
| 64 | |||
| 65 | <!-- 加载状态 --> | ||
| 66 | <view class="loading-more" v-if="loading"> | ||
| 67 | <text>加载中...</text> | ||
| 68 | </view> | ||
| 69 | <view class="no-more" v-if="!loading && noMore && studentList.length > 0"> | ||
| 70 | <text>没有更多了</text> | ||
| 71 | </view> | ||
| 72 | |||
| 73 | <!-- 空状态 --> | ||
| 74 | <view class="empty" v-if="!loading && studentList.length === 0"> | ||
| 75 | <image class="empty-img" :src="config.baseUrl_api + '/fs/static/nodata.png'"></image> | ||
| 76 | <text class="empty-text">暂无考生信息</text> | ||
| 77 | </view> | ||
| 78 | </view> | ||
| 79 | </scroll-view> | ||
| 80 | |||
| 81 | <!-- 底部确定按钮 --> | ||
| 82 | <view class="fixedBottom"> | ||
| 83 | <view class="bottom-info"> | ||
| 84 | <text class="info-text">已选择 <text class="count">{{selectedList.length}}</text> 人</text> | ||
| 85 | </view> | ||
| 86 | <view style="text-align:right"> | ||
| 87 | <button class="btn-confirm" @click="confirmSelect">确定添加</button> | ||
| 88 | </view> | ||
| 89 | |||
| 90 | </view> | ||
| 91 | </view> | ||
| 92 | </template> | ||
| 93 | |||
| 94 | <script setup> | ||
| 95 | import * as api from '@/common/api.js' | ||
| 96 | import config from '@/config.js' | ||
| 97 | import {ref} from 'vue' | ||
| 98 | import { onLoad } from '@dcloudio/uni-app' | ||
| 99 | |||
| 100 | let examId = '' | ||
| 101 | let memId = '' | ||
| 102 | let examType = '' | ||
| 103 | |||
| 104 | const searchName = ref('') | ||
| 105 | const studentList = ref([]) | ||
| 106 | const selectedList = ref([]) | ||
| 107 | const loading = ref(false) | ||
| 108 | const noMore = ref(false) | ||
| 109 | const pageNum = ref(1) | ||
| 110 | const pageSize = 20 | ||
| 111 | |||
| 112 | onLoad((option) => { | ||
| 113 | examId = option.examId || '' | ||
| 114 | memId = option.memId || '' | ||
| 115 | examType = option.examType || '1' | ||
| 116 | getStudentList() | ||
| 117 | }) | ||
| 118 | |||
| 119 | function getStudentList(isMore = false) { | ||
| 120 | if (loading.value) return | ||
| 121 | loading.value = true | ||
| 122 | |||
| 123 | api.chooseStudentsList({ | ||
| 124 | memId: memId, | ||
| 125 | examId: examId, | ||
| 126 | examType: examType, | ||
| 127 | name: searchName.value | ||
| 128 | }).then(res => { | ||
| 129 | const rows = res.rows || [] | ||
| 130 | rows.forEach(item => { | ||
| 131 | item.checked = selectedList.value.some(s => s.perId === item.perId) | ||
| 132 | if (item.photo && item.photo.indexOf('http') == -1) { | ||
| 133 | item.photo = config.baseUrl_api + item.photo | ||
| 134 | } | ||
| 135 | }) | ||
| 136 | |||
| 137 | if (isMore) { | ||
| 138 | studentList.value = [...studentList.value, ...rows] | ||
| 139 | } else { | ||
| 140 | studentList.value = rows | ||
| 141 | } | ||
| 142 | |||
| 143 | noMore.value = rows.length < pageSize | ||
| 144 | pageNum.value++ | ||
| 145 | loading.value = false | ||
| 146 | }).catch(() => { | ||
| 147 | loading.value = false | ||
| 148 | }) | ||
| 149 | } | ||
| 150 | |||
| 151 | function loadMore() { | ||
| 152 | if (!noMore.value) { | ||
| 153 | getStudentList(true) | ||
| 154 | } | ||
| 155 | } | ||
| 156 | |||
| 157 | function searchStudents() { | ||
| 158 | pageNum.value = 1 | ||
| 159 | noMore.value = false | ||
| 160 | getStudentList() | ||
| 161 | } | ||
| 162 | |||
| 163 | function clearSearch() { | ||
| 164 | searchName.value = '' | ||
| 165 | searchStudents() | ||
| 166 | } | ||
| 167 | |||
| 168 | function toggleSelect(item) { | ||
| 169 | item.checked = !item.checked | ||
| 170 | if (item.checked) { | ||
| 171 | selectedList.value.push({ | ||
| 172 | perId: item.perId, | ||
| 173 | name: item.name, | ||
| 174 | photo: item.photo | ||
| 175 | }) | ||
| 176 | } else { | ||
| 177 | const index = selectedList.value.findIndex(s => s.perId === item.perId) | ||
| 178 | if (index > -1) { | ||
| 179 | selectedList.value.splice(index, 1) | ||
| 180 | } | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | function removeSelected(index) { | ||
| 185 | const item = selectedList.value[index] | ||
| 186 | const student = studentList.value.find(s => s.perId === item.perId) | ||
| 187 | if (student) { | ||
| 188 | student.checked = false | ||
| 189 | } | ||
| 190 | selectedList.value.splice(index, 1) | ||
| 191 | } | ||
| 192 | |||
| 193 | function confirmSelect() { | ||
| 194 | if (selectedList.value.length === 0) { | ||
| 195 | uni.showToast({ title: '请选择考生', icon: 'none' }) | ||
| 196 | return | ||
| 197 | } | ||
| 198 | |||
| 199 | uni.showLoading({ title: '添加中...' }) | ||
| 200 | api.batchChoose({ | ||
| 201 | examId: examId, | ||
| 202 | perIds: selectedList.value.map(s => s.perId) | ||
| 203 | }).then(() => { | ||
| 204 | uni.hideLoading() | ||
| 205 | uni.showToast({ title: '添加成功', icon: 'success' }) | ||
| 206 | setTimeout(() => { | ||
| 207 | uni.navigateBack() | ||
| 208 | }, 1500) | ||
| 209 | }).catch(() => { | ||
| 210 | uni.hideLoading() | ||
| 211 | }) | ||
| 212 | } | ||
| 213 | |||
| 214 | function goBack() { | ||
| 215 | uni.navigateBack() | ||
| 216 | } | ||
| 217 | |||
| 218 | function formatDate(dateStr) { | ||
| 219 | if (!dateStr) return '-' | ||
| 220 | return dateStr.substring(0, 10) | ||
| 221 | } | ||
| 222 | |||
| 223 | function formatLevel(level) { | ||
| 224 | if (!level || level == 0) return '十级' | ||
| 225 | const hzArr = ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十'] | ||
| 226 | return hzArr[parseInt(level)] + '级' | ||
| 227 | } | ||
| 228 | </script> | ||
| 229 | |||
| 230 | <style lang="scss" scoped> | ||
| 231 | .choose-student-page { | ||
| 232 | min-height: 100vh; | ||
| 233 | background: #f5f5f5; | ||
| 234 | display: flex; | ||
| 235 | flex-direction: column; | ||
| 236 | } | ||
| 237 | |||
| 238 | /* 搜索头部 */ | ||
| 239 | .search-header { | ||
| 240 | display: flex; | ||
| 241 | align-items: center; | ||
| 242 | padding: 20rpx 30rpx; | ||
| 243 | background: #fff; | ||
| 244 | border-bottom: 1rpx solid #f0f0f0; | ||
| 245 | |||
| 246 | .search-box { | ||
| 247 | flex: 1; | ||
| 248 | display: flex; | ||
| 249 | align-items: center; | ||
| 250 | padding: 0 20rpx; | ||
| 251 | height: 64rpx; | ||
| 252 | background: #f5f5f5; | ||
| 253 | border-radius: 32rpx; | ||
| 254 | |||
| 255 | .search-input { | ||
| 256 | flex: 1; | ||
| 257 | height: 100%; | ||
| 258 | font-size: 26rpx; | ||
| 259 | margin-left: 10rpx; | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | .cancel-btn { | ||
| 264 | margin-left: 20rpx; | ||
| 265 | font-size: 28rpx; | ||
| 266 | color: #666; | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | /* 已选区域 */ | ||
| 271 | .selected-section { | ||
| 272 | background: #fff; | ||
| 273 | padding: 20rpx 30rpx; | ||
| 274 | border-bottom: 1rpx solid #f0f0f0; | ||
| 275 | |||
| 276 | .section-header { | ||
| 277 | display: flex; | ||
| 278 | align-items: center; | ||
| 279 | margin-bottom: 16rpx; | ||
| 280 | |||
| 281 | .section-title { | ||
| 282 | font-size: 26rpx; | ||
| 283 | font-weight: 600; | ||
| 284 | color: #333; | ||
| 285 | } | ||
| 286 | |||
| 287 | .section-count { | ||
| 288 | margin-left: 12rpx; | ||
| 289 | font-size: 24rpx; | ||
| 290 | color: #AD181F; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | |||
| 294 | .selected-scroll { | ||
| 295 | white-space: nowrap; | ||
| 296 | |||
| 297 | .selected-item { | ||
| 298 | display: inline-flex; | ||
| 299 | align-items: center; | ||
| 300 | position: relative; | ||
| 301 | margin-right: 24rpx; | ||
| 302 | |||
| 303 | .avatar-small { | ||
| 304 | width: 64rpx; | ||
| 305 | height: 64rpx; | ||
| 306 | border-radius: 50%; | ||
| 307 | background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%); | ||
| 308 | overflow: hidden; | ||
| 309 | display: flex; | ||
| 310 | align-items: center; | ||
| 311 | justify-content: center; | ||
| 312 | |||
| 313 | text { | ||
| 314 | font-size: 24rpx; | ||
| 315 | color: #fff; | ||
| 316 | } | ||
| 317 | |||
| 318 | image { | ||
| 319 | width: 100%; | ||
| 320 | height: 100%; | ||
| 321 | } | ||
| 322 | } | ||
| 323 | |||
| 324 | .name-small { | ||
| 325 | display: block; | ||
| 326 | text-align: center; | ||
| 327 | font-size: 22rpx; | ||
| 328 | color: #666; | ||
| 329 | margin-top: 8rpx; | ||
| 330 | width: 80rpx; | ||
| 331 | overflow: hidden; | ||
| 332 | text-overflow: ellipsis; | ||
| 333 | white-space: nowrap; | ||
| 334 | } | ||
| 335 | |||
| 336 | .remove-btn { | ||
| 337 | position: absolute; | ||
| 338 | top: -6rpx; | ||
| 339 | right: -6rpx; | ||
| 340 | width: 28rpx; | ||
| 341 | height: 28rpx; | ||
| 342 | background: #999; | ||
| 343 | border-radius: 50%; | ||
| 344 | display: flex; | ||
| 345 | align-items: center; | ||
| 346 | justify-content: center; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 352 | /* 考生列表 */ | ||
| 353 | .student-scroll { | ||
| 354 | flex: 1; | ||
| 355 | height: calc(100vh - 280rpx); | ||
| 356 | } | ||
| 357 | |||
| 358 | .student-list { | ||
| 359 | padding: 20rpx 30rpx; | ||
| 360 | |||
| 361 | .student-card { | ||
| 362 | display: flex; | ||
| 363 | align-items: center; | ||
| 364 | padding: 24rpx; | ||
| 365 | background: #fff; | ||
| 366 | border-radius: 16rpx; | ||
| 367 | margin-bottom: 16rpx; | ||
| 368 | box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04); | ||
| 369 | |||
| 370 | .checkbox { | ||
| 371 | margin-right: 20rpx; | ||
| 372 | |||
| 373 | .checkbox-empty { | ||
| 374 | width: 40rpx; | ||
| 375 | height: 40rpx; | ||
| 376 | border: 2rpx solid #ddd; | ||
| 377 | border-radius: 50%; | ||
| 378 | } | ||
| 379 | |||
| 380 | image { | ||
| 381 | width: 40rpx; | ||
| 382 | height: 40rpx; | ||
| 383 | } | ||
| 384 | } | ||
| 385 | |||
| 386 | .avatar { | ||
| 387 | width: 80rpx; | ||
| 388 | height: 80rpx; | ||
| 389 | border-radius: 50%; | ||
| 390 | background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%); | ||
| 391 | overflow: hidden; | ||
| 392 | display: flex; | ||
| 393 | align-items: center; | ||
| 394 | justify-content: center; | ||
| 395 | margin-right: 20rpx; | ||
| 396 | |||
| 397 | .avatar-text { | ||
| 398 | font-size: 32rpx; | ||
| 399 | color: #fff; | ||
| 400 | font-weight: 600; | ||
| 401 | } | ||
| 402 | |||
| 403 | image { | ||
| 404 | width: 100%; | ||
| 405 | height: 100%; | ||
| 406 | } | ||
| 407 | } | ||
| 408 | |||
| 409 | .student-info { | ||
| 410 | flex: 1; | ||
| 411 | |||
| 412 | .student-name { | ||
| 413 | font-size: 28rpx; | ||
| 414 | font-weight: 600; | ||
| 415 | color: #333; | ||
| 416 | margin-bottom: 8rpx; | ||
| 417 | |||
| 418 | .per-code { | ||
| 419 | font-size: 22rpx; | ||
| 420 | color: #999; | ||
| 421 | font-weight: normal; | ||
| 422 | margin-left: 12rpx; | ||
| 423 | } | ||
| 424 | } | ||
| 425 | |||
| 426 | .student-detail { | ||
| 427 | display: flex; | ||
| 428 | gap: 20rpx; | ||
| 429 | |||
| 430 | .level-info { | ||
| 431 | font-size: 24rpx; | ||
| 432 | color: #1561CB; | ||
| 433 | } | ||
| 434 | |||
| 435 | .validity { | ||
| 436 | font-size: 24rpx; | ||
| 437 | color: #666; | ||
| 438 | } | ||
| 439 | } | ||
| 440 | } | ||
| 441 | } | ||
| 442 | |||
| 443 | .loading-more, | ||
| 444 | .no-more { | ||
| 445 | text-align: center; | ||
| 446 | padding: 30rpx; | ||
| 447 | font-size: 24rpx; | ||
| 448 | color: #999; | ||
| 449 | } | ||
| 450 | |||
| 451 | } | ||
| 452 | |||
| 453 | /* 底部固定栏 */ | ||
| 454 | .fixedBottom { | ||
| 455 | display: flex; | ||
| 456 | align-items: center; | ||
| 457 | justify-content: space-between; | ||
| 458 | padding: 20rpx 30rpx; | ||
| 459 | background: #fff; | ||
| 460 | box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.05); | ||
| 461 | |||
| 462 | .bottom-info { | ||
| 463 | .info-text { | ||
| 464 | font-size: 26rpx; | ||
| 465 | color: #666; | ||
| 466 | |||
| 467 | .count { | ||
| 468 | color: #AD181F; | ||
| 469 | font-weight: 600; | ||
| 470 | } | ||
| 471 | } | ||
| 472 | } | ||
| 473 | |||
| 474 | .btn-confirm { | ||
| 475 | padding: 0 50rpx; | ||
| 476 | height: 72rpx; | ||
| 477 | line-height: 72rpx; | ||
| 478 | background: linear-gradient(135deg, #AD181F 0%, #c42a2a 100%); | ||
| 479 | border-radius: 36rpx; | ||
| 480 | font-size: 28rpx; | ||
| 481 | color: #fff; | ||
| 482 | box-shadow: 0 4rpx 16rpx rgba(173, 24, 31, 0.3); | ||
| 483 | } | ||
| 484 | } | ||
| 485 | .empty { | ||
| 486 | display: flex; | ||
| 487 | flex-direction: column; | ||
| 488 | justify-content: center; | ||
| 489 | align-items: center; | ||
| 490 | padding: 120rpx 0; | ||
| 491 | |||
| 492 | .empty-img { | ||
| 493 | width: 300rpx; | ||
| 494 | height: 300rpx; | ||
| 495 | opacity: 0.08; | ||
| 496 | } | ||
| 497 | |||
| 498 | .empty-text { | ||
| 499 | color: #999; | ||
| 500 | font-size: 28rpx; | ||
| 501 | margin-top: 20rpx; | ||
| 502 | } | ||
| 503 | } | ||
| 504 | </style> |
| ... | @@ -680,7 +680,16 @@ | ... | @@ -680,7 +680,16 @@ |
| 680 | "enablePullDownRefresh": false | 680 | "enablePullDownRefresh": false |
| 681 | } | 681 | } |
| 682 | 682 | ||
| 683 | }, { | 683 | }, |
| 684 | { | ||
| 685 | "path": "chooseStudent", | ||
| 686 | "style": { | ||
| 687 | "navigationBarTitleText": "添加考生", | ||
| 688 | "enablePullDownRefresh": false | ||
| 689 | } | ||
| 690 | |||
| 691 | }, | ||
| 692 | { | ||
| 684 | "path": "addApply", | 693 | "path": "addApply", |
| 685 | "style": { | 694 | "style": { |
| 686 | "navigationBarTitleText": "编辑级位考试", | 695 | "navigationBarTitleText": "编辑级位考试", | ... | ... |
-
Please register or sign in to post a comment