Compare commits
14 Commits
Author | SHA1 | Date |
---|---|---|
|
36646769bf | 4 years ago |
|
d9f4a5c622 | 4 years ago |
|
92731e5746 | 4 years ago |
|
20533e659b | 4 years ago |
|
ac70807c1b | 4 years ago |
|
d5da716645 | 4 years ago |
|
c1331ac55c | 4 years ago |
|
b6bfe30f5f | 4 years ago |
|
c496f8cdd6 | 4 years ago |
|
9c5f6ca845 | 4 years ago |
|
ca48d6efb3 | 4 years ago |
|
5ea7028879 | 4 years ago |
|
f02084c64f | 4 years ago |
|
34a948c865 | 4 years ago |
22 changed files with 1378 additions and 107 deletions
@ -1,10 +1,10 @@ |
|||
VUE_APP_MODE=production |
|||
VUE_APP_NODE_ENV=production |
|||
VUE_APP_SCENE=checkwork |
|||
VUE_APP_BASE_URL=https://test.tall.wiki/checkwork/ |
|||
VUE_APP_API_URL=https://test.tall.wiki/checkwork/gateway |
|||
VUE_APP_SCENE= |
|||
VUE_APP_BASE_URL=https://test.tall.wiki/ |
|||
VUE_APP_API_URL=https://test.tall.wiki/gateway |
|||
VUE_APP_PROXY_URL=/gateway |
|||
VUE_APP_PUBLIC_PATH=/checkwork |
|||
VUE_APP_PUBLIC_PATH=/ts |
|||
VUE_APP_MSG_URL=wss://test.tall.wiki/websocket/message/v4.0/ws |
|||
VUE_APP_TITLE=考勤管理 |
|||
VUE_APP_DESCRIPTION=考勤管理 |
|||
|
Binary file not shown.
@ -1,18 +1,30 @@ |
|||
import axios from 'axios'; |
|||
|
|||
const defaultwbs = `https://test.tall.wiki/gateway/defaultwbs`; |
|||
const defaultwbs = `https://test.tall.wiki/gateway/sports`; |
|||
|
|||
// 查询考勤信息
|
|||
export const clockQuery = params => axios.post(`${defaultwbs}/clock/query`, params); |
|||
// 查询用户信息
|
|||
export const getUserInfo = params => axios.post(`${defaultwbs}/player/info`, params); |
|||
|
|||
// 查询考勤信息
|
|||
export const clockPunch = params => axios.post(`${defaultwbs}/clock/punch`, params); |
|||
// 报名信息提交
|
|||
export const submitSignUp = params => axios.post(`${defaultwbs}/player/apply`, params); |
|||
|
|||
// 查询所有成员
|
|||
export const queryChecker = params => axios.post(`${defaultwbs}/deliver/queryChecker`, params); |
|||
// 培训目标列表
|
|||
export const getPositionList = params => axios.post(`${defaultwbs}/player/position`, params); |
|||
|
|||
// 查询所有成员
|
|||
export const clockAudit = params => axios.post(`${defaultwbs}/clock/audit`, params); |
|||
// 缴费
|
|||
export const toPay = params => axios.post(`${defaultwbs}/player/savePay`, params); |
|||
|
|||
// 导出考勤excel
|
|||
export const clockExport = params => axios.post(`${defaultwbs}/clock/export`, params); |
|||
// 上传文件
|
|||
export const uploadImg = `${defaultwbs}/file/upload`; |
|||
|
|||
// 学员列表
|
|||
export const studentList = params => axios.post(`${defaultwbs}/player/query`, params); |
|||
|
|||
// 待审核结业申请
|
|||
export const auditList = params => axios.post(`${defaultwbs}/teacher/getCompletePlayer`, params); |
|||
|
|||
// 审核结业申请
|
|||
export const auditApply = params => axios.post(`${defaultwbs}/teacher/auditComplete`, params); |
|||
|
|||
// 发证
|
|||
export const certificate = params => axios.post(`${defaultwbs}/player/certificate`, params); |
|||
|
@ -0,0 +1,317 @@ |
|||
<template> |
|||
<div class="apply-flex"> |
|||
<div class="title">个人基本信息</div> |
|||
|
|||
<div class="container px-6 bg-white"> |
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">姓名<span class="text-red-500 ml-1 align-middle">*</span></div> |
|||
<input class="text-right outline-none" v-model="name" type="text" placeholder="请输入您的姓名" /> |
|||
</div> |
|||
|
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">身份证号<span class="text-red-500 ml-1 align-middle">*</span></div> |
|||
<input class="text-right outline-none" v-model="idCard" type="text" placeholder="请输入您的身份证号" /> |
|||
</div> |
|||
|
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">年龄</div> |
|||
<input class="text-right outline-none" v-model="age" type="number" placeholder="请输入您的年龄" /> |
|||
</div> |
|||
|
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">性别</div> |
|||
<a-radio-group v-model="gender" @change="onChange"> |
|||
<a-radio :value="1"> 男 </a-radio> |
|||
<a-radio :value="0"> 女 </a-radio> |
|||
</a-radio-group> |
|||
</div> |
|||
|
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">身份<span class="text-red-500 ml-1 align-middle">*</span></div> |
|||
<div class="flex justify-end items-center" @click="openMenu(1)"> |
|||
<span class="mr-1 truncate">{{ positionName }}</span> |
|||
<a-icon type="right" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="title">联系方式</div> |
|||
|
|||
<div class="container px-6 bg-white"> |
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">地址</div> |
|||
<input class="text-right outline-none" v-model="address" type="text" placeholder="请输入您的详细地址" /> |
|||
</div> |
|||
|
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">电话<span class="text-red-500 ml-1 align-middle">*</span></div> |
|||
<input class="text-right outline-none" v-model="phone" type="text" placeholder="请输入您的电话" /> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="title">培训信息</div> |
|||
|
|||
<div class="container px-6 bg-white"> |
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">培训目标<span class="text-red-500 ml-1 align-middle">*</span></div> |
|||
<div class="flex justify-end items-center" @click="openMenu(2)"> |
|||
<span class="mr-1 truncate">{{ targetName }}</span> |
|||
<a-icon type="right" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="mt-14 px-6" v-if="!isApply"> |
|||
<button class="bg-blue-500 text-white w-full h-10 rounded" @click="submitSignUp">立即报名</button> |
|||
</div> |
|||
|
|||
<div class="fixed top-0 bottom-0 left-0 right-0 bg-black bg-opacity-60" v-if="showMenu"> |
|||
<div class="target-list absolute bottom-0 w-full bg-white"> |
|||
<div class="item-box text-center font-semibold border-b">{{ title }}</div> |
|||
<div class="list"> |
|||
<div class="item-box text-center" v-for="(item, index) in targetList" :key="index" :id="item.id" @click="selectTarget(item)"> |
|||
{{ item.name }} |
|||
</div> |
|||
</div> |
|||
<div class="bg-gray-300 h-2"></div> |
|||
<div class="item-box text-center" @click="cancel">取消</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div> |
|||
<div class="w-screen h-screen fixed z-10 statusChoose bg-black bg-opacity-50" style="display: none; top: 0; left: 0"> |
|||
<div class="flex flex-col absolute w-full bg-white" style="bottom: 0"> |
|||
<div class="flex flex-row justify-between px-5 py-4"> |
|||
<span class="text-gray-400" onclick="hide()">取消</span> |
|||
<span class="text-blue-500" onclick="choose()">确定</span> |
|||
</div> |
|||
<div class="bg-gray-200" style="width: 100%; height: 1px"></div> |
|||
<ul class="flex flex-col text-center" style="height: 240px; overflow-y: auto"></ul> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState, mapMutations } from 'vuex'; |
|||
import { getUserInfo, submitSignUp, getPositionList } from '@/config/api'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
timer: null, |
|||
name: '', // 姓名 |
|||
idCard: '', // 身份证 |
|||
age: '', // 年龄 |
|||
gender: -1, // 性别 |
|||
genderName: '', // 性别 |
|||
positionId: 0, // 身份 |
|||
positionName: '请选择当前身份', // 身份 |
|||
address: '', // 地址 |
|||
phone: '', // 手机 |
|||
targetId: 0, // 目标 |
|||
targetName: '请选择培训目标', // 目标名称 |
|||
targetList: [], |
|||
showMenu: false, |
|||
isApply: 1, // 是否已经报完名 |
|||
title: '', |
|||
playerId: '', |
|||
currType: 1, |
|||
}; |
|||
}, |
|||
|
|||
computed: mapState('home', ['projectId', 'roleId']), |
|||
|
|||
mounted() { |
|||
this.timer = setInterval(async () => { |
|||
if (this.projectId) { |
|||
clearInterval(this.timer); |
|||
await this.getUserInfo(); |
|||
await this.getTargetList(); |
|||
} |
|||
}, 300); |
|||
}, |
|||
|
|||
methods: { |
|||
onChange(e) { |
|||
this.gender = e.target.value; |
|||
}, |
|||
|
|||
async openMenu(type) { |
|||
this.currType = type; |
|||
if (type === 1) { |
|||
this.title = '当前身份'; |
|||
} else { |
|||
this.title = '培训目标'; |
|||
} |
|||
await this.getTargetList(); |
|||
this.showMenu = true; |
|||
}, |
|||
|
|||
cancel() { |
|||
this.showMenu = false; |
|||
}, |
|||
|
|||
/** |
|||
* 选择培训目标 |
|||
*/ |
|||
selectTarget(item) { |
|||
this.cancel(); |
|||
if (this.currType == 1) { |
|||
this.positionId = item.id; |
|||
this.positionName = item.name; |
|||
} else if (this.currType == 2) { |
|||
this.targetId = item.id; |
|||
this.targetName = item.name; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 培训目标列表 |
|||
*/ |
|||
async getTargetList() { |
|||
try { |
|||
const params = { param: {} }; |
|||
const res = await getPositionList(); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200) { |
|||
this.targetList = data; |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 报名 |
|||
*/ |
|||
async submitSignUp() { |
|||
try { |
|||
if (!this.name) { |
|||
this.$message.info('请输入姓名'); |
|||
return false; |
|||
} |
|||
|
|||
if (!this.idCard) { |
|||
this.$message.info('请输入身份证号'); |
|||
return false; |
|||
} |
|||
|
|||
if (this.positionId === 0) { |
|||
this.$message.info('请选择当前身份等级'); |
|||
return false; |
|||
} |
|||
|
|||
if (!this.phone) { |
|||
this.$message.info('请输入手机号'); |
|||
return false; |
|||
} |
|||
|
|||
if (this.targetId === 0) { |
|||
this.$message.info('请选择培训目标'); |
|||
return false; |
|||
} |
|||
|
|||
const params = { |
|||
param: { |
|||
projectId: this.projectId, |
|||
name: this.name, |
|||
idCard: this.idCard, |
|||
age: this.age, |
|||
gender: this.gender, |
|||
positionId: this.positionId, |
|||
address: this.address, |
|||
phone: this.phone, |
|||
targetId: this.targetId, |
|||
}, |
|||
}; |
|||
|
|||
const res = await submitSignUp(params); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200) { |
|||
window.history.back(); |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 个人信息 |
|||
*/ |
|||
async getUserInfo() { |
|||
try { |
|||
const params = { param: { projectId: this.projectId } }; |
|||
const res = await getUserInfo(params); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200) { |
|||
if (data) { |
|||
this.isApply = 1; |
|||
this.name = data.name; |
|||
this.idCard = data.idCard; |
|||
this.age = data.age; |
|||
this.genderName = data.gender == 1 ? '男' : '女'; |
|||
this.gender = data.gender; |
|||
this.positionName = data.position; |
|||
this.address = data.address; |
|||
this.phone = data.phone; |
|||
this.targetName = data.target; |
|||
} else { |
|||
this.isApply = 0; |
|||
} |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.apply-flex { |
|||
width: 100%; |
|||
min-height: 100vh; |
|||
background: #f3f3f3; |
|||
|
|||
.title { |
|||
padding-top: 12px; |
|||
padding-left: 16px; |
|||
height: 48px; |
|||
line-height: 36px; |
|||
} |
|||
|
|||
.item-box { |
|||
height: 48px; |
|||
line-height: 48px; |
|||
|
|||
.item-title { |
|||
width: 80px; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
input { |
|||
height: 40px; |
|||
width: calc(100% - 80px); |
|||
} |
|||
|
|||
input:disabled { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
div.flex { |
|||
width: calc(100% - 80px); |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,129 @@ |
|||
<template> |
|||
<div class="list-flex"> |
|||
<div class="px-4 pb-2 bg-white"> |
|||
<div class="title flex items-center justify-between border-b"> |
|||
<div class="text-gray-400 text-center" style="width: 30%">ID</div> |
|||
<div class="text-gray-400 text-center" style="width: 25%">姓名</div> |
|||
<div class="text-gray-400 text-center" style="width: 40%">操作</div> |
|||
</div> |
|||
|
|||
<div> |
|||
<div class="item title flex items-center justify-around border-b"> |
|||
<div class="text-center" style="width: 30%">123456789</div> |
|||
<div class="text-center" style="width: 25%">薛思男</div> |
|||
<div class="text-center flex justify-center items-center" style="width: 40%"> |
|||
<button class="btn px-2 border border-blue-500 bg-blue-500 text-white rounded-sm" @click="certificate(id)">发证</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="item title flex items-center justify-around border-b"> |
|||
<div class="text-center" style="width: 30%">123456789</div> |
|||
<div class="text-center" style="width: 25%">薛思男</div> |
|||
<div class="text-center flex justify-center items-center" style="width: 40%"> |
|||
<button class="btn px-2 border border-blue-500 bg-blue-500 text-white rounded-sm" @click="certificate(id)">发证</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="item title flex items-center justify-around border-b"> |
|||
<div class="text-center" style="width: 30%">123456789</div> |
|||
<div class="text-center" style="width: 25%">薛思男</div> |
|||
<div class="text-center flex justify-center items-center" style="width: 40%"> |
|||
<button class="btn px-2 border border-blue-500 bg-blue-500 text-white rounded-sm" @click="certificate(id)">发证</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState } from 'vuex'; |
|||
import { auditList, certificate } from '@/config/api'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
timer: null, |
|||
lists: [], |
|||
}; |
|||
}, |
|||
|
|||
computed: mapState('home', ['projectId', 'roleId']), |
|||
|
|||
mounted() { |
|||
this.timer = setInterval(async () => { |
|||
if (this.projectId) { |
|||
clearInterval(this.timer); |
|||
await this.getAuditList(); |
|||
} |
|||
}, 300); |
|||
}, |
|||
|
|||
methods: { |
|||
/** |
|||
* 获取待审核结业申请列表 |
|||
*/ |
|||
async getAuditList() { |
|||
try { |
|||
const params = { param: { projectId: this.projectId } }; |
|||
const res = await auditList(); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200) { |
|||
this.lists = data; |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 发证 |
|||
*/ |
|||
async certificate(playerId) { |
|||
try { |
|||
const params = { |
|||
param: { |
|||
projectId: this.projectId, |
|||
playerId: playerId, |
|||
type: type, |
|||
remark: this.remark, |
|||
}, |
|||
}; |
|||
const res = await certificate(); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200) { |
|||
this.getAuditList(); |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.list-flex { |
|||
width: 100%; |
|||
min-height: 100vh; |
|||
background: #f3f3f3; |
|||
|
|||
.title { |
|||
height: 48px; |
|||
line-height: 48px; |
|||
} |
|||
|
|||
.item { |
|||
.btn { |
|||
height: 26px; |
|||
line-height: 24px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,156 @@ |
|||
<template> |
|||
<div class="list-flex"> |
|||
<div class="px-4 pb-2 bg-white"> |
|||
<div class="title flex items-center justify-between border-b"> |
|||
<div class="text-gray-400 text-center" style="width: 30%">ID</div> |
|||
<div class="text-gray-400 text-center" style="width: 25%">姓名</div> |
|||
<div class="text-gray-400 text-center" style="width: 40%">操作</div> |
|||
</div> |
|||
|
|||
<div> |
|||
<div class="item title flex items-center justify-around border-b"> |
|||
<div class="text-center" style="width: 30%">123456789</div> |
|||
<div class="text-center" style="width: 25%">薛思男</div> |
|||
<div class="text-center flex justify-center items-center" style="width: 40%"> |
|||
<button class="btn mr-2 px-2 border border-blue-500 text-blue-500 rounded-sm" @click="rejectModal">驳回</button> |
|||
<button class="btn px-2 border border-blue-500 bg-blue-500 text-white rounded-sm" @click="auditApply(2)">通过</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="item title flex items-center justify-around border-b"> |
|||
<div class="text-center" style="width: 30%">123456789</div> |
|||
<div class="text-center" style="width: 25%">薛思男</div> |
|||
<div class="text-center flex justify-center items-center" style="width: 40%"> |
|||
<button class="btn mr-2 px-2 border border-blue-500 text-blue-500 rounded-sm">驳回</button> |
|||
<button class="btn px-2 border border-blue-500 bg-blue-500 text-white rounded-sm">通过</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="item title flex items-center justify-around border-b"> |
|||
<div class="text-center" style="width: 30%">123456789</div> |
|||
<div class="text-center" style="width: 25%">薛思男</div> |
|||
<div class="text-center flex justify-center items-center" style="width: 40%"> |
|||
<button class="btn mr-2 px-2 border border-blue-500 text-blue-500 rounded-sm">驳回</button> |
|||
<button class="btn px-2 border border-blue-500 bg-blue-500 text-white rounded-sm">通过</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<a-modal title="驳回原因" :visible="visible" @ok="handleOk" @cancel="handleCancel"> |
|||
<textarea class="reject-con border border-gray-200 w-full rounded-sm p-2" v-model="modalText" placeholder="请输入驳回原因" /> |
|||
</a-modal> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState } from 'vuex'; |
|||
import { auditList, auditApply } from '@/config/api'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
timer: null, |
|||
lists: [], |
|||
playerId: '', |
|||
remark: '', |
|||
visible: false, |
|||
modalText: '', |
|||
showModal: false, |
|||
}; |
|||
}, |
|||
|
|||
computed: mapState('home', ['projectId', 'roleId']), |
|||
|
|||
mounted() { |
|||
this.timer = setInterval(async () => { |
|||
if (this.projectId) { |
|||
clearInterval(this.timer); |
|||
await this.getAuditList(); |
|||
} |
|||
}, 300); |
|||
}, |
|||
|
|||
methods: { |
|||
// 驳回 |
|||
rejectModal() { |
|||
this.visible = true; |
|||
}, |
|||
|
|||
handleOk(e) { |
|||
this.remark = this.modalText; |
|||
this.visible = false; |
|||
this.auditApply(3); |
|||
}, |
|||
|
|||
handleCancel(e) { |
|||
this.visible = false; |
|||
}, |
|||
|
|||
/** |
|||
* 获取待审核结业申请列表 |
|||
*/ |
|||
async getAuditList() { |
|||
try { |
|||
const params = { param: { projectId: this.projectId } }; |
|||
const res = await auditList(); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200) { |
|||
this.lists = data; |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 审核结业申请 |
|||
*/ |
|||
async auditApply(type) { |
|||
try { |
|||
const params = { |
|||
param: { |
|||
projectId: this.projectId, |
|||
playerId: this.playerId, |
|||
type: type, |
|||
remark: this.remark, |
|||
}, |
|||
}; |
|||
const res = await auditList(); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200) { |
|||
this.getAuditList(); |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.list-flex { |
|||
width: 100%; |
|||
min-height: 100vh; |
|||
background: #f3f3f3; |
|||
|
|||
.title { |
|||
height: 48px; |
|||
line-height: 48px; |
|||
} |
|||
|
|||
.item { |
|||
.btn { |
|||
height: 26px; |
|||
line-height: 24px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,275 @@ |
|||
<template> |
|||
<div> |
|||
<!-- <div |
|||
data-tname="文件" |
|||
data-pid="1433332016270811136" |
|||
data-uid="1217647686598135808" |
|||
data-rid="rid333" |
|||
data-tid="tid444" |
|||
data-did="did555" |
|||
style="height: 5.375rem; width: 100%" |
|||
> --> |
|||
<div data-root="p1432643387798069248" style="height: 100%; width: 100%"> |
|||
<div class="title"></div> |
|||
<ul> |
|||
<li><img src="./img/640.webp" alt="" /></li> |
|||
<li><img src="./img/640 (1).webp" alt="" /></li> |
|||
<li><img src="./img/640 (2).webp" alt="" /></li> |
|||
<li><img src="./img/640 (3).webp" alt="" /></li> |
|||
<li><img src="./img/640 (4).webp" alt="" /></li> |
|||
<li><img src="./img/640 (5).webp" alt="" /></li> |
|||
</ul> |
|||
</div> |
|||
<!-- </div> --> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
// import { mapState, mapMutations } from 'vuex'; |
|||
// import { clockQuery, clockPunch, clockAudit } from '@/config/api'; |
|||
|
|||
// const columns = [ |
|||
// { title: '姓名', dataIndex: 'memberName', key: 'memberName', align: 'center', width: '16%' }, |
|||
// { title: '早', dataIndex: 'morning', key: 'morning', scopedSlots: { customRender: 'morning' }, align: 'center', width: '27%' }, |
|||
// { title: '晚', dataIndex: 'night', key: 'night', scopedSlots: { customRender: 'night' }, align: 'center', width: '27%' }, |
|||
// { |
|||
// title: '审核人', |
|||
// dataIndex: 'checkerName', |
|||
// key: 'checkerName', |
|||
// scopedSlots: { customRender: 'checkerName' }, |
|||
// align: 'center', |
|||
// width: '30%', |
|||
// }, |
|||
// ]; |
|||
|
|||
// export default { |
|||
// data() { |
|||
// return { |
|||
// columns, |
|||
// clockInfos: [], |
|||
// options: null, |
|||
// checkerId: undefined, |
|||
// placement: 'left', |
|||
// timer: null, |
|||
// chooseTime: '', |
|||
// auditOptions: null, |
|||
// morningLoading: false, |
|||
// nightLoading: false, |
|||
// today: this.$moment(new Date()).format('YYYY-MM-DD'), |
|||
// selectedDate: '', // 当前选择的日期 |
|||
// }; |
|||
// }, |
|||
|
|||
// computed: mapState('home', ['projectId', 'members', 'startTime', 'endTime', 'memberIdList', 'roleId', 'checkers']), |
|||
|
|||
// mounted() { |
|||
// this.timer = setInterval(async () => { |
|||
// if (this.projectId) { |
|||
// clearInterval(this.timer); |
|||
// await this.setParams(); |
|||
|
|||
// // 自动移动到目标位置 |
|||
// // document.querySelector('#scrollTo').scrollIntoView({ |
|||
// // behavior: 'smooth', // 平滑过渡 |
|||
// // block: 'start', // 上边框与视窗顶部平齐。默认值 |
|||
// // }); |
|||
// } |
|||
// }, 300); |
|||
|
|||
// const time = this.$moment(Date.now()).format('YYYY-MM-DD'); |
|||
// if (!this.startTime) { |
|||
// this.setStartTime(this.$moment(`${time} 00:00`).format('x') - 0); |
|||
// } |
|||
// if (!this.endTime) { |
|||
// this.setEndTime(this.$moment(`${time} 23:59`).format('x') - 0); |
|||
// } |
|||
// }, |
|||
|
|||
// methods: { |
|||
// ...mapMutations('home', ['setStartTime', 'setEndTime', 'setMemberIdList']), |
|||
|
|||
// async setParams() { |
|||
// const { projectId, startTime, endTime, memberIdList, roleId } = this; |
|||
// const params = { param: { projectId, memberIdList, startTime, endTime, roleId } }; |
|||
// await this.getClockQuery(params); |
|||
// }, |
|||
|
|||
// /** |
|||
// * 查询考勤信息 |
|||
// * @param {string} projectId |
|||
// * @param {array} memberIdList |
|||
// * @param {string} startTime |
|||
// * @param {string} endTime |
|||
// */ |
|||
// async getClockQuery(params) { |
|||
// try { |
|||
// const res = await clockQuery(params); |
|||
// const { code, msg, data } = res.data; |
|||
// if (code === 200) { |
|||
// data.forEach(item => { |
|||
// item.recordList.forEach(clcok => { |
|||
// clcok.morningVisible = false; |
|||
// clcok.nightVisible = false; |
|||
// clcok.showNightTime = false; |
|||
// clcok.showMorningTime = false; |
|||
// }); |
|||
// }); |
|||
|
|||
// this.clockInfos = [...data]; |
|||
// } else { |
|||
// this.$message.error(msg || '获取失败'); |
|||
// throw msg; |
|||
// } |
|||
// } catch (error) { |
|||
// throw error || '获取失败'; |
|||
// } |
|||
// }, |
|||
|
|||
// // 选择审核人 |
|||
// chooseChecker(value) { |
|||
// this.checkerId = value; |
|||
// }, |
|||
|
|||
// // 打卡 |
|||
// checkTime(listIndex, index, clockType, id, memberId, checkerId, clockTime) { |
|||
// const time = Date.now(); |
|||
// const selectTime = this.$moment(time).format('HH:mm'); |
|||
// if (clockType === 0) { |
|||
// this.clockInfos[listIndex].recordList[index].morning = selectTime; |
|||
// } else { |
|||
// this.clockInfos[listIndex].recordList[index].night = selectTime; |
|||
// } |
|||
// const dateTime = this.$moment(`${clockTime} ${selectTime}`).format('x') - 0; |
|||
// const params = { param: { checkerId: this.checkerId || checkerId || this.checkers[0].memberId, clockType, dateTime, id, memberId } }; |
|||
// this.handleClockPunch(params); |
|||
// }, |
|||
|
|||
// /** |
|||
// * 打卡 |
|||
// * @param {string} checkerId 审核员id |
|||
// * @param {array} clockType 打卡类型(0-早,1-晚) |
|||
// * @param {string} dateTime 打卡时间 |
|||
// * @param {string} id 记录id(没有则不传) |
|||
// * @param {string} memberId 考勤信息中的成员id |
|||
// */ |
|||
// async handleClockPunch(params) { |
|||
// try { |
|||
// if (params.param.clockType === 0) { |
|||
// this.morningLoading = true; |
|||
// } else { |
|||
// this.nightLoading = true; |
|||
// } |
|||
// const res = await clockPunch(params); |
|||
// const { code, msg } = res.data; |
|||
// if (code === 200) { |
|||
// this.$message.success('打卡成功'); |
|||
// const options = { startTime: this.startTime, endTime: this.endTime, memberIdList: this.memberIdList }; |
|||
// this.setParams(options); |
|||
// } else { |
|||
// this.$message.error(msg || '打卡失败'); |
|||
// throw msg; |
|||
// } |
|||
// if (params.param.clockType === 0) { |
|||
// this.morningLoading = false; |
|||
// } else { |
|||
// this.nightLoading = false; |
|||
// } |
|||
// } catch (error) { |
|||
// if (params.param.clockType === 0) { |
|||
// this.morningLoading = false; |
|||
// } else { |
|||
// this.nightLoading = false; |
|||
// } |
|||
// throw error || '打卡失败'; |
|||
// } |
|||
// }, |
|||
|
|||
// changeVisible(index, status, type) { |
|||
// if (status !== 0) { |
|||
// this.clockInfos.forEach(item => { |
|||
// item.recordList.forEach((clcok, i) => { |
|||
// if (i === index && type === 'morningVisible') { |
|||
// clcok.morningVisible = !clcok.morningVisible; |
|||
// clcok.nightVisible = false; |
|||
// } else if (i === index && type === 'nightVisible') { |
|||
// clcok.morningVisible = false; |
|||
// clcok.nightVisible = !clcok.nightVisible; |
|||
// } else { |
|||
// clcok.morningVisible = false; |
|||
// clcok.nightVisible = false; |
|||
// } |
|||
// }); |
|||
// }); |
|||
// } |
|||
// }, |
|||
|
|||
// // 修改 |
|||
// changeStatus(id, type, record, visible, show, selectedDate) { |
|||
// record[visible] = false; |
|||
// record[show] = true; |
|||
// this.selectedDate = selectedDate; |
|||
// this.auditOptions = { id, type }; |
|||
// }, |
|||
// // 选择修改时间 |
|||
// timeChange(time) { |
|||
// let updateTime = this.$moment(time).format('HH:mm:ss'); |
|||
// let updateDate = this.selectedDate + ' ' + updateTime; |
|||
// this.chooseTime = this.$moment(updateDate).format('x'); |
|||
// }, |
|||
// async openChange(open, record, show, timeType) { |
|||
// if (!open && this.chooseTime) { |
|||
// this.auditOptions[timeType] = this.chooseTime; |
|||
// this.auditOptions.projectId = this.projectId; |
|||
// const params = { param: this.auditOptions }; |
|||
// await this.handleClockAudit(params, record, show); |
|||
// } |
|||
// if (!open && !this.chooseTime) { |
|||
// record[show] = false; |
|||
// } |
|||
// }, |
|||
|
|||
// // 驳回 |
|||
// async rejectStatus(id, type, timeType, time, record, show) { |
|||
// record[show] = false; |
|||
// const params = { param: { id, type, [timeType]: time, projectId: this.projectId } }; |
|||
// await this.handleClockAudit(params, record, show); |
|||
// }, |
|||
|
|||
// // 取消 |
|||
// cancel(record, type) { |
|||
// record[type] = false; |
|||
// }, |
|||
|
|||
// /** |
|||
// * 审核打卡 |
|||
// * @param {string} id 打卡记录id |
|||
// * @param {string} morning 早打卡时间 |
|||
// * @param {string} night 晚打卡时间 |
|||
// * @param {string} projectId 项目id |
|||
// * @param {string} type 审批类型(0-修改,1-驳回,2-通过) |
|||
// */ |
|||
// async handleClockAudit(params, record, show) { |
|||
// try { |
|||
// const res = await clockAudit(params); |
|||
// const { code, msg } = res.data; |
|||
// if (code === 200) { |
|||
// this.$message.success(params.param.type === 0 ? '修改成功' : params.param.type === 1 ? '驳回成功' : '审核通过'); |
|||
// record[show] = false; |
|||
// this.auditOptions = null; |
|||
// this.chooseTime = ''; |
|||
// const options = { startTime: this.startTime, endTime: this.endTime, memberIdList: this.memberIdList }; |
|||
// this.setParams(options); |
|||
// } else { |
|||
// this.$message.error(msg || '审核失败'); |
|||
// throw msg; |
|||
// } |
|||
// } catch (error) { |
|||
// throw error || '审核失败'; |
|||
// } |
|||
// }, |
|||
// }, |
|||
// }; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 75 KiB |
@ -0,0 +1,221 @@ |
|||
<template> |
|||
<div class="pay-flex"> |
|||
<div class="title">选择缴费方式</div> |
|||
|
|||
<div class="container px-6 bg-white"> |
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">微信缴费</div> |
|||
<a-icon type="right" /> |
|||
</div> |
|||
|
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">支付宝缴费</div> |
|||
<a-icon type="right" /> |
|||
</div> |
|||
|
|||
<div class="item-box flex justify-between items-center border-b"> |
|||
<div class="item-title text-gray-400">兑换券缴费</div> |
|||
<a-icon type="right" /> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="title">其他支付凭证</div> |
|||
|
|||
<div class="container px-6 pb-3 bg-white"> |
|||
<div class="item-box"> |
|||
<div class="text-gray-400">上传缴费凭证</div> |
|||
</div> |
|||
|
|||
<a-upload |
|||
list-type="picture-card" |
|||
:action="action" |
|||
:headers="headers" |
|||
name="param" |
|||
:file-list="fileList" |
|||
@preview="handlePreview" |
|||
@change="handleChange" |
|||
> |
|||
<div v-if="fileList.length < 1"> |
|||
<a-icon class="mb-2 text-xl" type="plus" /> |
|||
<div class="ant-upload-text">上传照片</div> |
|||
</div> |
|||
</a-upload> |
|||
|
|||
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel"> |
|||
<img alt="example" style="width: 100%" :src="previewImage" /> |
|||
</a-modal> |
|||
</div> |
|||
|
|||
<div class="mt-14 px-6 flex justify-between items-center"> |
|||
<a-button class="rounded" @click="back"> 稍后缴费 </a-button> |
|||
<a-button class="rounded" type="primary" @click="uploadPay"> 立即支付 </a-button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState, mapMutations } from 'vuex'; |
|||
import { toPay, uploadImg, getUserInfo } from '@/config/api'; |
|||
|
|||
function getBase64(file) { |
|||
return new Promise((resolve, reject) => { |
|||
const reader = new FileReader(); |
|||
reader.readAsDataURL(file); |
|||
reader.onload = () => resolve(reader.result); |
|||
reader.onerror = error => reject(error); |
|||
}); |
|||
} |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
timer: null, |
|||
playerId: '', |
|||
fileId: '', |
|||
previewVisible: false, |
|||
previewImage: '', |
|||
fileList: [], |
|||
action: uploadImg, |
|||
}; |
|||
}, |
|||
|
|||
computed: { |
|||
...mapState('home', ['projectId', 'roleId']), |
|||
headers() { |
|||
const token = sessionStorage.getItem('anyringToken'); |
|||
return { Authorization: `Bearer ${token}` }; |
|||
}, |
|||
}, |
|||
|
|||
mounted() { |
|||
this.timer = setInterval(async () => { |
|||
if (this.projectId) { |
|||
clearInterval(this.timer); |
|||
await this.setParams(); |
|||
} |
|||
}, 300); |
|||
}, |
|||
|
|||
methods: { |
|||
async setParams() { |
|||
const { projectId, roleId } = this; |
|||
const params = { param: { projectId } }; |
|||
await this.getUserInfo(params); |
|||
}, |
|||
|
|||
/** |
|||
* 个人信息 |
|||
*/ |
|||
async getUserInfo() { |
|||
try { |
|||
const params = { param: { projectId: this.projectId } }; |
|||
const res = await getUserInfo(params); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200 && data) { |
|||
this.playerId = data.id; |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
|
|||
handleCancel() { |
|||
this.previewVisible = false; |
|||
}, |
|||
|
|||
async handlePreview(file) { |
|||
if (!file.url && !file.preview) { |
|||
file.preview = await getBase64(file.originFileObj); |
|||
} |
|||
this.previewImage = file.url || file.preview; |
|||
this.previewVisible = true; |
|||
}, |
|||
|
|||
handleChange({ fileList }) { |
|||
this.fileList = fileList; |
|||
}, |
|||
|
|||
async uploadPay() { |
|||
let res = {}; |
|||
this.fileList.forEach((item, index) => { |
|||
if (index === 0 && item.response) { |
|||
res = item.response.data; |
|||
} |
|||
}); |
|||
|
|||
this.fileId = res.fileId; |
|||
|
|||
if (!this.fileId) { |
|||
this.$message.info('请上传支付凭证'); |
|||
return false; |
|||
} |
|||
|
|||
try { |
|||
const params = { |
|||
param: { |
|||
projectId: this.projectId, |
|||
playerId: this.playerId, |
|||
fileId: this.fileId, |
|||
}, |
|||
}; |
|||
const res = await toPay(params); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200) { |
|||
this.back(); |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
|
|||
back() { |
|||
window.history.back(); |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.pay-flex { |
|||
width: 100%; |
|||
min-height: 100vh; |
|||
background: #f3f3f3; |
|||
|
|||
.title { |
|||
padding-top: 12px; |
|||
padding-left: 16px; |
|||
height: 48px; |
|||
line-height: 36px; |
|||
} |
|||
|
|||
.item-box { |
|||
height: 48px; |
|||
line-height: 48px; |
|||
|
|||
.item-title { |
|||
width: 80px; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
input { |
|||
height: 40px; |
|||
width: calc(100% - 80px); |
|||
} |
|||
|
|||
div.flex { |
|||
width: calc(100% - 80px); |
|||
} |
|||
} |
|||
|
|||
button { |
|||
width: 45%; |
|||
height: 40px; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,118 @@ |
|||
<template> |
|||
<div class="list-flex"> |
|||
<div class="px-4 pb-2 bg-white"> |
|||
<div class="title flex items-center justify-around border-b"> |
|||
<div class="text-gray-400 text-center" style="width: 25%">姓名</div> |
|||
<div class="text-gray-400 text-center" style="width: 15%">性别</div> |
|||
<div class="text-gray-400 text-center" style="width: 15%">年龄</div> |
|||
<div class="text-gray-400 text-center" style="width: 35%">手机号</div> |
|||
<!-- <div class="text-gray-400 text-center" style="width: 30%">目标</div> --> |
|||
<!-- <div class="text-gray-400 text-center" style="width: 20%">是否缴费</div> --> |
|||
</div> |
|||
|
|||
<div> |
|||
<div class="item title flex items-center justify-around border-b" v-for="(item, index) in lists" :key="index"> |
|||
<div class="text-center" style="width: 25%">{{ item.name }}</div> |
|||
<div class="text-center" style="width: 15%">{{ item.gender === 0 ? '女' : '男' }}</div> |
|||
<div class="text-center" style="width: 15%">{{ item.age }}</div> |
|||
<div class="text-center" style="width: 35%">{{ item.phone }}</div> |
|||
<!-- <div class="text-center" style="width: 30%">目标</div> --> |
|||
<!-- <div class="text-center" style="width: 20%">是</div> --> |
|||
</div> |
|||
|
|||
<div class="item title flex items-center justify-around border-b"> |
|||
<div class="text-center" style="width: 25%">薛思男</div> |
|||
<div class="text-center" style="width: 15%">女</div> |
|||
<div class="text-center" style="width: 15%">28</div> |
|||
<div class="text-center" style="width: 35%">18435164840</div> |
|||
<!-- <div class="text-center" style="width: 30%">目标</div> --> |
|||
<!-- <div class="text-center" style="width: 20%">是</div> --> |
|||
</div> |
|||
|
|||
<div class="item title flex items-center justify-around border-b"> |
|||
<div class="text-center" style="width: 25%">薛思男</div> |
|||
<div class="text-center" style="width: 15%">女</div> |
|||
<div class="text-center" style="width: 15%">28</div> |
|||
<div class="text-center" style="width: 35%">18435164840</div> |
|||
<!-- <div class="text-center" style="width: 30%">目标</div> --> |
|||
<!-- <div class="text-center" style="width: 20%">是</div> --> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
import { mapState, mapMutations } from 'vuex'; |
|||
import { studentList } from '@/config/api'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
timer: null, |
|||
lists: [], |
|||
}; |
|||
}, |
|||
|
|||
computed: mapState('home', ['projectId', 'roleId']), |
|||
|
|||
mounted() { |
|||
this.timer = setInterval(async () => { |
|||
if (this.projectId) { |
|||
clearInterval(this.timer); |
|||
await this.getStudentList(); |
|||
|
|||
// 自动移动到目标位置 |
|||
// document.querySelector('#scrollTo').scrollIntoView({ |
|||
// behavior: 'smooth', // 平滑过渡 |
|||
// block: 'start', // 上边框与视窗顶部平齐。默认值 |
|||
// }); |
|||
} |
|||
}, 300); |
|||
}, |
|||
|
|||
methods: { |
|||
async getStudentList() { |
|||
try { |
|||
const params = { param: this.fileList[0] }; |
|||
const res = await studentList(); |
|||
const { code, msg, data } = res.data; |
|||
if (code === 200) { |
|||
this.lists = data; |
|||
} else { |
|||
this.$message.error(msg || '获取失败'); |
|||
throw msg; |
|||
} |
|||
} catch (error) { |
|||
throw error || '获取失败'; |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.list-flex { |
|||
width: 100%; |
|||
min-height: 100vh; |
|||
background: #f3f3f3; |
|||
|
|||
.title { |
|||
height: 48px; |
|||
line-height: 48px; |
|||
} |
|||
|
|||
.item-box { |
|||
height: 48px; |
|||
line-height: 48px; |
|||
|
|||
.item-title { |
|||
width: 80px; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
div.flex { |
|||
width: calc(100% - 80px); |
|||
} |
|||
} |
|||
} |
|||
</style> |
Loading…
Reference in new issue