first commit
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<!-- 导航栏 -->
|
||||
|
||||
<van-nav-bar title="资产盘点" left-text="返回" left-arrow placeholder
|
||||
@click-left="historyBack" fixed></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入编号或名称搜索"
|
||||
v-model="pageForm.searchKeyword"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.isStocktakingText"
|
||||
@change="(val)=>{this.pageForm.isStocktaking = val==='1';this.doSearch();}">
|
||||
<van-tab title="已盘点" name="1"></van-tab>
|
||||
<van-tab title="未盘点" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/asset/stocktaking/pageData" :page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
title="assetNumber" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="资产名称">{{row.assetName}}</table-column>
|
||||
<table-column label="类别名称"> {{row.assetTypeCode===1?'校工会资产':'分工会资产'}}</table-column>
|
||||
<table-column label="存放地点">{{row.assetStorageLocation}}</table-column>
|
||||
<table-column label="责任人">{{row.assetUseUserName}}</table-column>
|
||||
<table-column label="折旧到期日期"> {{$moment(row.assetRetiredAssetsDate).format('YYYY-MM-DD')}}
|
||||
</table-column>
|
||||
<table-column label="使用状况">{{row.assetUsageStateName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="!row.isStocktaking"
|
||||
:disabled="stocktakingPlanOption.length==0
|
||||
||!pageForm.assetStocktakingPlanId
|
||||
||!stocktakingPlanOption.find(p=>p.id===pageForm.assetStocktakingPlanId).isShow"
|
||||
@click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>开始盘点</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.isStocktaking"
|
||||
:disabled="stocktakingPlanOption.length==0
|
||||
||!pageForm.assetStocktakingPlanId
|
||||
||!stocktakingPlanOption.find(p=>p.id===pageForm.assetStocktakingPlanId).isShow"
|
||||
@click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>删除盘点</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
|
||||
<h5-asset-info ref="h5AssetInfoRef"></h5-asset-info>
|
||||
|
||||
<h5-asset-stocktaking-form ref="h5AssetStocktakingFormRef" @save_success="doSearch"></h5-asset-stocktaking-form>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("info.js"){}#-->
|
||||
<!--#include("stocktakingForm.js"){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
assetCategoryOption: [],
|
||||
stocktakingPlanOption: [],
|
||||
unionList: [],
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
isStocktakingText: "0",
|
||||
isStocktaking: false,
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"h5-asset-info": H5_ASSET_INFO,
|
||||
"h5-asset-stocktaking-form": H5_ASSET_STOCKTAKING_FORM,
|
||||
},
|
||||
methods: {
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要删除本次盘点信息吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/asset/stocktaking/doDelete", {
|
||||
id: row.id,
|
||||
assetStocktakingPlanId: this.pageForm.assetStocktakingPlanId
|
||||
}).then(resp => {
|
||||
if (resp.code === 0) {
|
||||
this.doSearch()
|
||||
this.$toast.success(resp.msg)
|
||||
} else {
|
||||
this.$toast.fail(resp.msg)
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
},
|
||||
onAudit(row) {
|
||||
row.assetStocktakingPlanId = this.pageForm.assetStocktakingPlanId
|
||||
this.$refs.h5AssetStocktakingFormRef.onOpen(row)
|
||||
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.h5AssetInfoRef.onOpen(row)
|
||||
},
|
||||
// 查询资产类别
|
||||
queryCategory() {
|
||||
this.$axios.post("/platform/asset/category/queryCategory").then(resp => {
|
||||
if (resp.code === 0) {
|
||||
this.assetCategoryOption = resp.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 按年度查询资产盘点计划
|
||||
async queryStocktakingPlan() {
|
||||
const resp = await this.$axios.post("/platform/asset/stocktakingPlan/queryStocktakingPlan")
|
||||
if (resp.code === 0) {
|
||||
resp.data.forEach(v => {
|
||||
const startDate = this.$moment(v.startDate).format('YYYY-MM-DD')
|
||||
const endDate = this.$moment(v.endDate).format('YYYY-MM-DD')
|
||||
v.name = startDate + "至" + endDate + "(" + v.year + ")"
|
||||
v.isShow = (this.$moment().format('YYYY-MM-DD hh:mm:ss') > v.startDate && this.$moment().format('YYYY-MM-DD hh:mm:ss') < v.endDate)
|
||||
})
|
||||
this.stocktakingPlanOption = resp.data
|
||||
if (this.stocktakingPlanOption && this.stocktakingPlanOption.length > 0) {
|
||||
this.$set(this.pageForm, "assetStocktakingPlanId", this.stocktakingPlanOption[0].id)
|
||||
} else {
|
||||
this.$set(this.pageForm, "assetStocktakingPlanId", null)
|
||||
}
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
onReady() {
|
||||
this.queryCategory()
|
||||
this.queryStocktakingPlan()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,124 @@
|
||||
const H5_ASSET_INFO = {
|
||||
template: /*language=HTML*/ `
|
||||
<van-action-sheet v-model="visible" title="查看详情" ref="actionSheetRef">
|
||||
<van-tabs v-model="activeName">
|
||||
<van-tab title="资产基本信息" name="1">
|
||||
</van-tab>
|
||||
<van-tab title="盘点信息" name="2">
|
||||
</van-tab>
|
||||
</van-tabs>
|
||||
|
||||
<div class="detail-container" v-if="activeName==='1'">
|
||||
<van-cell-group>
|
||||
<van-cell title="资产编号">
|
||||
{{ viewData.assetNumber }}
|
||||
</van-cell>
|
||||
<van-cell title="资产名称">
|
||||
{{ viewData.assetName }}
|
||||
</van-cell>
|
||||
<van-cell title="资产类别">
|
||||
{{viewData.assetCategoryName}}({{viewData.assetDepreciationYear}}年)
|
||||
</van-cell>
|
||||
<van-cell title="资产规格型号">
|
||||
{{viewData.assetSpecs}}
|
||||
</van-cell>
|
||||
<van-cell title="供应商名称">
|
||||
{{viewData.assetSupplierName}}
|
||||
</van-cell>
|
||||
<van-cell title="采购方式">
|
||||
{{viewData.assetFundingSubjectName}}
|
||||
</van-cell>
|
||||
<van-cell title="单价(元)">
|
||||
{{viewData.assetUnitPrice}}
|
||||
</van-cell>
|
||||
<van-cell title="数量(台/件)">
|
||||
{{viewData.assetQuantity}}
|
||||
</van-cell>
|
||||
<van-cell title="资产类型">
|
||||
{{viewData.assetTypeCode===1?'校工会资产':'分工会资产'}}
|
||||
</van-cell>
|
||||
<van-cell title="开始使用日期">
|
||||
{{$moment(viewData.assetUsedDate).format('YYYY-MM-DD')}}
|
||||
</van-cell>
|
||||
<van-cell title="预计报废时间">
|
||||
{{$moment(viewData.assetRetiredAssetsDate).format('YYYY-MM-DD')}}
|
||||
</van-cell>
|
||||
<van-cell title="责任人">
|
||||
{{viewData.assetUseUserName}}
|
||||
</van-cell>
|
||||
<van-cell title="使用/管理部门">
|
||||
{{viewData.assetUseUnionName}}
|
||||
</van-cell>
|
||||
<van-cell title="存放地点">
|
||||
{{viewData.assetStorageLocation}}
|
||||
</van-cell>
|
||||
<van-cell title="使用状况">
|
||||
{{viewData.assetUsageStateName}}
|
||||
</van-cell>
|
||||
<van-cell title="备注" class="direction-column-cell">
|
||||
<div style="white-space: pre">{{viewData.assetNotes}}</div>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</div>
|
||||
|
||||
<div class="detail-container" v-else-if="activeName==='2'">
|
||||
<template v-for="item in viewData.assetStocktakingList"
|
||||
v-if="viewData.assetStocktakingList&&viewData.assetStocktakingList.length>0">
|
||||
<van-cell-group :title="$moment(item.createdAt).format('YYYY-MM-DD HH:mm:ss')">
|
||||
<van-cell title="原责任人">
|
||||
{{ item.oldAssetUseUserName }}
|
||||
</van-cell>
|
||||
<van-cell title="原使用/管理部门">
|
||||
{{ item.oldAssetUseUnionName }}
|
||||
</van-cell>
|
||||
<van-cell title="原存放地点">
|
||||
{{ item.oldAssetStorageLocation }}
|
||||
</van-cell>
|
||||
<van-cell title="原使用状况">
|
||||
{{ item.oldAssetUsageStateName }}
|
||||
</van-cell>
|
||||
<!-- <van-cell title="操作时间">
|
||||
{{$moment(item.createdAt).format('YYYY-MM-DD HH:mm:ss')}}
|
||||
</van-cell>-->
|
||||
<van-cell title="旧备注" class="direction-column-cell">
|
||||
<div style="white-space: pre">{{item.oldAssetNotes}}</div>
|
||||
</van-cell>
|
||||
<van-cell title="旧资产图片" class="direction-column-cell">
|
||||
<file-preview :files="item.oldAssetFiles" complete_result></file-preview>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
<template v-if="viewData.assetStocktakingList&&viewData.assetStocktakingList.length===0">
|
||||
<van-empty description="暂无数据" ></van-empty>
|
||||
</template>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
viewData: {},
|
||||
row: null,
|
||||
activeName: "1",
|
||||
actionSheetRef: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 打开
|
||||
onOpen(row) {
|
||||
this.activeName = "1"
|
||||
this.row = row
|
||||
this.visible = true
|
||||
this.getInfo()
|
||||
},
|
||||
// 获取申请信息
|
||||
getInfo() {
|
||||
this.$axios.post('/platform/asset/manage/fondOneAsset', {id: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
let H5_ASSET_STOCKTAKING_FORM = {
|
||||
template: /*language=HTML*/ `
|
||||
<van-action-sheet v-model="visible" title="盘点信息">
|
||||
<div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-cell-group title="资产信息">
|
||||
<van-field label="资产编号"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.assetNumber"
|
||||
readonly
|
||||
required></van-field>
|
||||
<van-field label="资产名称"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.assetName"
|
||||
readonly
|
||||
required></van-field>
|
||||
<van-field label="开始使用日期"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="$moment(formData.assetUsedDate).format('YYYY-MM-DD')"
|
||||
readonly
|
||||
required></van-field>
|
||||
<van-field label="存放地点"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.assetStorageLocation"
|
||||
required
|
||||
name="assetStorageLocation"
|
||||
placeholder="请输入存放地点"></van-field>
|
||||
|
||||
<van-field
|
||||
v-model="formData.assetUseName"
|
||||
name="assetUseName"
|
||||
label="责任人"
|
||||
required
|
||||
readonly
|
||||
:rules="[{ required: true }]"
|
||||
is-link
|
||||
placeholder="请输入工号或姓名选择责任人"
|
||||
@click="assetUseNameShow=true"
|
||||
></van-field>
|
||||
<van-action-sheet v-model="assetUseNameShow" title="责任人" class="height100" :close-on-click-overlay="false">
|
||||
<van-search
|
||||
v-model="searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入工号或姓名选择责任人"
|
||||
@input="(val) => {searchAssetUseUser(val)}"
|
||||
@clear="(val) => {searchAssetUseUser(val)}"
|
||||
shape="round"
|
||||
></van-search>
|
||||
<div class="van-action-sheet__content mt5"
|
||||
v-if="assetUseUserOption && assetUseUserOption.length>0">
|
||||
<template>
|
||||
<template v-for="item in assetUseUserOption">
|
||||
<van-button native-type="button" @click="onUserSelect(item)"
|
||||
class="van-action-sheet__item van-hairline--bottom">
|
||||
<span class="van-action-sheet__name">{{item.username}}({{item.loginname}})</span>
|
||||
</van-button>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
<van-empty description="暂无数据" v-else></van-empty>
|
||||
</van-action-sheet>
|
||||
|
||||
|
||||
<van-field
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.assetUsageStateName"
|
||||
label="使用状况"
|
||||
name="assetUsageStateName"
|
||||
placeholder="请选择使用状况"
|
||||
required
|
||||
is-link
|
||||
readonly
|
||||
@click="showAssetUsageStateNamePopup = true"
|
||||
></van-field>
|
||||
<van-popup v-model="showAssetUsageStateNamePopup" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="assetUsageStateNameOption.map(i => i.name)"
|
||||
@confirm="onAssetUsageStateNameConfirm"
|
||||
@cancel="showAssetUsageStateNamePopup = false"
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-field label="备注"
|
||||
v-model="formData.assetNotes"
|
||||
type="textarea"
|
||||
name="assetNotes"
|
||||
rows="4"
|
||||
autosize
|
||||
maxlength="150"
|
||||
class="more-text"
|
||||
placeholder="请填写备注"></van-field>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="附件">
|
||||
<van-field class="more-text" name="assetFiles"
|
||||
:rules="[{ required: true,message:'请上传附件' }]"
|
||||
label=""
|
||||
required>
|
||||
<template #input>
|
||||
<h5-file-upload
|
||||
slot="input"
|
||||
:value.sync="formData.assetFiles"
|
||||
:upload_number="10"
|
||||
upload_mode="file"
|
||||
upload_result_category="array"
|
||||
upload_result_type="url"
|
||||
complete_result
|
||||
></h5-file-upload>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button type="primary" @click="onSubmit">提交</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
`,
|
||||
dicts: ["ASSET_USAGE_STATE"],
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
viewData: {},
|
||||
row: null,
|
||||
formData: {},
|
||||
assetUsageStateNameOption:[],
|
||||
showAssetUsageStateNamePopup:false,
|
||||
|
||||
assetUseUserOption:[],
|
||||
assetUseNameShow:false,
|
||||
searchKeyword:""
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 打开
|
||||
async onOpen(row) {
|
||||
this.row = row
|
||||
this.$set(this.formData, "assetId", row.id)
|
||||
this.$set(this.formData, "assetStocktakingPlanId", row.assetStocktakingPlanId)
|
||||
this.$set(this.formData, "assetNumber", row.assetNumber)
|
||||
this.$set(this.formData, "assetName", row.assetName)
|
||||
this.$set(this.formData, "assetUsedDate", row.assetUsedDate)
|
||||
this.$set(this.formData, "assetStorageLocation", row.assetStorageLocation)
|
||||
this.assetUsageStateNameOption = await this.$businessTool.getDictOptions("ASSET_USAGE_STATE")
|
||||
this.visible = true
|
||||
},
|
||||
onAssetUsageStateNameConfirm(value,index){
|
||||
this.formData.assetUsageStateName = this.assetUsageStateNameOption[index].name
|
||||
this.showAssetUsageStateNamePopup=false
|
||||
},
|
||||
onUserSelect(o){
|
||||
this.$set(this.formData, "assetUseUserId", o.id)
|
||||
this.$set(this.formData, "assetUseName", o.username)
|
||||
this.assetUseNameShow = false
|
||||
},
|
||||
searchAssetUseUser(val) {
|
||||
$.get("/platform/asset/manage/searchAssetUseUser", {query: val}).then(resp => {
|
||||
if (resp.code === 0) {
|
||||
this.assetUseUserOption = resp.data
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(() => {
|
||||
let formData = clone(this.formData)
|
||||
if (formData.assetFiles) {
|
||||
formData.assetFiles = JSON.stringify(formData.assetFiles)
|
||||
}
|
||||
this.$axios.post("/platform/asset/stocktaking/doSubmit", formData).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast(res.msg)
|
||||
this.visible = false
|
||||
this.$emit("save_success")
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,351 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.course-cover {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background: linear-gradient(45deg, #f0f2f5, #e9ecef);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.course-cover .van-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.course-info {
|
||||
padding: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.course-info .van-cell-group {
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #fff 0%, #f8f9fa 100%);
|
||||
}
|
||||
|
||||
.course-title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.3;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.course-desc {
|
||||
font-size: 15px;
|
||||
color: #555;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 16px;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.course-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.course-date {
|
||||
color: #888;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.progress-section {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress-container .van-progress {
|
||||
flex: 1;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
min-width: 40px;
|
||||
}
|
||||
|
||||
.chapters-section {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.chapter-card {
|
||||
background: #fff;
|
||||
border: 1px solid #f0f0f0;
|
||||
margin-bottom: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chapter-header {
|
||||
padding: 16px;
|
||||
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.chapter-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.chapter-videos {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.video-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid #f8f9fa;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.video-item:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.video-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.video-icon {
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.video-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.video-title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
margin-bottom: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.video-duration {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.video-status {
|
||||
margin-left: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="课程详情" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div v-if="loading" class="loading-container">
|
||||
<van-loading type="spinner" size="24px">加载中...</van-loading>
|
||||
</div>
|
||||
|
||||
<div v-else-if="course">
|
||||
<!-- 课程封面 -->
|
||||
<div class="course-cover">
|
||||
<van-image v-if="course.cover" :src="course.cover" fit="cover" :alt="course.title">
|
||||
<template v-slot:error>
|
||||
<van-icon name="photo-fail" size="48" color="#ddd"></van-icon>
|
||||
</template>
|
||||
</van-image>
|
||||
<van-icon v-else name="graduation" size="48" color="#ddd"></van-icon>
|
||||
</div>
|
||||
|
||||
<!-- 课程信息 -->
|
||||
<van-cell-group class="course-info">
|
||||
<div class="course-title">{{ course.title || '未命名课程' }}</div>
|
||||
<div class="course-desc">{{ course.description || '暂无描述' }}</div>
|
||||
<div class="course-meta">
|
||||
<van-tag type="primary" size="mini">{{ course.category || '未分类' }}</van-tag>
|
||||
<span class="course-date">{{ formatDate(course.createdAt) }}</span>
|
||||
</div>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 学习进度 -->
|
||||
<van-cell-group title="学习进度" class="progress-section">
|
||||
<van-cell>
|
||||
<template #default>
|
||||
<div class="progress-container">
|
||||
<van-progress :percentage="progressPercentage" stroke-width="6"></van-progress>
|
||||
<span class="progress-text">{{ progressPercentage }}%</span>
|
||||
</div>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 课程章节 -->
|
||||
<div class="chapters-section">
|
||||
<h3 style="margin: 0 0 16px 0; padding-left:16px;font-size: 16px; font-weight: 600; color: #333;">课程章节</h3>
|
||||
|
||||
<div v-if="course.chapters && course.chapters.length">
|
||||
<div
|
||||
v-for="(chapter, index) in course.chapters"
|
||||
v-if="chapter.videos && chapter.videos.length"
|
||||
:key="chapter.id"
|
||||
class="chapter-card"
|
||||
>
|
||||
<div class="chapter-header">
|
||||
<h4 class="chapter-title">{{ chapter.title || '第' + (index + 1) + '章' }}</h4>
|
||||
</div>
|
||||
|
||||
<div class="chapter-videos">
|
||||
<div
|
||||
v-for="video in chapter.videos"
|
||||
:key="video.id"
|
||||
class="video-item"
|
||||
@click="playVideo(video.id, video.title)"
|
||||
>
|
||||
<div class="video-icon">
|
||||
<van-icon
|
||||
:name="isVideoCompleted(video.id) ? 'success' : 'play-circle-o'"
|
||||
:color="isVideoCompleted(video.id) ? '#07c160' : '#1989fa'"
|
||||
size="20"
|
||||
></van-icon>
|
||||
</div>
|
||||
|
||||
<div class="video-content">
|
||||
<div class="video-title">{{ video.title || '未命名视频' }}</div>
|
||||
<div class="video-duration">{{ formatDuration(video.duration) }}</div>
|
||||
</div>
|
||||
|
||||
<div class="video-status" v-if="isVideoCompleted(video.id)">
|
||||
<van-tag type="success" size="mini">已完成</van-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<van-empty v-else description="暂无章节内容" style="padding: 40px 20px;"></van-empty>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<van-empty v-else description="课程不存在"></van-empty>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
course: null,
|
||||
loading: true,
|
||||
courseId: null,
|
||||
activeChapters: [],
|
||||
progressData: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
progressPercentage() {
|
||||
if (!this.progressData || !this.progressData.totalVideos) return 0;
|
||||
return Math.round(this.progressData.completedVideos / this.progressData.totalVideos * 100);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
|
||||
// 加载课程详情
|
||||
async loadCourseDetail() {
|
||||
if (!this.courseId) {
|
||||
this.$toast.fail('缺少课程ID参数');
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const {code, data, msg} = await $.get('/platform/h5/edu/course/detail/data', {
|
||||
courseId: this.courseId
|
||||
});
|
||||
|
||||
if (code === 0 && data) {
|
||||
this.course = data;
|
||||
this.loadCourseProgress();
|
||||
} else {
|
||||
this.$toast.fail(msg || '加载课程详情失败');
|
||||
}
|
||||
} catch (error) {
|
||||
this.$toast.fail('网络错误');
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
// 加载课程进度
|
||||
async loadCourseProgress() {
|
||||
try {
|
||||
const {code, data} = await $.get('/platform/h5/edu/course/progress', {
|
||||
courseId: this.courseId
|
||||
});
|
||||
|
||||
if (code === 0 && data) {
|
||||
this.progressData = data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载进度失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 检查视频是否已完成
|
||||
isVideoCompleted(videoId) {
|
||||
return this.progressData &&
|
||||
this.progressData.completedVideoIds &&
|
||||
this.progressData.completedVideoIds.includes(videoId);
|
||||
},
|
||||
|
||||
// 播放视频
|
||||
playVideo(videoId, videoTitle) {
|
||||
pjaxReplace('/platform/h5/edu/video/play?videoId=' + videoId + '&courseId=' + this.courseId + '&title=' + encodeURIComponent(videoTitle || ''));
|
||||
},
|
||||
|
||||
// 格式化日期
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
const date = new Date(dateStr);
|
||||
return date.getFullYear() + '-' +
|
||||
String(date.getMonth() + 1).padStart(2, '0') + '-' +
|
||||
String(date.getDate()).padStart(2, '0');
|
||||
},
|
||||
|
||||
// 格式化时长
|
||||
formatDuration(seconds) {
|
||||
if (!seconds) return '00:00';
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
return String(minutes).padStart(2, '0') + ':' + String(remainingSeconds).padStart(2, '0');
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// 获取URL参数
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
this.courseId = urlParams.get('courseId');
|
||||
|
||||
this.loadCourseDetail();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,230 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.course-item {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 6px;
|
||||
margin: 12px 16px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.course-cover {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
margin: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.course-cover::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 2px;
|
||||
border-radius: 14px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.course-cover .van-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 14px;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.course-cover .van-icon {
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
|
||||
}
|
||||
|
||||
.course-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 16px 16px 16px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.course-title {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.3;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.course-desc {
|
||||
font-size: 14px;
|
||||
color: #64748b;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 12px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.course-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.course-date {
|
||||
color: #94a3b8;
|
||||
font-weight: 500;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="教育培训课程" placeholder fixed>
|
||||
<template #right>
|
||||
<van-icon name="clock-o" @click="goToHistory"></van-icon>
|
||||
</template>
|
||||
</van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-tabs v-model="pageForm.category" @change="doSearch">
|
||||
<van-tab name="" title="全部"></van-tab>
|
||||
<van-tab v-for="item in dict.type.TRAIN_EDU_COURSE_TYPE"
|
||||
:name="item.code"
|
||||
:title="item.name"
|
||||
:key="item.id"
|
||||
></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<van-pull-refresh v-model="tableRefreshing" @refresh="onRefresh">
|
||||
<van-list v-model="tableLoading" :finished="tableFinished" finished-text="没有更多了" @load="onLoad">
|
||||
<div class="course-item" v-for="(course, index) in tableData" :key="course.id"
|
||||
@click="viewCourse(course.id)">
|
||||
<div class="course-cover">
|
||||
<van-image v-if="course.cover" :src="course.cover" fit="cover" :alt="course.title">
|
||||
<template v-slot:error>
|
||||
<van-icon name="photo-fail" size="32" color="#ddd"></van-icon>
|
||||
</template>
|
||||
</van-image>
|
||||
<van-icon v-else name="play-circle-o" size="48" color="#ddd"></van-icon>
|
||||
</div>
|
||||
<div class="course-info">
|
||||
<div class="course-title">{{ course.title || '未命名课程' }}</div>
|
||||
<div class="course-desc">{{ course.description || '暂无描述' }}</div>
|
||||
<div class="course-meta">
|
||||
<van-tag type="primary" size="mini">{{ course.category || '未分类' }}</van-tag>
|
||||
<span class="course-date">{{ formatDate(course.createdAt) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
|
||||
<van-empty v-if="!tableLoading && !tableData.length" description="暂无课程"></van-empty>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts:['TRAIN_EDU_COURSE_TYPE'],
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
category: ""
|
||||
},
|
||||
tableData: [],
|
||||
tableLoading: false,
|
||||
tableFinished: false,
|
||||
tableRefreshing: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
|
||||
// 刷新
|
||||
onRefresh() {
|
||||
this.tableFinished = false;
|
||||
this.tableLoading = true
|
||||
this.pageForm.pageNumber = 1;
|
||||
this.onLoad();
|
||||
},
|
||||
|
||||
// 加载更多
|
||||
async onLoad() {
|
||||
if(this.tableRefreshing){
|
||||
this.tableData = []
|
||||
this.tableRefreshing = false
|
||||
}
|
||||
|
||||
this.$axios.post('/platform/h5/edu/courses/list', this.pageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = this.tableData.concat(res.data.list)
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
if (this.tableData.length >= this.pageForm.totalCount) {
|
||||
this.tableFinished = true
|
||||
}
|
||||
this.pageForm.pageNumber++;
|
||||
}
|
||||
}).finally(() => {
|
||||
this.tableLoading = false
|
||||
this.tableRefreshing = false
|
||||
})
|
||||
},
|
||||
|
||||
// 搜索
|
||||
doSearch() {
|
||||
this.pageForm.pageNumber = 1;
|
||||
this.tableData = [];
|
||||
this.tableFinished = false;
|
||||
this.tableLoading = true;
|
||||
this.onLoad();
|
||||
},
|
||||
|
||||
// 查看课程详情
|
||||
viewCourse(courseId) {
|
||||
pjaxReplace(`/platform/h5/edu/course/detail?courseId=` + courseId);
|
||||
},
|
||||
|
||||
// 前往学习历史
|
||||
goToHistory() {
|
||||
pjaxReplace('/platform/h5/edu/studyhis/');
|
||||
},
|
||||
|
||||
// 格式化日期
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
const date = new Date(dateStr);
|
||||
return date.getFullYear() + '-' +
|
||||
String(date.getMonth() + 1).padStart(2, '0') + '-' +
|
||||
String(date.getDate()).padStart(2, '0');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,410 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.history-container {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
margin: 15px;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.stats-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #1989fa;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.history-item {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
margin: 15px;
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.history-header {
|
||||
padding: 15px 20px;
|
||||
border-bottom: 1px solid #f8f9fa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.course-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.course-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.course-meta {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.course-category {
|
||||
background: #e3f2fd;
|
||||
color: #1976d2;
|
||||
padding: 2px 6px;
|
||||
border-radius: 8px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.progress-info {
|
||||
text-align: right;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #28a745;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 60px;
|
||||
height: 4px;
|
||||
background: #e9ecef;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #28a745, #20c997);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.video-list {
|
||||
padding: 0 20px 15px;
|
||||
}
|
||||
|
||||
.video-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #f8f9fa;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.video-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.video-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background: linear-gradient(135deg, #1989fa, #1976d2);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
margin-right: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.video-icon.completed {
|
||||
background: linear-gradient(135deg, #28a745, #20c997);
|
||||
}
|
||||
|
||||
.video-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.video-title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
margin-bottom: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.video-meta {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.video-duration {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.video-progress {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.watch-time {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" class="history-container">
|
||||
<van-nav-bar
|
||||
title="学习历史"
|
||||
left-text="返回"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
></van-nav-bar>
|
||||
|
||||
<van-tabs v-model="activeTab" @change="onTabChange">
|
||||
<van-tab title="全部" name="all"></van-tab>
|
||||
<van-tab title="已完成" name="completed"></van-tab>
|
||||
<van-tab title="学习中" name="in_progress"></van-tab>
|
||||
<van-tab title="最近观看" name="recent"></van-tab>
|
||||
</van-tabs>
|
||||
|
||||
<!-- 学习统计 -->
|
||||
<div v-if="showStats && stats" class="stats-card">
|
||||
<div class="stats-title">
|
||||
<van-icon name="chart-trending-o" style="margin-right: 8px; color: #1989fa;"/>
|
||||
学习统计
|
||||
</div>
|
||||
<div class="stats-grid">
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">{{ stats.totalCourses || 0 }}</div>
|
||||
<div class="stat-label">学习课程</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">{{ stats.completedVideos || 0 }}</div>
|
||||
<div class="stat-label">完成视频</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">{{ Math.round((stats.totalWatchTime || 0) / 60) }}</div>
|
||||
<div class="stat-label">学习时长(分)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 学习历史列表 -->
|
||||
<van-loading v-if="loading" type="spinner" color="#1989fa" style="margin: 40px auto; display: block;">
|
||||
加载中...
|
||||
</van-loading>
|
||||
|
||||
<van-empty v-else-if="historyList.length === 0" description="暂无学习记录">
|
||||
<van-button round type="primary" @click="loadData">刷新</van-button>
|
||||
</van-empty>
|
||||
|
||||
<div v-else>
|
||||
<div v-for="course in historyList" :key="course.courseId" class="history-item">
|
||||
<div class="history-header" @click="viewCourse(course.courseId)">
|
||||
<div class="course-info">
|
||||
<div class="course-title">{{ course.courseTitle || '未命名课程' }}</div>
|
||||
<div class="course-meta">
|
||||
<span class="course-category">{{ course.courseCategory || '未分类' }}</span>
|
||||
<span>最后学习:{{ formatDate(course.lastWatchTime) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<div class="progress-text">{{ getProgressPercent(course) }}%</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" :style="{ width: getProgressPercent(course) + '%' }"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="course.videos && course.videos.length > 0" class="video-list">
|
||||
<div
|
||||
v-for="video in course.videos"
|
||||
:key="video.videoId"
|
||||
class="video-item"
|
||||
@click="playVideo(video.videoId, course.courseId, video.videoTitle)"
|
||||
>
|
||||
<div class="video-icon" :class="{ completed: video.isCompleted }">
|
||||
<van-icon :name="video.isCompleted ? 'success' : 'play-circle-o'"/>
|
||||
</div>
|
||||
<div class="video-info">
|
||||
<div class="video-title">{{ video.videoTitle || '未命名视频' }}</div>
|
||||
<div class="video-meta">
|
||||
<span class="video-duration">{{ formatDuration(video.duration) }}</span>
|
||||
<span class="video-progress">
|
||||
{{ getVideoProgress(video) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="watch-time">
|
||||
{{ formatDate(video.lastWatchTime) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data() {
|
||||
return {
|
||||
activeTab: 'all',
|
||||
loading: false,
|
||||
showStats: false,
|
||||
stats: null,
|
||||
historyList: []
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadData();
|
||||
},
|
||||
methods: {
|
||||
onClickLeft() {
|
||||
window.location.href = '/platform/h5/edu/courses';
|
||||
},
|
||||
|
||||
onTabChange(name) {
|
||||
this.activeTab = name;
|
||||
this.loadData();
|
||||
},
|
||||
|
||||
async loadData() {
|
||||
this.loading = true;
|
||||
try {
|
||||
// 如果是全部标签,先加载统计信息
|
||||
if (this.activeTab === 'all') {
|
||||
await this.loadStats();
|
||||
this.showStats = true;
|
||||
} else {
|
||||
this.showStats = false;
|
||||
}
|
||||
|
||||
// 加载学习历史
|
||||
await this.loadHistory();
|
||||
} catch (error) {
|
||||
this.$toast('加载失败,请重试');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async loadStats() {
|
||||
try {
|
||||
const response = await this.$axios.post('/platform/h5/edu/study/stats');
|
||||
if (response.data.code === 0) {
|
||||
this.stats = response.data.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载统计失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
async loadHistory() {
|
||||
try {
|
||||
const response = await this.$axios.post('/platform/h5/edu/study/history', {
|
||||
params: {filter: this.activeTab}
|
||||
});
|
||||
if (response.data.code === 0) {
|
||||
this.historyList = response.data.data || [];
|
||||
} else {
|
||||
this.$toast(response.data.msg || '加载失败');
|
||||
}
|
||||
} catch (error) {
|
||||
this.$toast('网络错误,请检查网络连接');
|
||||
}
|
||||
},
|
||||
|
||||
viewCourse(courseId) {
|
||||
window.location.href = `/platform/h5/edu/course/detail?courseId=` + courseId;
|
||||
},
|
||||
|
||||
playVideo(videoId, courseId, videoTitle) {
|
||||
pjaxReplace('/platform/h5/edu/video/play?videoId=' + videoId + '&courseId=' + courseId + '&title=' + encodeURIComponent(videoTitle))
|
||||
},
|
||||
|
||||
getProgressPercent(course) {
|
||||
if (!course.videos || course.videos.length === 0) return 0;
|
||||
const completedCount = course.videos.filter(v => v.isCompleted).length;
|
||||
return Math.round((completedCount / course.videos.length) * 100);
|
||||
},
|
||||
|
||||
getVideoProgress(video) {
|
||||
if (video.isCompleted) return '已完成';
|
||||
if (video.duration > 0 && video.watchDuration > 0) {
|
||||
const percent = Math.round((video.watchDuration / video.duration) * 100);
|
||||
return `观看` + percent + '%';
|
||||
}
|
||||
return '未开始';
|
||||
},
|
||||
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return '未知';
|
||||
const date = new Date(dateStr);
|
||||
const now = new Date();
|
||||
const diffTime = now - date;
|
||||
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
||||
|
||||
if (diffDays === 0) {
|
||||
const diffHours = Math.floor(diffTime / (1000 * 60 * 60));
|
||||
if (diffHours === 0) {
|
||||
const diffMinutes = Math.floor(diffTime / (1000 * 60));
|
||||
return diffMinutes <= 0 ? '刚刚' : diffMinutes + `分钟前`;
|
||||
}
|
||||
return diffHours + `小时前`;
|
||||
} else if (diffDays === 1) {
|
||||
return '昨天';
|
||||
} else if (diffDays < 7) {
|
||||
return diffDays + `天前`;
|
||||
} else {
|
||||
return date.getFullYear() + '-' +
|
||||
String(date.getMonth() + 1).padStart(2, '0') + '-' +
|
||||
String(date.getDate()).padStart(2, '0');
|
||||
}
|
||||
},
|
||||
|
||||
formatDuration(seconds) {
|
||||
if (!seconds) return '00:00';
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
return String(minutes).padStart(2, '0') + ':' + String(remainingSeconds).padStart(2, '0');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,547 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.study-his-container {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.stats-overview {
|
||||
background: linear-gradient(135deg, #1989fa, #1976d2);
|
||||
padding: 20px 15px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.stats-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 15px 10px;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 5px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.filter-tabs {
|
||||
background: white;
|
||||
padding: 0 15px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
display: inline-block;
|
||||
padding: 15px 20px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
border-bottom: 2px solid transparent;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
color: #1989fa;
|
||||
border-bottom-color: #1989fa;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.history-list {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.history-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 15px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.course-header {
|
||||
padding: 15px 20px;
|
||||
border-bottom: 1px solid #f8f9fa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.course-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.course-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.course-meta {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.course-category {
|
||||
background: #e3f2fd;
|
||||
color: #1976d2;
|
||||
padding: 3px 8px;
|
||||
border-radius: 10px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.last-study-time {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.progress-section {
|
||||
text-align: right;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.progress-percent {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #28a745;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 80px;
|
||||
height: 6px;
|
||||
background: #e9ecef;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #28a745, #20c997);
|
||||
border-radius: 3px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.video-list {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
}
|
||||
|
||||
.video-list.expanded {
|
||||
max-height: 1000px;
|
||||
padding: 0 20px 15px;
|
||||
}
|
||||
|
||||
.video-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #f8f9fa;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.video-item:hover {
|
||||
background-color: #f8f9fa;
|
||||
margin: 0 -10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.video-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.video-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: linear-gradient(135deg, #1989fa, #1976d2);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
margin-right: 15px;
|
||||
font-size: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.video-icon.completed {
|
||||
background: linear-gradient(135deg, #28a745, #20c997);
|
||||
}
|
||||
|
||||
.video-icon.in-progress {
|
||||
background: linear-gradient(135deg, #ffc107, #ff9800);
|
||||
}
|
||||
|
||||
.video-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.video-title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
margin-bottom: 6px;
|
||||
line-height: 1.4;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.video-meta {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.video-duration {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.video-progress {
|
||||
color: #28a745;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.video-time {
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
text-align: right;
|
||||
min-width: 60px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.expand-btn {
|
||||
color: #1989fa;
|
||||
font-size: 12px;
|
||||
margin-left: 10px;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.expand-btn.expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 48px;
|
||||
color: #ddd;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 14px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 40px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" class="study-his-container">
|
||||
<van-nav-bar
|
||||
title="学习统计"
|
||||
left-text="返回"
|
||||
left-arrow
|
||||
@click-left="onClickLeft"
|
||||
></van-nav-bar>
|
||||
|
||||
<!-- 学习统计概览 -->
|
||||
<div v-if="stats" class="stats-overview">
|
||||
<div class="stats-title">我的学习成果</div>
|
||||
<div class="stats-grid">
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">{{ stats.totalCourses || 0 }}</div>
|
||||
<div class="stat-label">学习课程</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">{{ stats.completedVideos || 0 }}</div>
|
||||
<div class="stat-label">完成视频</div>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<div class="stat-number">{{ Math.round((stats.totalWatchTime || 0) / 60) }}</div>
|
||||
<div class="stat-label">学习时长(分)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选标签 -->
|
||||
<div class="filter-tabs">
|
||||
<div
|
||||
v-for="tab in tabs"
|
||||
:key="tab.key"
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === tab.key }"
|
||||
@click="switchTab(tab.key)"
|
||||
>
|
||||
{{ tab.label }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<div v-if="loading" class="loading-container">
|
||||
<van-loading type="spinner" color="#1989fa" size="24px">加载中...</van-loading>
|
||||
</div>
|
||||
|
||||
<!-- 学习历史列表 -->
|
||||
<div v-else-if="historyList.length > 0" class="history-list">
|
||||
<div v-for="course in historyList" :key="course.courseId" class="history-card">
|
||||
<div class="course-header" @click="toggleCourseExpand(course.courseId)">
|
||||
<div class="course-info">
|
||||
<div class="course-title">{{ course.courseTitle || '未命名课程' }}</div>
|
||||
<div class="course-meta">
|
||||
<span class="course-category">{{ course.courseCategory || '未分类' }}</span>
|
||||
<span class="last-study-time">{{ formatDate(course.lastWatchTime) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-section">
|
||||
<div class="progress-percent">{{ getProgressPercent(course) }}%</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" :style="{ width: getProgressPercent(course) + '%' }"></div>
|
||||
</div>
|
||||
</div>
|
||||
<van-icon
|
||||
name="arrow-down"
|
||||
class="expand-btn"
|
||||
:class="{ expanded: expandedCourses.includes(course.courseId) }"
|
||||
></van-icon>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="video-list"
|
||||
:class="{ expanded: expandedCourses.includes(course.courseId) }"
|
||||
>
|
||||
<div
|
||||
v-for="video in course.videos"
|
||||
:key="video.videoId"
|
||||
class="video-item"
|
||||
@click="playVideo(video.videoId, course.courseId, video.videoTitle)"
|
||||
>
|
||||
<div
|
||||
class="video-icon"
|
||||
:class="getVideoIconClass(video)"
|
||||
>
|
||||
<van-icon :name="getVideoIconName(video)" ></van-icon>
|
||||
</div>
|
||||
<div class="video-content">
|
||||
<div class="video-title">{{ video.videoTitle || '未命名视频' }}</div>
|
||||
<div class="video-meta">
|
||||
<span class="video-duration">{{ formatDuration(video.duration) }}</span>
|
||||
<span class="video-progress">{{ getVideoProgressText(video) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video-time">
|
||||
{{ formatDate(video.lastWatchTime) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div v-else class="empty-state">
|
||||
<div class="empty-icon">📚</div>
|
||||
<div class="empty-text">暂无学习记录</div>
|
||||
<van-button round type="primary" size="small" @click="goToCourses">
|
||||
开始学习
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
stats: null,
|
||||
activeTab: 'all',
|
||||
tabs: [
|
||||
{ key: 'all', label: '全部' },
|
||||
{ key: 'completed', label: '已完成' },
|
||||
{ key: 'in_progress', label: '学习中' },
|
||||
{ key: 'recent', label: '最近' }
|
||||
],
|
||||
historyList: [],
|
||||
expandedCourses: []
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.loadData();
|
||||
},
|
||||
methods: {
|
||||
onClickLeft() {
|
||||
window.location.href = '/platform/h5/edu/courses';
|
||||
},
|
||||
|
||||
async loadData() {
|
||||
this.loading = true;
|
||||
try {
|
||||
await Promise.all([
|
||||
this.loadStats(),
|
||||
this.loadHistory()
|
||||
]);
|
||||
} catch (error) {
|
||||
this.$toast('加载失败,请重试');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async loadStats() {
|
||||
try {
|
||||
const response = await this.$axios.post('/platform/h5/edu/studyhis/stats');
|
||||
if (response.data.code === 0) {
|
||||
this.stats = response.data.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载统计失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
async loadHistory() {
|
||||
try {
|
||||
const response = await this.$axios.post('/platform/h5/edu/studyhis/history', {
|
||||
filter: this.activeTab
|
||||
});
|
||||
if (response.data.code === 0) {
|
||||
this.historyList = response.data.data || [];
|
||||
} else {
|
||||
this.$toast(response.data.msg || '加载失败');
|
||||
}
|
||||
} catch (error) {
|
||||
this.$toast('网络错误,请检查网络连接');
|
||||
}
|
||||
},
|
||||
|
||||
switchTab(tabKey) {
|
||||
if (this.activeTab === tabKey) return;
|
||||
|
||||
this.activeTab = tabKey;
|
||||
this.expandedCourses = [];
|
||||
this.loadData();
|
||||
},
|
||||
|
||||
toggleCourseExpand(courseId) {
|
||||
const index = this.expandedCourses.indexOf(courseId);
|
||||
if (index > -1) {
|
||||
this.expandedCourses.splice(index, 1);
|
||||
} else {
|
||||
this.expandedCourses.push(courseId);
|
||||
}
|
||||
},
|
||||
|
||||
playVideo(videoId, courseId, videoTitle) {
|
||||
const url = '/platform/h5/edu/video/play?videoId=' + videoId +
|
||||
'&courseId=' + courseId +
|
||||
'&title=' + encodeURIComponent(videoTitle || '');
|
||||
window.location.href = url;
|
||||
},
|
||||
|
||||
goToCourses() {
|
||||
window.location.href = '/platform/h5/edu/courses';
|
||||
},
|
||||
|
||||
getProgressPercent(course) {
|
||||
if (!course.videos || course.videos.length === 0) return 0;
|
||||
const completedCount = course.videos.filter(v => v.isCompleted).length;
|
||||
return Math.round((completedCount / course.videos.length) * 100);
|
||||
},
|
||||
|
||||
getVideoIconClass(video) {
|
||||
if (video.isCompleted) return 'completed';
|
||||
if (video.watchDuration > 0) return 'in-progress';
|
||||
return '';
|
||||
},
|
||||
|
||||
getVideoIconName(video) {
|
||||
if (video.isCompleted) return 'success';
|
||||
if (video.watchDuration > 0) return 'pause-circle-o';
|
||||
return 'play-circle-o';
|
||||
},
|
||||
|
||||
getVideoProgressText(video) {
|
||||
if (video.isCompleted) return '已完成';
|
||||
if (video.duration > 0 && video.watchDuration > 0) {
|
||||
const percent = Math.round((video.watchDuration / video.duration) * 100);
|
||||
return '观看' + percent + '%';
|
||||
}
|
||||
return '未开始';
|
||||
},
|
||||
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return '未知';
|
||||
const date = new Date(dateStr);
|
||||
const now = new Date();
|
||||
const diffTime = now - date;
|
||||
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
||||
|
||||
if (diffDays === 0) {
|
||||
const diffHours = Math.floor(diffTime / (1000 * 60 * 60));
|
||||
if (diffHours === 0) {
|
||||
const diffMinutes = Math.floor(diffTime / (1000 * 60));
|
||||
return diffMinutes <= 0 ? '刚刚' : diffMinutes + '分钟前';
|
||||
}
|
||||
return diffHours + '小时前';
|
||||
} else if (diffDays === 1) {
|
||||
return '昨天';
|
||||
} else if (diffDays < 7) {
|
||||
return diffDays + '天前';
|
||||
} else {
|
||||
return (date.getMonth() + 1) + '-' + date.getDate();
|
||||
}
|
||||
},
|
||||
|
||||
formatDuration(seconds) {
|
||||
if (!seconds) return '00:00';
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = seconds % 60;
|
||||
return String(minutes).padStart(2, '0') + ':' + String(remainingSeconds).padStart(2, '0');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,305 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.video-container {
|
||||
background: #000;
|
||||
min-height: calc(100vh - 46px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 300px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.video-player {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.video-element {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-height: calc(100vh - 46px);
|
||||
object-fit: contain;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="pageBack" left-arrow left-text="返回" :title="videoTitle" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="video-container">
|
||||
<div v-if="loading" class="loading-container">
|
||||
<van-loading type="spinner" size="24px">加载中...</van-loading>
|
||||
</div>
|
||||
|
||||
<div v-else-if="videoInfo" class="video-player">
|
||||
<video
|
||||
ref="videoElement"
|
||||
class="video-element"
|
||||
:src="videoSrc"
|
||||
controls
|
||||
preload="metadata"
|
||||
@loadedmetadata="onVideoLoaded"
|
||||
@canplay="onVideoCanPlay"
|
||||
@play="onVideoPlay"
|
||||
@pause="onVideoPause"
|
||||
@timeupdate="onTimeUpdate"
|
||||
@ended="onVideoEnded"
|
||||
@error="onVideoError"
|
||||
>
|
||||
您的浏览器不支持视频播放
|
||||
</video>
|
||||
</div>
|
||||
|
||||
<van-empty v-else description="视频加载失败"></van-empty>
|
||||
</div>
|
||||
|
||||
<!-- 进度保存提示 -->
|
||||
<van-toast v-model="showProgressToast" message="进度已保存" :duration="1000"/>
|
||||
|
||||
<!-- 完成学习弹窗 -->
|
||||
<van-dialog
|
||||
v-model="showCompletionDialog"
|
||||
title="恭喜完成学习!"
|
||||
message="您已完成本视频的学习,学习记录已保存。"
|
||||
show-cancel-button
|
||||
cancel-button-text="继续观看"
|
||||
confirm-button-text="返回课程"
|
||||
@confirm="backToCourse"
|
||||
></van-dialog>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
videoInfo: null,
|
||||
loading: true,
|
||||
videoId: null,
|
||||
courseId: null,
|
||||
videoTitle: '视频播放',
|
||||
isPlaying: false,
|
||||
progressSaveTimer: null,
|
||||
showProgressToast: false,
|
||||
showCompletionDialog: false,
|
||||
savedProgress: 0,
|
||||
progressSet: false // 标记进度是否已设置,避免死循环
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
videoSrc() {
|
||||
if (this.videoInfo && this.videoInfo.url) {
|
||||
const id = this.videoInfo.url.split('id=')[1];
|
||||
console.log('/platform/sys/file/videoPlay?id=' + id)
|
||||
return '/platform/sys/file/videoPlay?id=' + id;
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
pageBack() {
|
||||
this.historyBack(this.clearProgressSave)
|
||||
},
|
||||
|
||||
// 加载视频信息
|
||||
async loadVideoInfo() {
|
||||
if (!this.videoId) {
|
||||
this.$toast.fail('缺少视频ID参数');
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const {code, data, msg} = await this.$axios.post('/platform/h5/edu/video/detail', {
|
||||
videoId: this.videoId
|
||||
});
|
||||
|
||||
if (code === 0 && data) {
|
||||
this.videoInfo = data;
|
||||
this.$nextTick(() => {
|
||||
this.loadWatchProgress();
|
||||
});
|
||||
} else {
|
||||
this.$toast.fail(msg || '加载视频信息失败');
|
||||
}
|
||||
} catch (error) {
|
||||
this.$toast.fail('网络错误');
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
// 视频加载完成
|
||||
onVideoLoaded() {
|
||||
console.log('视频元数据加载完成');
|
||||
},
|
||||
|
||||
// 视频可以播放
|
||||
onVideoCanPlay() {
|
||||
console.log('视频可以播放');
|
||||
// 视频可以播放时,设置观看进度
|
||||
this.setWatchProgress();
|
||||
},
|
||||
|
||||
// 视频开始播放
|
||||
onVideoPlay() {
|
||||
this.isPlaying = true;
|
||||
this.startProgressSave();
|
||||
},
|
||||
|
||||
// 视频暂停
|
||||
onVideoPause() {
|
||||
this.isPlaying = false;
|
||||
this.saveProgress();
|
||||
},
|
||||
|
||||
// 时间更新
|
||||
onTimeUpdate() {
|
||||
console.log('时间更新')
|
||||
// 可以在这里添加进度更新逻辑
|
||||
},
|
||||
|
||||
// 视频播放结束
|
||||
onVideoEnded() {
|
||||
this.isPlaying = false;
|
||||
this.markVideoCompleted();
|
||||
},
|
||||
|
||||
// 视频加载错误
|
||||
onVideoError() {
|
||||
this.$toast.fail('视频加载失败');
|
||||
},
|
||||
|
||||
// 加载观看进度
|
||||
async loadWatchProgress() {
|
||||
if (!this.videoId || !this.courseId) return;
|
||||
|
||||
try {
|
||||
const {code, data} = await this.$axios.post('/platform/h5/edu/study/record', {
|
||||
videoId: this.videoId
|
||||
});
|
||||
|
||||
if (code === 0 && data && data.watchedDuration > 0) {
|
||||
this.savedProgress = data.watchedDuration;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载观看进度失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 设置观看进度
|
||||
setWatchProgress() {
|
||||
if (this.savedProgress > 0 && !this.progressSet) {
|
||||
const video = this.$refs.videoElement;
|
||||
if (video && video.readyState >= 3) {
|
||||
// 使用setTimeout确保DOM更新完成
|
||||
setTimeout(() => {
|
||||
try {
|
||||
this.progressSet = true; // 标记进度已设置,避免重复设置
|
||||
video.currentTime = this.savedProgress;
|
||||
console.log('设置观看进度成功:', this.savedProgress);
|
||||
} catch (error) {
|
||||
console.error('设置观看进度失败:', error);
|
||||
}
|
||||
}, 100);
|
||||
} else {
|
||||
console.log('视频还未准备好,readyState:', video ? video.readyState : 'video不存在');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 保存观看进度
|
||||
async saveProgress() {
|
||||
const video = this.$refs.videoElement;
|
||||
if (!video || !this.videoId || !this.courseId) return;
|
||||
|
||||
try {
|
||||
await $.post('/platform/h5/edu/study/progress/save', {
|
||||
videoId: this.videoId,
|
||||
courseId: this.courseId,
|
||||
watchedDuration: Math.floor(video.currentTime)
|
||||
});
|
||||
|
||||
this.showProgressToast = true;
|
||||
} catch (error) {
|
||||
console.error('保存进度失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 开始定时保存进度
|
||||
startProgressSave() {
|
||||
this.clearProgressSave();
|
||||
this.progressSaveTimer = setInterval(() => {
|
||||
this.saveProgress();
|
||||
}, 10000); // 每10秒保存一次
|
||||
},
|
||||
|
||||
// 清除定时保存
|
||||
clearProgressSave() {
|
||||
if (this.progressSaveTimer) {
|
||||
clearInterval(this.progressSaveTimer);
|
||||
this.progressSaveTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 标记视频完成
|
||||
async markVideoCompleted() {
|
||||
if (!this.videoId || !this.courseId) return;
|
||||
|
||||
try {
|
||||
const {code} = await $.post('/platform/h5/edu/study/complete', {
|
||||
videoId: this.videoId,
|
||||
courseId: this.courseId
|
||||
});
|
||||
|
||||
if (code === 0) {
|
||||
this.showCompletionDialog = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('标记完成失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 返回课程
|
||||
backToCourse() {
|
||||
if (this.courseId) {
|
||||
|
||||
} else {
|
||||
this.historyBack();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// 获取URL参数
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
this.videoId = urlParams.get('videoId');
|
||||
this.courseId = urlParams.get('courseId');
|
||||
this.videoTitle = decodeURIComponent(urlParams.get('title') || '视频播放');
|
||||
|
||||
this.loadVideoInfo();
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
// 页面销毁前保存进度
|
||||
this.saveProgress();
|
||||
this.clearProgressSave();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+479
@@ -0,0 +1,479 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<div id="app">
|
||||
<!-- 导航栏 -->
|
||||
<van-nav-bar title="子女入学" left-text="返回" left-arrow
|
||||
@click-left="historyBack" fixed></van-nav-bar>
|
||||
|
||||
<!-- 表单容器 -->
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<!-- 登记类型信息 -->
|
||||
<van-cell-group title="登记类型">
|
||||
<van-field
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.registrationTypeName"
|
||||
label="登记类型"
|
||||
placeholder="请选择登记类型"
|
||||
required
|
||||
is-link
|
||||
readonly
|
||||
@click="showRegistrationTypePopup = true"
|
||||
></van-field>
|
||||
<van-popup v-model="showRegistrationTypePopup" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="registrationTypeOption.map(i => i.registrationTypeName)"
|
||||
@confirm="onRegistrationTypeConfirm"
|
||||
@cancel="showRegistrationTypePopup = false"
|
||||
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 教职工信息 -->
|
||||
<van-cell-group title="教职工信息">
|
||||
<van-field label="监护人(教工)姓名" :rules="[{ required: true }]" v-model="formData.userName" readonly
|
||||
required></van-field>
|
||||
<van-field label="工号" :rules="[{ required: true }]" v-model="formData.loginName" readonly
|
||||
required></van-field>
|
||||
<van-field label="手机号码" name="mobile" :rules="[{ required: true }]" v-model="formData.mobile"
|
||||
required
|
||||
placeholder="请输入手机号码"></van-field>
|
||||
<van-field label="所在单位" :rules="[{ required: true }]" v-model="formData.unitName" readonly
|
||||
required></van-field>
|
||||
|
||||
<van-field
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.childRelationshipName"
|
||||
label="监护人与学生关系"
|
||||
name="childRelationshipName"
|
||||
placeholder="请选择监护人与学生关系"
|
||||
required
|
||||
is-link
|
||||
readonly
|
||||
@click="showChildRelationshipPopup = true"
|
||||
></van-field>
|
||||
<van-popup v-model="showChildRelationshipPopup" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="childRelationshipOption.map(i => i.name)"
|
||||
@confirm="onChildRelationshipConfirm"
|
||||
@cancel="showChildRelationshipPopup = false"
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 子女信息 -->
|
||||
<van-cell-group title="子女信息">
|
||||
<van-field label="子女姓名" name="childrenName" :rules="[{ required: true }]"
|
||||
v-model="formData.childrenName" required
|
||||
placeholder="请输入子女姓名"></van-field>
|
||||
|
||||
<van-field
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.sex"
|
||||
label="性别"
|
||||
name="sex"
|
||||
placeholder="请选择性别"
|
||||
required
|
||||
is-link
|
||||
readonly
|
||||
@click="showSexPopup = true"
|
||||
></van-field>
|
||||
<van-popup v-model="showSexPopup" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="sexOption"
|
||||
@confirm="onSexConfirm"
|
||||
@cancel="showSexPopup = false"
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-field label="身份证号"
|
||||
name="childrenIdCard"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.childrenIdCard"
|
||||
placeholder="请输入身份证号"
|
||||
required
|
||||
></van-field>
|
||||
<van-field label="出生年月"
|
||||
name="childrenBirthday"
|
||||
:rules="[{ required: true }]"
|
||||
:value="formData.childrenBirthday"
|
||||
readonly
|
||||
is-link
|
||||
placeholder="请填写出生年月"
|
||||
required
|
||||
@click="childrenBirthdayPopup = true"></van-field>
|
||||
<van-popup v-model="childrenBirthdayPopup" position="bottom">
|
||||
<van-datetime-picker
|
||||
v-model="formData.childrenBirthdayDate"
|
||||
type="date"
|
||||
title="选择出生年月"
|
||||
:min-date="childrenBirthdayMinDate"
|
||||
:max-date="childrenBirthdayMaxDate"
|
||||
@confirm="childrenBirthdayConfirm"
|
||||
@cancel="childrenBirthdayPopup=false"
|
||||
></van-datetime-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-field label="现就读学校"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.childrenCurrentSchool"
|
||||
required
|
||||
placeholder="请输入现就读学校"></van-field>
|
||||
|
||||
<van-field
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.childrenPlanSchoolName"
|
||||
label="拟报就读学校"
|
||||
name="childrenPlanSchoolName"
|
||||
placeholder="请选择拟报就读学校"
|
||||
required
|
||||
is-link
|
||||
readonly
|
||||
@click="showChildrenPlanSchoolPopup = true"
|
||||
class="van-field"
|
||||
></van-field>
|
||||
<van-popup v-model="showChildrenPlanSchoolPopup" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="childrenPlanSchoolOption.map(i => i.name)"
|
||||
@confirm="onChildrenPlanSchoolConfirm"
|
||||
@cancel="showChildrenPlanSchoolPopup = false"
|
||||
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-field label="子女户口所在地"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.childrenHuKouAddress"
|
||||
required
|
||||
type="textarea"
|
||||
name="childrenHuKouAddress"
|
||||
rows="4"
|
||||
autosize
|
||||
class="more-text"
|
||||
placeholder="请输入子女户口所在地"></van-field>
|
||||
|
||||
<van-field label="备注"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.note"
|
||||
required
|
||||
type="textarea"
|
||||
name="note"
|
||||
rows="4"
|
||||
autosize
|
||||
class="more-text"
|
||||
placeholder="请填写户籍所在地派出所"></van-field>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 户口簿照片 -->
|
||||
<van-cell-group title="户口簿照片">
|
||||
<van-field class="more-text" name="huKouFiles" :rules="[{ required: true,message:'请上传户口簿照片' }]"
|
||||
label="" required>
|
||||
<template #input>
|
||||
<h5-file-upload
|
||||
slot="input"
|
||||
:value.sync="formData.huKouFiles"
|
||||
:upload_number="10"
|
||||
upload_mode="file"
|
||||
upload_result_category="array"
|
||||
upload_result_type="url"
|
||||
complete_result
|
||||
></h5-file-upload>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 子女出生证照片 -->
|
||||
<van-cell-group title="子女出生证照片">
|
||||
<van-field class="more-text" name="birthCertificateFiles" label="">
|
||||
<template #input>
|
||||
<h5-file-upload
|
||||
slot="input"
|
||||
:value.sync="formData.birthCertificateFiles"
|
||||
:upload_number="10"
|
||||
upload_mode="image"
|
||||
upload_result_category="array"
|
||||
upload_result_type="url"
|
||||
complete_result
|
||||
></h5-file-upload>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button native-type="button" plain type="info" @click="onSave">保存</van-button>
|
||||
<van-button type="primary" @click="onSubmit" v-if="!taskId">提交</van-button>
|
||||
<van-button type="primary" @click="onFinishTask" v-else>提交</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ENROLLMENT_REGISTRATION_CHILD_RELATIONSHIP", "ENROLLMENT_REGISTRATION_CHILDREN_PLAN_SCHOOL"],
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
bizId: GetQueryString("bizId"),
|
||||
taskId: GetQueryString("taskId"),
|
||||
formData: {},
|
||||
registrationTypeOption: [],
|
||||
showRegistrationTypePopup: false,
|
||||
|
||||
childRelationshipOption: [],
|
||||
showChildRelationshipPopup: false,
|
||||
|
||||
sexOption: ["男", "女"],
|
||||
showSexPopup: false,
|
||||
|
||||
childrenBirthdayMinDate: new Date(1900, 0, 1),
|
||||
childrenBirthdayMaxDate: new Date(),
|
||||
childrenBirthdayPopup: false,
|
||||
|
||||
childrenPlanSchoolOption: [],
|
||||
showChildrenPlanSchoolPopup: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getEnrollmentRegistrationPlan() {
|
||||
const res = await this.$axios.post("/platform/enrollmentRegistration/apply/getEnrollmentRegistrationPlan")
|
||||
if (res.code === 0) {
|
||||
this.registrationTypeOption = res.data
|
||||
}
|
||||
},
|
||||
init() {
|
||||
setTimeout(() => {
|
||||
this.childRelationshipOption = this.dict.type.ENROLLMENT_REGISTRATION_CHILD_RELATIONSHIP
|
||||
this.childrenPlanSchoolOption = this.dict.type.ENROLLMENT_REGISTRATION_CHILDREN_PLAN_SCHOOL
|
||||
}, 300)
|
||||
|
||||
if (this.bizId) {
|
||||
this.findOne(this.bizId).then(async data => {
|
||||
this.formData = data
|
||||
//登记类型回显
|
||||
const registrationType = this.registrationTypeOption.find(v => v.registrationType === data.registrationType)
|
||||
if (registrationType) {
|
||||
this.$set(this.formData, "registrationTypeName", registrationType.registrationTypeName)
|
||||
}
|
||||
//监护人与学生关系回显
|
||||
const childRelationship = this.dict.type.ENROLLMENT_REGISTRATION_CHILD_RELATIONSHIP.find(v => v.code === data.childRelationship)
|
||||
if (childRelationship) {
|
||||
this.$set(this.formData, "childRelationshipName", childRelationship.name)
|
||||
}
|
||||
//出生年月回显
|
||||
if (data.childrenBirthday) {
|
||||
this.$set(this.formData, "childrenBirthdayDate", new Date(data.childrenBirthday))
|
||||
}
|
||||
//拟报就读学校
|
||||
const childrenPlanSchool = this.dict.type.ENROLLMENT_REGISTRATION_CHILDREN_PLAN_SCHOOL.find(v => v.code === data.childrenPlanSchool)
|
||||
if (childrenPlanSchool) {
|
||||
this.$set(this.formData, "childrenPlanSchoolName", childrenPlanSchool.name)
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
const {id, username, loginname, mobile, union, unit} = this.$store.state.user
|
||||
this.formData = {
|
||||
userId: id,
|
||||
userName: username,
|
||||
loginName: loginname,
|
||||
unitName: unit.name,
|
||||
unitId: unit.id,
|
||||
unionName: union.name,
|
||||
unionId: union.id,
|
||||
mobile: mobile,
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
onChildrenPlanSchoolConfirm(value, index) {
|
||||
this.formData.childrenPlanSchool = this.childrenPlanSchoolOption[index].code;
|
||||
this.formData.childrenPlanSchoolName = value;
|
||||
this.showChildrenPlanSchoolPopup = false;
|
||||
},
|
||||
childrenBirthdayConfirm(value) {
|
||||
this.formData.childrenBirthdayDate = value
|
||||
this.formData.childrenBirthday = this.$moment(value).format("YYYY-MM-DD")
|
||||
this.childrenBirthdayPopup = false
|
||||
},
|
||||
onSexConfirm(value) {
|
||||
this.formData.sex = value;
|
||||
this.showSexPopup = false;
|
||||
},
|
||||
onChildRelationshipConfirm(value, index) {
|
||||
this.formData.childRelationship = this.childRelationshipOption[index].code;
|
||||
this.formData.childRelationshipName = value;
|
||||
this.showChildRelationshipPopup = false;
|
||||
},
|
||||
onRegistrationTypeConfirm(value, index) {
|
||||
this.formData.registrationType = this.registrationTypeOption[index].registrationType;
|
||||
this.formData.registrationTypeName = value;
|
||||
this.showRegistrationTypePopup = false;
|
||||
},
|
||||
validateBirthday() {
|
||||
if (!this.formData.registrationType) {
|
||||
return "请选择登记类型"
|
||||
}
|
||||
if (!this.formData.childrenBirthday) {
|
||||
return "请选择子女出生年月"
|
||||
}
|
||||
|
||||
const childrenBirthday = new Date(this.formData.childrenBirthday);
|
||||
if (isNaN(childrenBirthday.getTime())) {
|
||||
return "出生日期格式无效";
|
||||
}
|
||||
const registrationType = this.registrationTypeOption.find(item => item.registrationType === this.formData.registrationType)
|
||||
if (registrationType.greaterThanBirthday) {
|
||||
const greaterThanBirthday = new Date(registrationType.greaterThanBirthday);
|
||||
if (isNaN(greaterThanBirthday.getTime())) {
|
||||
return "限制日期格式无效";
|
||||
}
|
||||
|
||||
if (childrenBirthday < greaterThanBirthday) {
|
||||
return "出生日期不能小于" + registrationType.greaterThanBirthday;
|
||||
}
|
||||
}
|
||||
if (registrationType.lessThanBirthday) {
|
||||
const lessThanBirthday = new Date(registrationType.lessThanBirthday);
|
||||
if (isNaN(lessThanBirthday.getTime())) {
|
||||
return "限制日期格式无效";
|
||||
}
|
||||
|
||||
if (childrenBirthday > lessThanBirthday) {
|
||||
return "出生日期不能大于" + registrationType.lessThanBirthday;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null; // 表示通过
|
||||
},
|
||||
async getIsRepeatByIdCard() {
|
||||
if (!this.formData.childrenIdCard) {
|
||||
this.$toast.fail("请填写子女身份证号码")
|
||||
return
|
||||
}
|
||||
const res = await this.$axios.post('/platform/enrollmentRegistration/apply/getIsRepeatByIdCard', {
|
||||
idCard: this.formData.childrenIdCard,
|
||||
id: this.formData.id
|
||||
})
|
||||
if (res.code === 0) {
|
||||
if (res.data > 0) {
|
||||
this.$toast.fail("该身份证在本年度已填报!")
|
||||
return true
|
||||
} else {
|
||||
this.$toast.success("该身份证在本年度暂未填报!")
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
async findOne(id) {
|
||||
const resp = await $.get('/platform/enrollmentRegistration/apply/findOne', {id})
|
||||
if (resp.code === 0) {
|
||||
return resp.data
|
||||
}
|
||||
},
|
||||
onSave() {
|
||||
const msg = this.validateBirthday()
|
||||
if (msg) {
|
||||
this.$toast.fail(msg)
|
||||
return
|
||||
}
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定保存吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/enrollmentRegistration/apply/save', {
|
||||
data: JSON.stringify(this.formData)
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
pjaxReplace("/platform/enrollmentRegistration/applyList/h5")
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onSubmit() {
|
||||
const msg = this.validateBirthday()
|
||||
if (msg) {
|
||||
this.$toast.fail(msg)
|
||||
return
|
||||
}
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/enrollmentRegistration/apply/submit', {
|
||||
data: JSON.stringify(this.formData),
|
||||
taskId: GetQueryString("taskId")
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
pjaxReplace("/platform/enrollmentRegistration/applyList/h5")
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
|
||||
}).catch();
|
||||
},
|
||||
onFinishTask() {
|
||||
const msg = this.validateBirthday()
|
||||
if (msg) {
|
||||
this.$toast.fail(msg)
|
||||
return
|
||||
}
|
||||
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/enrollmentRegistration/apply/submitAgain', {
|
||||
data: JSON.stringify(this.formData),
|
||||
taskId: GetQueryString("taskId")
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
pjaxReplace("/platform/enrollmentRegistration/applyList/h5")
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
|
||||
}).catch();
|
||||
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
await this.getEnrollmentRegistrationPlan()
|
||||
this.init()
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,170 @@
|
||||
const H5_ENROLLMENT_REGISTRATION_INFO = {
|
||||
template: /*language=HTML*/ `
|
||||
<van-action-sheet v-model="visible" title="查看详情">
|
||||
<div>
|
||||
<div class="process-title">教职工信息</div>
|
||||
<van-cell-group>
|
||||
<van-cell title="监护人(教工)姓名">
|
||||
{{ viewData.userName }}
|
||||
</van-cell>
|
||||
<van-cell title="工号">
|
||||
{{ viewData.loginName }}
|
||||
</van-cell>
|
||||
<van-cell title="手机号码">
|
||||
{{ viewData.mobile }}
|
||||
</van-cell>
|
||||
<van-cell title="所在单位">
|
||||
{{ viewData.unitName }}
|
||||
</van-cell>
|
||||
<van-cell title="监护人与学生关系">
|
||||
<dict-tag :options="dict.type.ENROLLMENT_REGISTRATION_CHILD_RELATIONSHIP"
|
||||
:value="viewData.childRelationship"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="登记类型">
|
||||
<dict-tag :options="dict.type.ENROLLMENT_REGISTRATION_TYPE"
|
||||
:value="viewData.registrationType"></dict-tag>
|
||||
</van-cell>
|
||||
|
||||
</van-cell-group>
|
||||
|
||||
<div class="process-title">子女信息</div>
|
||||
<van-cell-group>
|
||||
<van-cell title="子女姓名">
|
||||
{{viewData.childrenName}}
|
||||
</van-cell>
|
||||
<van-cell title="性别">
|
||||
{{viewData.sex}}
|
||||
</van-cell>
|
||||
<van-cell title="身份证号">
|
||||
{{viewData.childrenIdCard}}
|
||||
</van-cell>
|
||||
<van-cell title="出生日期">
|
||||
{{viewData.childrenBirthday}}
|
||||
</van-cell>
|
||||
<van-cell title="现就读学校">
|
||||
{{viewData.childrenCurrentSchool}}
|
||||
</van-cell>
|
||||
<van-cell title="拟报就读学校">
|
||||
<dict-tag :options="dict.type.ENROLLMENT_REGISTRATION_CHILDREN_PLAN_SCHOOL"
|
||||
:value="viewData.childrenPlanSchool"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="子女户口所在地">
|
||||
{{viewData.childrenHuKouAddress}}
|
||||
</van-cell>
|
||||
<van-cell title="备注">
|
||||
{{viewData.note}}
|
||||
</van-cell>
|
||||
<van-cell title="户口簿照片">
|
||||
<template #label>
|
||||
<template v-for="(item,index) in viewData.huKouFiles">
|
||||
<van-image :src="item.url"
|
||||
v-if="item.url"
|
||||
class="signature-image"
|
||||
@click="previewOptionImg(viewData.huKouFiles,index)"></van-image>
|
||||
</template>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="子女出生证照片">
|
||||
<template #label>
|
||||
<template v-for="(item,index) in viewData.birthCertificateFiles">
|
||||
<van-image :src="item.url"
|
||||
v-if="item.url"
|
||||
class="signature-image"
|
||||
@click="previewOptionImg(viewData.birthCertificateFiles,index)"></van-image>
|
||||
</template>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<template v-for="(task,index) in doneTasks">
|
||||
<div class="process-title">
|
||||
{{ task.displayName }}
|
||||
</div>
|
||||
<van-cell-group v-if="task.ext.isFirstTaskNode">
|
||||
<van-cell title="申请用户">
|
||||
{{ task.ext.initiatorName}}({{task.ext.initiatorAccount}})
|
||||
</van-cell>
|
||||
<van-cell title="申请时间">
|
||||
{{ task.finishTime}}
|
||||
</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group v-else>
|
||||
<van-cell title="办理用户">
|
||||
{{ task.taskFormData.userName}}({{task.taskFormData.loginName}})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">
|
||||
{{ task.finishTime}}
|
||||
</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="办理意见" v-if="!task.ext.isFirstTaskNode">
|
||||
<template #label>
|
||||
{{
|
||||
task.taskFormData.opinion
|
||||
}}
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="签字" v-if="!task.ext.isFirstTaskNode">
|
||||
<van-image :src="task.ext.tf_userSign"
|
||||
v-if="task.ext.tf_userSign"
|
||||
class="signature-image"></van-image>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
|
||||
<slot></slot>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
`,
|
||||
dicts: ["ENROLLMENT_REGISTRATION_TYPE", "ENROLLMENT_REGISTRATION_CHILD_RELATIONSHIP", "ENROLLMENT_REGISTRATION_CHILDREN_PLAN_SCHOOL", "PROCESS_TASK_SUBMIT_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//预览图片
|
||||
previewOptionImg(files, index) {
|
||||
const urls = files.map(item => item.url)
|
||||
vant.ImagePreview({images: urls, startPosition: index})
|
||||
},
|
||||
// 打开
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
this.getInfo()
|
||||
this.getDoneTasks()
|
||||
},
|
||||
|
||||
// 关闭
|
||||
onClose() {
|
||||
this.visible = false
|
||||
},
|
||||
|
||||
// 获取申请信息
|
||||
getInfo() {
|
||||
this.$axios.post('/platform/enrollmentRegistration/apply/findOne', {id: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取已办任务审批记录
|
||||
getDoneTasks() {
|
||||
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doneTasks = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<!-- 导航栏 -->
|
||||
|
||||
<van-nav-bar title="我的申报" left-text="返回" left-arrow placeholder
|
||||
@click-left="historyBack" fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
|
||||
<table-list api="/platform/enrollmentRegistration/applyList/pageData" :page_form.sync="pageForm" ref="tableListRef"
|
||||
@ready="doSearch">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="子女姓名">{{row.childrenName}}</table-column>
|
||||
<table-column label="教职工姓名">{{row.userName}}</table-column>
|
||||
<table-column label="手机号码">{{row.mobile}}</table-column>
|
||||
<table-column label="所属单位">{{row.unitName}}</table-column>
|
||||
<table-column label="登记类型">
|
||||
<dict-tag :options="dict.type.ENROLLMENT_REGISTRATION_TYPE"
|
||||
:value="row.registrationType"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="填报时间">{{row.applyTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onEdit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>编辑</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onDelete(row.id)"
|
||||
v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>删除</span>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
|
||||
<h5-enrollment-registration-info ref="h5EnrollmentRegistrationInfoRef"></h5-enrollment-registration-info>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ENROLLMENT_REGISTRATION_TYPE", "ENROLLMENT_REGISTRATION_CHILD_RELATIONSHIP", "ENROLLMENT_REGISTRATION_CHILDREN_PLAN_SCHOOL"],
|
||||
components: {
|
||||
"h5-enrollment-registration-info": H5_ENROLLMENT_REGISTRATION_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.$refs.h5EnrollmentRegistrationInfoRef.onOpen(row)
|
||||
},
|
||||
onEdit(row) {
|
||||
pjaxReplace('/platform/enrollmentRegistration/apply/h5?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
|
||||
},
|
||||
onDelete(id) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要删除吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/enrollmentRegistration/applyList/doDelete", {id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$toast.fail(res.msg)
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.startTaskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$toast.fail(res.msg)
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
doSearch() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
},
|
||||
|
||||
},
|
||||
created() {
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="校工会审核" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名搜索"
|
||||
v-model="pageForm.searchKeyword"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/enrollmentRegistration/schoolAudit/pageData" :page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
@ready="doSearch">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="子女姓名">{{row.childrenName}}</table-column>
|
||||
<table-column label="教职工姓名">{{row.userName}}</table-column>
|
||||
<table-column label="手机号码">{{row.mobile}}</table-column>
|
||||
<table-column label="所属单位">{{row.unitName}}</table-column>
|
||||
<table-column label="登记类型">
|
||||
<dict-tag :options="dict.type.ENROLLMENT_REGISTRATION_TYPE"
|
||||
:value="row.registrationType"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="填报时间">{{row.applyTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.curTaskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<h5-enrollment-registration-info ref="h5EnrollmentRegistrationInfoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">
|
||||
校工会审核
|
||||
</div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-cell-group title="审批意见">
|
||||
<van-field label=""
|
||||
:rules="[{ required: true,message:'请填审批意见' }]"
|
||||
v-model="formData.tf_opinion"
|
||||
required
|
||||
type="textarea"
|
||||
name="tf_opinion"
|
||||
rows="4"
|
||||
autosize
|
||||
class="more-text"
|
||||
placeholder="请填审批意见"></van-field>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="电子签名" class="form-section">
|
||||
<van-field class="more-text" name="tf_userSign" label="">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button type="danger" @click="handleTaskAction(6)">退回到发起人</van-button>
|
||||
<van-button type="danger" @click="handleTaskAction(2)">拒绝申请</van-button>
|
||||
<van-button type="primary" @click="handleTaskAction(1)">同意申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
</h5-enrollment-registration-info>
|
||||
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ENROLLMENT_REGISTRATION_TYPE", "ENROLLMENT_REGISTRATION_CHILD_RELATIONSHIP", "ENROLLMENT_REGISTRATION_CHILDREN_PLAN_SCHOOL"],
|
||||
components: {
|
||||
"h5-enrollment-registration-info": H5_ENROLLMENT_REGISTRATION_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
searchName: "info.userName",
|
||||
},
|
||||
formData: {},
|
||||
infoShow: false,
|
||||
showApprovalForm: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/flow/common/executeTask', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.$refs.h5EnrollmentRegistrationInfoRef.onClose()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
tf_opinion: null,
|
||||
tf_userSign: null,
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
this.$refs.h5EnrollmentRegistrationInfoRef.onOpen(row)
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.infoShow = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.h5EnrollmentRegistrationInfoRef.onOpen(row)
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="分工会审核" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名搜索"
|
||||
v-model="pageForm.searchKeyword"
|
||||
></van-search>
|
||||
<!--<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
</van-dropdown-menu>-->
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/enrollmentRegistration/unionAudit/pageData" :page_form.sync="pageForm" ref="tableListRef"
|
||||
@ready="doSearch">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="子女姓名">{{row.childrenName}}</table-column>
|
||||
<table-column label="教职工姓名">{{row.userName}}</table-column>
|
||||
<table-column label="手机号码">{{row.mobile}}</table-column>
|
||||
<table-column label="所属单位">{{row.unitName}}</table-column>
|
||||
<table-column label="登记类型">
|
||||
<dict-tag :options="dict.type.ENROLLMENT_REGISTRATION_TYPE"
|
||||
:value="row.registrationType"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="填报时间">{{row.applyTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.curTaskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<h5-enrollment-registration-info ref="h5EnrollmentRegistrationInfoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">
|
||||
分工会审核
|
||||
</div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-cell-group title="审批意见">
|
||||
<van-field label=""
|
||||
:rules="[{ required: true,message:'请填审批意见' }]"
|
||||
v-model="formData.tf_opinion"
|
||||
required
|
||||
type="textarea"
|
||||
name="tf_opinion"
|
||||
rows="4"
|
||||
autosize
|
||||
class="more-text"
|
||||
placeholder="请填审批意见"></van-field>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="电子签名" class="form-section">
|
||||
<van-field class="more-text" name="tf_userSign" label="">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button type="danger" @click="handleTaskAction(6)">退回到发起人</van-button>
|
||||
<van-button type="danger" @click="handleTaskAction(2)">拒绝申请</van-button>
|
||||
<van-button type="primary" @click="handleTaskAction(1)">同意申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
</h5-enrollment-registration-info>
|
||||
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ENROLLMENT_REGISTRATION_TYPE", "ENROLLMENT_REGISTRATION_CHILD_RELATIONSHIP", "ENROLLMENT_REGISTRATION_CHILDREN_PLAN_SCHOOL"],
|
||||
components: {
|
||||
"h5-enrollment-registration-info": H5_ENROLLMENT_REGISTRATION_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
searchName: "info.userName",
|
||||
},
|
||||
formData: {},
|
||||
infoShow: false,
|
||||
showApprovalForm: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/flow/common/executeTask', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.$refs.h5EnrollmentRegistrationInfoRef.onClose()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
tf_opinion: null,
|
||||
tf_userSign: null,
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
this.$refs.h5EnrollmentRegistrationInfoRef.onOpen(row)
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.infoShow = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.h5EnrollmentRegistrationInfoRef.onOpen(row)
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,123 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="体检项目选择" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入项目名称搜索"
|
||||
v-model="pageForm.name"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.status"
|
||||
@change="onStatusChange">
|
||||
<van-tab title="进行中" name="ongoing"></van-tab>
|
||||
<van-tab title="已结束" name="finished"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/healthCheckup/h5/pageData" :page_form.sync="pageForm" ref="tableListRef"
|
||||
@ready="doSearch" img="cover">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="开始时间">
|
||||
{{$moment(row.choiceTimeStart).format('MM/DD HH:mm')}}
|
||||
</table-column>
|
||||
<table-column label="结束时间">
|
||||
{{$moment(row.choiceTimeEnd).format('MM/DD HH:mm')}}
|
||||
</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<template v-if="$moment().isBefore($moment(row.choiceTimeEnd))">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>去报名</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
yearList: [],
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: "",
|
||||
status: "ongoing", // 默认为进行中
|
||||
name: "" // 添加搜索名称字段
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 查看项目详情
|
||||
viewProjectDetail(row) {
|
||||
// 这里可以添加查看项目详情的逻辑
|
||||
console.log('查看项目详情:', row);
|
||||
},
|
||||
|
||||
onView(row) {
|
||||
/* if(row.selectCount > 0) {
|
||||
vant.Dialog.alert({
|
||||
title: '温馨提示',
|
||||
message: '此项活动您已选择',
|
||||
})
|
||||
return
|
||||
}*/
|
||||
// 检查项目是否已结束
|
||||
const now = new Date();
|
||||
const endTime = new Date(row.choiceTimeEnd);
|
||||
if (now > endTime) {
|
||||
vant.Toast('报名已经结束');
|
||||
return;
|
||||
}
|
||||
|
||||
this.$pjaxReplace("/platform/healthCheckup/h5/projectManageForm?projectId=" + row.id)
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
// 新增状态切换处理方法
|
||||
onStatusChange() {
|
||||
this.doSearch();
|
||||
},
|
||||
initData() {
|
||||
for (let i = new Date().getFullYear() - 10; i <= new Date().getFullYear(); i++) {
|
||||
this.yearList.unshift({value: i, text: i + "年"})
|
||||
}
|
||||
this.$set(this.pageForm, "year", this.yearList[0].value)
|
||||
// 初始化状态
|
||||
this.$set(this.pageForm, "status", "ongoing")
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,122 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="我的体检" placeholder fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-tabs v-model="pageForm.status"
|
||||
@change="onStatusChange">
|
||||
<van-tab title="进行中" name="ongoing"></van-tab>
|
||||
<van-tab title="已结束" name="finished"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
|
||||
<table-list api="/platform/healthCheckup/h5/mineData" :page_form.sync="pageForm" ref="tableListRef"
|
||||
@ready="doSearch" title="healthCheckupName">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="项目名称">{{row.name}}</table-column>
|
||||
<table-column label="开始时间">{{row.choiceTimeStart}}</table-column>
|
||||
<table-column label="结束时间">{{row.choiceTimeEnd}}</table-column>
|
||||
<table-column label="选择医院">{{row.optionName}}</table-column>
|
||||
<table-column label="邮寄地址">{{row.receiveAddress}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="edit(row)" v-if="new Date().getTime() < new Date(row.choiceTimeEnd).getTime()">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>修改</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="cancel(row)" v-if="new Date().getTime() < new Date(row.choiceTimeEnd).getTime()">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>取消</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
viewShow: false,
|
||||
yearList: [],
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: "",
|
||||
status: "ongoing", // 默认为进行中
|
||||
name: "" // 添加搜索名称字段
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
edit(row) {
|
||||
this.$pjaxReplace("/platform/healthCheckup/h5/projectManageForm?projectId=" + row.projectId)
|
||||
},
|
||||
async cancel(o) {
|
||||
vant.Dialog.confirm({
|
||||
title: '温馨提醒',
|
||||
message: '您确定要取消此选择吗?',
|
||||
}).then(async () => {
|
||||
const res = await $.post('/platform/healthCheckup/h5/cancel', {id: o.id, projectId: o.projectId})
|
||||
if (res.code === 0) {
|
||||
vant.Toast.success('取消成功')
|
||||
this.doSearch()
|
||||
} else {
|
||||
vant.Toast(res.msg)
|
||||
}
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
tabChange(val) {
|
||||
this.tabName = val
|
||||
this.startLoading()
|
||||
this.tableData = []
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageData()
|
||||
this.closeLoading()
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
// 新增状态切换处理方法
|
||||
onStatusChange() {
|
||||
this.doSearch();
|
||||
},
|
||||
init() {
|
||||
this.startLoading()
|
||||
this.pageForm.tabName = 'ing'
|
||||
this.pageData()
|
||||
this.closeLoading()
|
||||
},
|
||||
initData() {
|
||||
for (let i = new Date().getFullYear() - 10; i <= new Date().getFullYear(); i++) {
|
||||
this.yearList.unshift({value: i, text: i + "年"})
|
||||
}
|
||||
this.$set(this.pageForm, "year", this.yearList[0].value)
|
||||
// 初始化状态
|
||||
this.$set(this.pageForm, "status", "ongoing")
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.initData()
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+516
@@ -0,0 +1,516 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="体检套餐选择" placeholder
|
||||
fixed></van-nav-bar>
|
||||
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef" @submit="doSubmit">
|
||||
<van-cell-group title="基础信息">
|
||||
<van-field
|
||||
input-align="right"
|
||||
label="身份证号"
|
||||
name="idCard"
|
||||
readonly
|
||||
required
|
||||
placeholder="请联系校工会补充身份证号"
|
||||
v-model="formData.idCard"
|
||||
:rules="[{ required: true, message: '请输入身份证号' }]">
|
||||
</van-field>
|
||||
<van-cell title="人员类型">{{formData.userState}}</van-cell>
|
||||
<van-field
|
||||
input-align="right"
|
||||
readonly
|
||||
required
|
||||
label="婚姻状况"
|
||||
name="marriage"
|
||||
placeholder="请联系校工会补充婚姻状况"
|
||||
v-model="formData.marriage"
|
||||
:rules="[{ required: true, message: '请选择婚姻状况' }]"></van-field>
|
||||
|
||||
<van-cell title="出生年月">{{$moment(formData.birthday).format('YYYY-MM-DD')}}</van-cell>
|
||||
<van-cell title="单位">{{formData.unitName}}</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="本年度预约体检医院">
|
||||
<div class="van-card-body">
|
||||
<van-radio-group v-model="formData.subjectId" class="basic">
|
||||
<van-cell-group>
|
||||
<van-cell
|
||||
v-for="item in project.healthCheckupProjectSubjects"
|
||||
:key="item.id"
|
||||
:title="item.optionName">
|
||||
<template #label>
|
||||
<div style="display: flex; justify-content: space-between; margin-left: 8px">
|
||||
<!-- <div>{{ item.optionName }}</div>-->
|
||||
<div></div>
|
||||
<div @click.stop="viewDesc(item)" style="color: #0e78c5">查看说明</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #right-icon>
|
||||
<van-radio :name="item.id" @click.stop="clickRadio(item)"></van-radio>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</van-radio-group>
|
||||
</div>
|
||||
<van-field
|
||||
input-align="right"
|
||||
readonly
|
||||
required
|
||||
label="所选医院额度"
|
||||
name="marriage"
|
||||
placeholder="请选择医院"
|
||||
v-model="formData.money"
|
||||
:rules="[{ required: true, message: '请选择医院' }]"></van-field>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="体检报告邮寄地址">
|
||||
<van-radio-group v-model="formData.postMethod">
|
||||
<van-cell-group>
|
||||
<van-cell title="单位" clickable
|
||||
@click="formData.postMethod = '1';formData.receiveAddress=formData.unitName">
|
||||
<template #right-icon>
|
||||
<van-radio name="1"></van-radio>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="自选" clickable
|
||||
@click="formData.postMethod = '2';formData.receiveAddress=''">
|
||||
<template #right-icon>
|
||||
<van-radio name="2"></van-radio>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</van-radio-group>
|
||||
<template>
|
||||
<van-field
|
||||
v-if="formData.postMethod === '2'"
|
||||
v-model="formData.receiveAddress"
|
||||
label="邮寄地址"
|
||||
placeholder="请选择邮寄地址"
|
||||
readonly
|
||||
type="textarea"
|
||||
autosize
|
||||
rows="2"
|
||||
is-link
|
||||
@click="editAddressPopup = true"
|
||||
required
|
||||
></van-field>
|
||||
<van-cell title="邮寄地址" v-else>{{formData.receiveAddress}}</van-cell>
|
||||
</template>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- <van-cell-group title="基础信息">
|
||||
<div class="van-card-body">
|
||||
<van-field
|
||||
@click="campusVisible = true"
|
||||
readonly
|
||||
is-link
|
||||
label="院区"
|
||||
name="campus"
|
||||
placeholder="请选择体检院区"
|
||||
v-model="formData.campusName"
|
||||
:rules="[{ required: true, message: '请选择体检院区' }]">
|
||||
</van-field>
|
||||
<van-field
|
||||
:rules="[{ required: true, message: '请选择家属是否体检' }]"
|
||||
label="家属体检"
|
||||
name="isFamily">
|
||||
<template #input>
|
||||
<van-radio-group direction="horizontal" v-model="formData.isFamily">
|
||||
<van-radio name="是" shape="square">是</van-radio>
|
||||
<van-radio name="否" shape="square">否</van-radio>
|
||||
</van-radio-group>
|
||||
</template>
|
||||
</van-field>
|
||||
</div>
|
||||
</van-cell-group>-->
|
||||
|
||||
<van-cell-group title="家属信息" v-if="formData.isFamily === '是'">
|
||||
<div style="padding: 10px;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<span>家属信息</span>
|
||||
<div>
|
||||
<van-tag @click="delCompanion" size="large" type="primary" color="lightgrey">
|
||||
删除家属
|
||||
</van-tag>
|
||||
<van-tag @click="addCompanion" size="large" type="primary" color="#1867b0">
|
||||
添加家属
|
||||
</van-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="formData.companionList && formData.companionList.length > 0">
|
||||
<van-tabs v-model="active" type="card" color="#0e78c5" animated>
|
||||
<van-tab
|
||||
v-for="(item, index) in formData.companionList"
|
||||
:key="index"
|
||||
:title="'家属' + (index + 1)">
|
||||
<van-field
|
||||
label="姓名"
|
||||
name="userName"
|
||||
placeholder="请填写姓名"
|
||||
v-model="item.userName"
|
||||
:rules="[{ required: true, message: '请填写姓名' }]">
|
||||
</van-field>
|
||||
<van-field
|
||||
:rules="[{ required: true, message: '请选择性别' }]"
|
||||
label="性别"
|
||||
name="sex">
|
||||
<template #input>
|
||||
<van-radio-group direction="horizontal" v-model="item.sex">
|
||||
<van-radio name="男" shape="square">男</van-radio>
|
||||
<van-radio name="女" shape="square">女</van-radio>
|
||||
</van-radio-group>
|
||||
</template>
|
||||
</van-field>
|
||||
<van-field
|
||||
:rules="[{ required: true, message: '请选择婚否' }]"
|
||||
label="婚否"
|
||||
name="marry">
|
||||
<template #input>
|
||||
<van-radio-group direction="horizontal" v-model="item.marry">
|
||||
<van-radio name="未婚" shape="square">未婚</van-radio>
|
||||
<van-radio name="已婚" shape="square">已婚</van-radio>
|
||||
</van-radio-group>
|
||||
</template>
|
||||
</van-field>
|
||||
<van-field
|
||||
label="年龄"
|
||||
name="age"
|
||||
placeholder="请填写年龄"
|
||||
type="digit"
|
||||
:rules="[{ required: true, message: '请填写年龄' }]"
|
||||
v-model="item.age">
|
||||
</van-field>
|
||||
<van-field
|
||||
label="身份证号"
|
||||
name="idCard"
|
||||
placeholder="请填写身份证号"
|
||||
type="digit"
|
||||
:rules="[{ required: true, message: '请填写身份证号' }]"
|
||||
v-model="item.idCard">
|
||||
</van-field>
|
||||
<van-field
|
||||
label="手机号"
|
||||
name="mobile"
|
||||
placeholder="请填写手机号"
|
||||
type="digit"
|
||||
:rules="[{ required: true, message: '请填写手机号' }]"
|
||||
v-model="item.mobile">
|
||||
</van-field>
|
||||
</van-tab>
|
||||
</van-tabs>
|
||||
</div>
|
||||
<div v-else class="empty_text">
|
||||
<span>如有家属,请添加家属</span>
|
||||
</div>
|
||||
</div>
|
||||
</van-cell-group>
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button type="primary" native-type="submit">提交</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
|
||||
<!--体检院区弹出框-->
|
||||
<van-action-sheet title="体检院区" v-model="campusVisible">
|
||||
<van-picker
|
||||
title="院区"
|
||||
show-toolbar
|
||||
:columns="campusList"
|
||||
value-key="campusName"
|
||||
@confirm="onCampusConfirm"
|
||||
@cancel="campusVisible = false">
|
||||
</van-picker>
|
||||
</van-action-sheet>
|
||||
|
||||
<!--查看说明-->
|
||||
<van-action-sheet title="医院说明" v-model="descVisible" :style="{ height: '60%' }">
|
||||
<div class="form-container" style="margin: 10px;">
|
||||
<van-cell-group title="说明"></van-cell-group>
|
||||
<div v-html="desc" class="pre_text"></div>
|
||||
<div style="margin-top: 10px">
|
||||
<van-cell-group title="以下内容由医院方提供"></van-cell-group>
|
||||
<file-preview :files="files" complete_result></file-preview>
|
||||
</div>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
|
||||
<!-- 收货地址选择弹窗 -->
|
||||
<van-action-sheet v-model="editAddressPopup" title="选择收货地址" :round="true">
|
||||
<div style="padding: 16px 0 0">
|
||||
<div
|
||||
v-for="address in addressOptions"
|
||||
:key="address.id"
|
||||
class="address-item"
|
||||
@click="selectAddress(address)"
|
||||
style="padding: 12px 16px; border-bottom: 1px solid #f0f0f0; cursor: pointer"
|
||||
>
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-start">
|
||||
<div style="flex: 1">
|
||||
<div style="font-size: 16px; font-weight: 500; color: #323233; margin-bottom: 4px">
|
||||
{{ address.userName }} {{ address.tel }}
|
||||
</div>
|
||||
<div style="font-size: 14px; color: #646566; line-height: 1.4">
|
||||
{{ address.province }}{{ address.city }}{{ address.county }}{{ address.addressDetail
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<van-tag v-if="address.isDefault" type="primary" size="mini" style="margin-left: 8px">默认
|
||||
</van-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="addressOptions.length === 0"
|
||||
style="text-align: center; padding: 40px 16px; color: #969799">暂无收货地址
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding: 16px; border-top: 1px solid #f0f0f0; background: #fafafa">
|
||||
<van-button type="info" block round @click="goToAddressManage">收货地址管理</van-button>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ASSET_USAGE_STATE"],
|
||||
data() {
|
||||
return {
|
||||
viewData: {},
|
||||
formData: {
|
||||
subjectId: '',
|
||||
campus: '',
|
||||
campusName: '',
|
||||
isFamily: '否',
|
||||
companionList: [],
|
||||
projectId: '',
|
||||
postMethod: ''
|
||||
},
|
||||
assetUsageStateNameOption: [],
|
||||
showAssetUsageStateNamePopup: false,
|
||||
assetUseUserOption: [],
|
||||
assetUseNameShow: false,
|
||||
searchKeyword: "",
|
||||
active: 0,
|
||||
campusList: [],
|
||||
campusVisible: false,
|
||||
descVisible: false,
|
||||
desc: '',
|
||||
files: [],
|
||||
project: {},
|
||||
|
||||
marriageList: ["已婚", "未婚"],
|
||||
marriageVisible: false,
|
||||
|
||||
editAddressPopup: false,
|
||||
addressOptions: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 选择收货地址
|
||||
selectAddress(address) {
|
||||
this.formData.receiveAddress =
|
||||
address.userName + " " + address.tel + " " + address.province + address.city + address.county + address.addressDetail
|
||||
this.editAddressPopup = false
|
||||
},
|
||||
// 跳转到地址管理页面
|
||||
goToAddressManage() {
|
||||
this.$pjaxReplace("/platform/h5/welfare/address/list")
|
||||
},
|
||||
// 获取收货地址
|
||||
getAddress() {
|
||||
this.$axios.post("/platform/welfare/addressManage/selectUserAddress").then(resp => {
|
||||
if (resp.code === 0) {
|
||||
this.addressOptions = resp.data
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
isEmptyObject(obj) {
|
||||
for (let key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
addressClick() {
|
||||
|
||||
},
|
||||
// 打开表单
|
||||
async initData() {
|
||||
await this.getCampus()
|
||||
this.getAddress()
|
||||
await this.findSubject(GetQueryString("projectId"))
|
||||
if (GetQueryString("projectId")) {
|
||||
await this.selectInfo(GetQueryString("projectId"));
|
||||
const {idCard, userState, marriage, birthday, unit} = this.$store.state.user
|
||||
this.$set(this.formData, 'projectId', GetQueryString("projectId"))
|
||||
this.$set(this.formData, 'idCard', idCard)
|
||||
this.$set(this.formData, 'userState', userState)
|
||||
this.$set(this.formData, 'marriage', marriage)
|
||||
this.$set(this.formData, 'birthday', birthday)
|
||||
this.$set(this.formData, 'unitName', unit.name)
|
||||
this.$set(this.formData, 'postMethod', this.formData?.postMethod ? this.formData.postMethod : "1")
|
||||
this.$set(this.formData, 'receiveAddress', this.formData?.receiveAddress ? this.formData.receiveAddress : unit.name)
|
||||
}
|
||||
},
|
||||
clickRadio(item) {
|
||||
const toast = this.$toast.loading({
|
||||
duration: 0, // 持续展示 toast
|
||||
forbidClick: true,
|
||||
message: '查询中....',
|
||||
});
|
||||
$.post("/platform/healthCheckup/h5/getSubjectMoney", {
|
||||
id: item.id,
|
||||
marriage: this.formData.marriage
|
||||
}).then(resp => {
|
||||
if (resp.code === 0) {
|
||||
this.$set(this.formData, 'subjectId', item.id)
|
||||
this.$set(this.formData, 'money', resp.data.money)
|
||||
this.$set(this.formData, 'subjectMoneyId', resp.data.subjectMoneyId)
|
||||
} else {
|
||||
this.$set(this.formData, 'money', 0)
|
||||
}
|
||||
toast.clear();
|
||||
})
|
||||
},
|
||||
async selectInfo(projectId) {
|
||||
const resp = await this.$axios.post('/platform/healthCheckup/h5/selectInfo', {projectId: projectId});
|
||||
if (resp.data !== null) {
|
||||
this.formData = resp.data;
|
||||
/* const o = this.campusList.find(o => o.id === this.formData.campus)
|
||||
this.formData.campusName = o.campusName*/
|
||||
}
|
||||
},
|
||||
|
||||
// 查看说明
|
||||
viewDesc(item) {
|
||||
if (item.description || item.files) {
|
||||
this.files = item.files;
|
||||
this.desc = item.description;
|
||||
this.descVisible = true;
|
||||
} else {
|
||||
vant.Toast('暂无详细说明');
|
||||
}
|
||||
},
|
||||
|
||||
// 执行提交
|
||||
async doSubmit() {
|
||||
const formData = clone(this.formData);
|
||||
if (!formData.receiveAddress) {
|
||||
this.$toast.fail('请填写邮寄地址!')
|
||||
}
|
||||
|
||||
const subject = this.project.healthCheckupProjectSubjects.find(v => v.id === formData.subjectId)
|
||||
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交选择的【' + subject.optionName + '】吗?',
|
||||
}).then(() => {
|
||||
const toast = this.$toast.loading({
|
||||
duration: 0, // 持续展示 toast
|
||||
forbidClick: true,
|
||||
message: '提交中....',
|
||||
});
|
||||
/* if (formData.isFamily === '否') {
|
||||
formData.companionList = [];
|
||||
} else {
|
||||
// 过滤空的家属信息
|
||||
formData.companionList = formData.companionList.filter(item => item.userName && item.userName.trim() !== '');
|
||||
}*/
|
||||
this.$axios.post('/platform/healthCheckup/h5/doSubmit', {
|
||||
userSelection: JSON.stringify(formData),
|
||||
}).then(resp => {
|
||||
if (resp.code === 0) {
|
||||
toast.clear();
|
||||
this.$toast.success(resp.msg)
|
||||
this.historyBack()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
});
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
// 添加家属
|
||||
addCompanion() {
|
||||
// 检查是否已达到最大数量限制
|
||||
if (this.companionList && this.formData.companionList.length >= 5) {
|
||||
vant.Toast('最多只能添加5个家属');
|
||||
return;
|
||||
}
|
||||
if (!this.formData.companionList) {
|
||||
this.$set(this.formData, 'companionList', []);
|
||||
}
|
||||
this.formData.companionList.push({
|
||||
userName: '', sex: '', marry: '', age: '', idCard: '', mobile: ''
|
||||
});
|
||||
},
|
||||
|
||||
// 删除家属
|
||||
delCompanion() {
|
||||
if (this.formData.companionList && this.formData.companionList.length > 0) {
|
||||
this.formData.companionList.splice(this.active, 1);
|
||||
// 确保active索引有效
|
||||
if (this.active >= this.formData.companionList.length && this.active > 0) {
|
||||
this.active = this.formData.companionList.length - 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 院区选择确认
|
||||
onCampusConfirm(value) {
|
||||
this.formData.campusName = value.campusName;
|
||||
this.formData.campus = value.id;
|
||||
this.campusVisible = false;
|
||||
},
|
||||
|
||||
// 婚姻状况确认
|
||||
onMarriageConfirm(value) {
|
||||
this.$set(this.formData, 'marriage', value)
|
||||
this.$set(this.formData, 'subjectId', null)
|
||||
this.marriageVisible = false;
|
||||
},
|
||||
|
||||
// 查询体检套餐
|
||||
async findSubject(id) {
|
||||
try {
|
||||
const resp = await this.$axios.post('/platform/healthCheckup/project/mange/findOne', {
|
||||
id: id
|
||||
});
|
||||
this.project = resp.data || {};
|
||||
} catch (error) {
|
||||
vant.Toast('获取体检套餐失败');
|
||||
}
|
||||
},
|
||||
|
||||
// 获取院区
|
||||
async getCampus() {
|
||||
try {
|
||||
const resp = await this.$axios.post('/platform/healthCheckup/h5/getCampus');
|
||||
this.campusList = resp.data || [];
|
||||
} catch (error) {
|
||||
vant.Toast('获取院区失败');
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initData()
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
.info-title {
|
||||
font-weight: bold;
|
||||
background-color: white;
|
||||
padding: 13px;
|
||||
box-shadow: 0 8px 12px #ebedf0;
|
||||
text-align: center !important;
|
||||
}
|
||||
.info-container {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
.button {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.info-img {
|
||||
display: block;
|
||||
}
|
||||
.van-count-down {
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="职工素养培训" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.activityType" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/literacy/apply/activityPageData"
|
||||
:page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
title="activityName"
|
||||
img="cover"
|
||||
@ready="onReady"
|
||||
>
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="面向对象">{{row.activityGroupName}}</table-column>
|
||||
<table-column label="报名时间">
|
||||
{{$moment(row.activitySignUpStartTime).format('MM/DD HH:mm') + '~' + $moment(row.activitySignUpEndTime).format('MM/DD HH:mm')}}
|
||||
</table-column>
|
||||
<table-column label="活动时间">
|
||||
{{$moment(row.activityStartTime).format('MM/DD HH:mm') + '~' + $moment(row.activityEndTime).format('MM/DD HH:mm')}}
|
||||
</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<template v-if="$moment().isBefore($moment(row.activitySignUpEndTime))">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看介绍</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onApply(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>去报名</span>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<van-action-sheet :close-on-click-overlay="false" title="详细信息" v-model="infoVisible">
|
||||
|
||||
<div class="info-container">
|
||||
<div>
|
||||
<van-image class="info-img" height="186" width="100%" :src="infoRow.cover"></van-image>
|
||||
<div class="info-title">{{infoRow.activityName}}</div>
|
||||
<pdf-preview :content="infoRow.introduce"></pdf-preview>
|
||||
</div>
|
||||
<div class="button">
|
||||
<van-button @click="onApply(infoRow)" type="primary" block>
|
||||
<span v-if="time >= 0">
|
||||
去报名
|
||||
</span>
|
||||
<template v-else>
|
||||
距离开始
|
||||
<van-count-down :time="Math.abs(time)" class="count-down" format="DD 天 HH 时 mm 分 ss 秒" @finish="time = 0"></van-count-down>
|
||||
</template>
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
"pdf-preview": httpVueLoader("/components/plugins/sysFilePreview/PdfIndex.vue?v=" + new Date().getTime())
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
time: 0,
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
year: new Date().getFullYear(),
|
||||
activityType: 2,
|
||||
},
|
||||
typeOptions: [
|
||||
{text: '全部', value: 1},
|
||||
{text: '即将开始 & 报名中', value: 2},
|
||||
{text: '已结束', value: 3},
|
||||
],
|
||||
infoVisible: false,
|
||||
infoRow: {},
|
||||
|
||||
id: GetQueryString('id')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.infoRow = row
|
||||
this.time = this.$moment().diff(this.$moment(row.activitySignUpStartTime), 'milliseconds')
|
||||
this.infoVisible = true
|
||||
},
|
||||
onApply(row) {
|
||||
if(this.$moment().isBefore(this.$moment(row.activitySignUpStartTime))) {
|
||||
this.onView(row)
|
||||
return
|
||||
}
|
||||
this.$pjaxReplace('/platform/literacy/apply/list/h5?id=' + row.id)
|
||||
},
|
||||
fetchOne() {
|
||||
this.$axios.post('/platform/literacy/manage/findOne', {id: this.id}).then((res) => {
|
||||
if(res.code === 0) {
|
||||
this.onView(res.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
onReady() {
|
||||
this.doSearch()
|
||||
if(this.id) {
|
||||
this.fetchOne()
|
||||
}
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,89 @@
|
||||
const times = {
|
||||
template:
|
||||
/*language=HTML*/
|
||||
`
|
||||
<div>
|
||||
<van-action-sheet v-model="visible" title="时间段" cancel-text="取消">
|
||||
<button v-for="(item,index) in row?.courseTimes" type="button" class="van-action-sheet__item">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div>
|
||||
<div class="van-action-sheet__name">
|
||||
<label>{{ weekdayCNMap[$moment(item.courseDate).day()] }}</label>
|
||||
<label>{{ $moment(item.courseDate).format('YYYY-MM-DD') }}</label>
|
||||
</div>
|
||||
<div class="van-action-sheet__subname">
|
||||
{{$moment(item.courseStartTime).format('MM-DD HH:mm') + ' 至 ' + $moment(item.courseEndTime).format('MM-DD HH:mm')}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="row.isSign === true && row.isMobileSign === true" class="sign_button">
|
||||
<van-button v-if="item.isAttend !== true" @click.stop="onSign(item)" size="mini" type="info">签到</van-button>
|
||||
<van-button v-if="item.isAttend === true" size="mini" type="info" disabled>已签到</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</van-action-sheet>
|
||||
|
||||
<van-popup round :safe-area-inset-bottom="true"
|
||||
:close-on-click-overlay="false"
|
||||
v-model="signVisible"
|
||||
:style="{ width: '80%', height: '66%' }"
|
||||
get-container="#app"
|
||||
@close="onSignClose"
|
||||
closeable
|
||||
>
|
||||
<scan-code ref="scanCodeRef"></scan-code>
|
||||
</van-popup>
|
||||
</div>
|
||||
`,
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
visible:false,
|
||||
row: null,
|
||||
weekdayCNMap: {0: '周日', 1: '周一', 2: '周二', 3: '周三', 4: '周四', 5: '周五', 6: '周六'},
|
||||
|
||||
selectCourseTime: {},
|
||||
signVisible: false,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"scan-code": httpVueLoader("/components/plugins/sysScanCode/index.vue?v=" + new Date().getTime())
|
||||
},
|
||||
methods: {
|
||||
onSignClose() {
|
||||
this.$refs.scanCodeRef.closeScan()
|
||||
},
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
},
|
||||
onSign(courseTime) {
|
||||
this.selectCourseTime = courseTime
|
||||
if(this.row.signType === 1) {
|
||||
this.signVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.scanCodeRef.init()
|
||||
})
|
||||
}
|
||||
if(this.row.signType === 2) {
|
||||
this.makeCode()
|
||||
}
|
||||
if(this.row.signType === 3) {
|
||||
this.$toast('此签到模式正在升级中')
|
||||
}
|
||||
},
|
||||
makeCode() {
|
||||
const url = '/platform/literacy/mine/passiveScan'
|
||||
const data = url + '?id=' + this.selectCourseTime.id
|
||||
console.log(data)
|
||||
const content = jrQrcode.getQrBase64(data)
|
||||
vant.ImagePreview([content])
|
||||
},
|
||||
onClose(){
|
||||
this.visible = false
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
const applyForm = {
|
||||
template:
|
||||
/*language=HTML*/
|
||||
`
|
||||
<div>
|
||||
<van-action-sheet :close-on-click-overlay="false" title="报名信息" v-model="visible">
|
||||
<van-form ref="formRef" class="form-container">
|
||||
<van-cell-group title="活动信息" class="form-section">
|
||||
<van-field label="活动名称" readonly v-model="row.courseName"></van-field>
|
||||
<van-field label="校区" readonly v-model="row.campus"></van-field>
|
||||
<van-field label="活动地点" readonly v-model="row.courseLocation"></van-field>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="基础信息" class="form-section">
|
||||
<van-field label="姓名" readonly v-model="formData.username"></van-field>
|
||||
<van-field label="工号" readonly v-model="formData.loginname"></van-field>
|
||||
<van-field label="所属单位" readonly v-model="formData.unitName"></van-field>
|
||||
<van-field label="所属工会" readonly v-model="formData.unionName"></van-field>
|
||||
<van-field label="性别" readonly v-model="formData.sex"></van-field>
|
||||
<template v-if="row.courseIsLimitApply">
|
||||
<van-field label="报名时段"
|
||||
required
|
||||
:rules="[{ required: true, message: '请选择报名时段' }]"
|
||||
readonly
|
||||
@click="showCoursePicker = true"
|
||||
placeholder="请选择报名时段"
|
||||
name="courseTimeName"
|
||||
v-model="formData.courseTimeName">
|
||||
</van-field>
|
||||
<van-popup v-model="showCoursePicker" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="courseTimeSelectList"
|
||||
@confirm="onCourseConfirm"
|
||||
@cancel="showCoursePicker=false"
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
</template>
|
||||
<train-dynamic-form v-model="dynamicColumnsData" ref="dynamicForm"></train-dynamic-form>
|
||||
</van-cell-group>
|
||||
|
||||
<div class="button">
|
||||
<van-button @click="onSubmit" round type="info" block>提交</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</van-action-sheet>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
row: {},
|
||||
activity: {},
|
||||
dynamicColumnsData: [],
|
||||
visible: false,
|
||||
formData: {},
|
||||
showCoursePicker: false,
|
||||
courseTimeSelectList: [],
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"train-dynamic-form": httpVueLoader("/components/module/trainSignUp/TrainDynamicForm.vue")
|
||||
},
|
||||
methods: {
|
||||
async onOpen(row, courseType) {
|
||||
this.row = row
|
||||
this.init(row, courseType)
|
||||
if(row.courseIsLimitApply) {
|
||||
await this.getCourseTimeSelectList(row)
|
||||
}
|
||||
this.visible = true
|
||||
},
|
||||
init(row, courseType) {
|
||||
this.$set(this.formData, 'username', this.$store.state.user.username)
|
||||
this.$set(this.formData, 'loginname', this.$store.state.user.loginname)
|
||||
this.$set(this.formData, 'unionName', this.$store.state.user.union.name)
|
||||
this.$set(this.formData, 'unitName', this.$store.state.user.unit.name)
|
||||
this.$set(this.formData, 'sex', this.$store.state.user.sex)
|
||||
this.$set(this.formData, 'activityId', row.activityId)
|
||||
this.$set(this.formData, 'courseId', row.id)
|
||||
|
||||
this.dynamicColumnsData = courseType ? courseType.trainMobileSignColumnList : []
|
||||
this.dynamicColumnsData.forEach((item) => {
|
||||
item.columnValue = this.$store.state.user[item.columnCode] || ""
|
||||
})
|
||||
},
|
||||
onCourseConfirm(val){
|
||||
this.formData.activityCourseId = val.value
|
||||
this.$set(this.formData, "activityCourseId", val.value)
|
||||
this.$set(this.formData, "courseTimeName", val.text.substring(0, 12))
|
||||
this.showCoursePicker = false
|
||||
},
|
||||
async getCourseTimeSelectList(o) {
|
||||
const resp = await this.$axios.post('/platform/literacy/apply/getCourseTimeSelectList',{courseId: o.id})
|
||||
if (resp.code === 0) {
|
||||
this.courseTimeSelectList = resp.data
|
||||
} else {
|
||||
this.$toast.fail("获取时段信息失败,请联系管理员")
|
||||
}
|
||||
},
|
||||
async validateSignUp() {
|
||||
// 验证自定义表单
|
||||
await this.$refs.dynamicForm.$refs.form.validate()
|
||||
// 获取家属人数
|
||||
let familyCount = this.dynamicColumnsData.filter(o => o.columnCode === 'xdqsrs').reduce((sum, item) => {
|
||||
return sum + (Number(item.columnValue) || 0)
|
||||
}, 0)
|
||||
|
||||
const res = await this.$axios.post("/platform/literacy/apply/validateSignUp", {
|
||||
courseId: this.formData.courseId,
|
||||
currentFamilyNumber: familyCount
|
||||
})
|
||||
return res.code === 0
|
||||
},
|
||||
async validateCourseTime() {
|
||||
const res = await this.$axios.post('/platform/literacy/apply/validateSourceSignUp', {
|
||||
activityCourseId: this.formData.activityCourseId,
|
||||
courseId: this.row.id
|
||||
})
|
||||
return res.code === 0
|
||||
},
|
||||
async onSubmit() {
|
||||
if(!await this.validateSignUp()) return
|
||||
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(async () => {
|
||||
if (this.row.courseIsLimitApply) {
|
||||
if(!await this.validateCourseTime()) return
|
||||
}
|
||||
|
||||
const mobileColumnsValue = this.dynamicColumnsData.map((v) => {
|
||||
return {
|
||||
columnName: v.columnName,
|
||||
columnValue: v.columnValue,
|
||||
columnCode: v.columnCode,
|
||||
columnFormType: v.columnFormType
|
||||
}
|
||||
})
|
||||
this.formData.mobileColumnsValue = JSON.stringify(mobileColumnsValue)
|
||||
this.$axios.post("/platform/literacy/apply/doSignUp", this.formData).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast(res.msg)
|
||||
this.visible = false
|
||||
this.$emit('refresh')
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
/deep/ .button {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
.primary-color {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
.sign_button .van-button{
|
||||
width: 66px;
|
||||
height: 30px;
|
||||
font-size: 14px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="职工素养培训报名" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-item v-model="pageForm.courseTypeId" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
<van-tabs v-if="assortList.length > 0" type="card" color="#1867B0"
|
||||
style="margin-top: 10px" @click="tabClick">
|
||||
<van-tab v-for="item,index in assortList" :name="item" :title="item" :key="index">
|
||||
</van-tab>
|
||||
</van-tabs>
|
||||
|
||||
<table-list api="/platform/literacy/apply/pageData"
|
||||
:page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
@ready="onReady"
|
||||
>
|
||||
<template #header="{index,row}">
|
||||
<div class="item-header">
|
||||
<div class="item-title">{{ row.courseName }}</div>
|
||||
<div v-html="calcSignUpCount(row)"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="类型">{{row.typeName}}</table-column>
|
||||
<table-column label="校区">{{row.campus}}</table-column>
|
||||
<table-column label="地点">{{row.courseLocation}}</table-column>
|
||||
<table-column label="联系人">{{row.courseInstructor}}</table-column>
|
||||
<table-column label="时间">
|
||||
<span v-if="row.courseTimes && row.courseTimes.length === 1" class="primary-color" @click="onTime(row)">
|
||||
{{ weekdayCNMap[$moment(row.courseTimes[0].courseDate).day()]
|
||||
+ ' '
|
||||
+ $moment(row.courseTimes[0].courseStartTime).format('MM月DD日 HH:mm')
|
||||
+ '~'
|
||||
+ $moment(row.courseTimes[0].courseEndTime).format('HH:mm') }}
|
||||
</span>
|
||||
<span v-else @click="onTime(row)" class="primary-color">点我查看</span>
|
||||
</table-column>
|
||||
<table-column v-if="row.introduce" label="详细信息">
|
||||
<span @click="introduceRow = row; introduceVisible = true" class="primary-color">点我查看</span>
|
||||
</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div v-if="activity.wechat && row.isSign" class="action-btn" @click="this.vant.ImagePreview([activity.wechat])">
|
||||
<i class="fa fa-wechat"></i>
|
||||
<span>微信群二维码</span>
|
||||
</div>
|
||||
<template v-if="$moment().isBefore($moment(activity.activitySignUpEndTime))">
|
||||
<div v-if="row.isSign === false" class="action-btn" @click="onApply(row)">
|
||||
<i class="fa fa-sign-in"></i>
|
||||
<span>我要报名</span>
|
||||
</div>
|
||||
<div v-if="row.isSign === true" class="action-btn delete" @click="onCancel(row)">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>取消报名</span>
|
||||
</div>
|
||||
</template>
|
||||
<div v-if="row.isSign === true && row.isMobileSign === true && $moment().isAfter($moment(activity.activitySignUpEndTime))"
|
||||
class="action-btn"
|
||||
@click="onTime(row)"
|
||||
>
|
||||
<i class="fa fa-sign-in"></i>
|
||||
<span>签到</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<van-action-sheet :close-on-click-overlay="false" title="详细信息" v-model="introduceVisible" cancel-text="取消">
|
||||
<pdf-preview :content="introduceRow.introduce"></pdf-preview>
|
||||
</van-action-sheet>
|
||||
|
||||
<times ref="timesRef"></times>
|
||||
<apply-form ref="formRef" @refresh="refresh"></apply-form>
|
||||
</div>
|
||||
|
||||
<script src="${base!}/assets/platform/plugins/jr-qrcode/jr-qrcode.js"></script>
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/times.js'){}#-->
|
||||
<!--#include('applyForm.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
'times': times,
|
||||
'apply-form': applyForm,
|
||||
"pdf-preview": httpVueLoader("/components/plugins/sysFilePreview/PdfIndex.vue?v=" + new Date().getTime())
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
year: new Date().getFullYear(),
|
||||
courseTypeId: null,
|
||||
activityId: GetQueryString('id'),
|
||||
dataType: GetQueryString('dataType'),
|
||||
assortTypes: [],
|
||||
},
|
||||
typeOptions: [],
|
||||
assortOptions: [],
|
||||
sourceTypeOptions: [],
|
||||
introduceVisible: false,
|
||||
|
||||
introduceRow: {},
|
||||
activity: {},
|
||||
assortList: [],
|
||||
|
||||
weekdayCNMap: {0: '周日', 1: '周一', 2: '周二', 3: '周三', 4: '周四', 5: '周五', 6: '周六'},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
tabClick(name) {
|
||||
this.pageForm.assortTypes = []
|
||||
this.pageForm.assortTypes.push(name)
|
||||
this.pageForm.assortTypes = JSON.stringify(this.pageForm.assortTypes)
|
||||
this.doSearch()
|
||||
},
|
||||
refresh() {
|
||||
this.doSearch()
|
||||
},
|
||||
async onTime(row) {
|
||||
// 如果设置签到,并且也报名的话
|
||||
if(row.isMobileSign === true && row.isSign === true) {
|
||||
const res = await this.$axios.post('/platform/literacy/mine/queryCourseSign', {
|
||||
courseId: row.id
|
||||
})
|
||||
row.courseTimes = res.data
|
||||
}
|
||||
this.$refs.timesRef.onOpen(row)
|
||||
},
|
||||
onApply(row) {
|
||||
const courseType = this.sourceTypeOptions.find((v) => v.id === row.courseType)
|
||||
this.$axios.post('/platform/literacy/apply/validateSignUp', {
|
||||
courseId: row.id
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code !== 0) {
|
||||
vant.Dialog.alert({
|
||||
title: '提示',
|
||||
message: res.msg,
|
||||
confirmButtonColor: '#1867b0'
|
||||
})
|
||||
} else {
|
||||
let lave = row.coursePeopleNumber - (row.hasRegisterNum + row.courseReservedNumber)
|
||||
if(row.reserveMode === 2 && lave <= 0) {
|
||||
vant.Dialog.alert({
|
||||
title: '提示',
|
||||
message: '您当前的报名为候补报名状态',
|
||||
confirmButtonColor: '#1867b0'
|
||||
})
|
||||
}
|
||||
this.$refs.formRef.onOpen(row, courseType)
|
||||
}
|
||||
})
|
||||
},
|
||||
onCancel(row) {
|
||||
vant.Dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: "您确定要<span style='color: red'>取消【" + row.courseName + "】</span>吗?",
|
||||
confirmButtonColor: '#1867b0',
|
||||
}).then(async () => {
|
||||
const resp = await this.$axios.post('/platform/literacy/apply/cancelSignUp', {
|
||||
activityId: row.activityId,
|
||||
courseId: row.id
|
||||
})
|
||||
this.$toast(resp.msg)
|
||||
if (resp.code === 0) {
|
||||
this.doSearch()
|
||||
}
|
||||
}).catch(() => {})
|
||||
},
|
||||
calcSignUpCount(row) {
|
||||
if(!row.coursePeopleNumber || row.coursePeopleNumber === 0) {
|
||||
return "名额数不限制"
|
||||
}
|
||||
let lave = row.coursePeopleNumber - (row.hasRegisterNum + row.courseReservedNumber)
|
||||
if(row.reserveMode === 2) {
|
||||
let lave2 = row.waitingNum - row.hasWaitingNum
|
||||
return "<span style='color: red'>余" + lave +"</span>/" + row.coursePeopleNumber + "人"
|
||||
+ ",<span style='color: red'>候补余" + lave2 + "</span>/" + row.waitingNum + "人"
|
||||
} else {
|
||||
return "<span style='color: red'>余" + lave +"</span>/" + row.coursePeopleNumber + "人"
|
||||
}
|
||||
},
|
||||
async onReady() {
|
||||
this.queryCourseAssort()
|
||||
const typeList = await this.getCourseTypeList()
|
||||
this.sourceTypeOptions = clone(typeList)
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: "全部类型",
|
||||
value: null
|
||||
}
|
||||
].concat(typeList.map((v) => ({ text: v.typeName, value: v.id })))
|
||||
if (this.typeOptions.length > 0) {
|
||||
this.pageForm.type = this.typeOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
this.fetchActivity()
|
||||
},
|
||||
fetchActivity() {
|
||||
this.$axios.post('/platform/literacy/manage/findOne', {id: this.pageForm.activityId})
|
||||
.then((res) => {
|
||||
this.activity = res.data
|
||||
})
|
||||
},
|
||||
async getCourseTypeList() {
|
||||
const resp = await this.$axios.post("/platform/literacy/type/getAllType")
|
||||
return resp.data
|
||||
},
|
||||
queryCourseAssort() {
|
||||
this.$axios.post("/platform/literacy/apply/queryCourseAssort", {activityId: this.pageForm.activityId})
|
||||
.then((resp) => {
|
||||
this.assortList = resp.data
|
||||
if(this.assortList.length > 0) {
|
||||
this.pageForm.assortTypes = JSON.stringify([this.assortList[0]])
|
||||
}
|
||||
})
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,132 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
.info-title {
|
||||
font-weight: bold;
|
||||
background-color: white;
|
||||
padding: 13px;
|
||||
box-shadow: 0 8px 12px #ebedf0;
|
||||
text-align: center !important;
|
||||
}
|
||||
.info-container {
|
||||
|
||||
}
|
||||
.button {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.info-img {
|
||||
display: block;
|
||||
}
|
||||
.van-count-down {
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="职工素养培训-我的报名" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.activityType" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/literacy/apply/activityPageData"
|
||||
:page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
title="activityName"
|
||||
img="cover"
|
||||
@ready="onReady"
|
||||
>
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="面向对象">{{row.activityGroupName}}</table-column>
|
||||
<table-column label="报名时间">
|
||||
{{$moment(row.activitySignUpStartTime).format('MM/DD HH:mm') + '~' + $moment(row.activitySignUpEndTime).format('MM/DD HH:mm')}}
|
||||
</table-column>
|
||||
<table-column label="活动时间">
|
||||
{{$moment(row.activityStartTime).format('MM/DD HH:mm') + '~' + $moment(row.activityEndTime).format('MM/DD HH:mm')}}
|
||||
</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看介绍</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onApply(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<van-action-sheet :close-on-click-overlay="false" title="活动详细信息" v-model="infoVisible" cancel-text="取消">
|
||||
|
||||
<div class="info-container">
|
||||
<div>
|
||||
<van-image class="info-img" height="186" width="100%" :src="infoRow.cover"></van-image>
|
||||
<div class="info-title">{{infoRow.activityName}}</div>
|
||||
<pdf-preview :content="infoRow.introduce"></pdf-preview>
|
||||
</div>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
"pdf-preview": httpVueLoader("/components/plugins/sysFilePreview/PdfIndex.vue?v=" + new Date().getTime())
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
year: new Date().getFullYear(),
|
||||
activityType: 1,
|
||||
dataType: 'mine'
|
||||
},
|
||||
typeOptions: [
|
||||
{text: '全部', value: 1},
|
||||
{text: '报名中', value: 2},
|
||||
{text: '已结束', value: 3},
|
||||
],
|
||||
infoVisible: false,
|
||||
infoRow: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.infoRow = row
|
||||
this.infoVisible = true
|
||||
},
|
||||
onApply(row) {
|
||||
this.$pjaxReplace('/platform/literacy/apply/list/h5?id=' + row.id + '&dataType=mine')
|
||||
},
|
||||
onReady() {
|
||||
this.doSearch()
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,77 @@
|
||||
const leaveInfo = {
|
||||
template:
|
||||
/*language=HTML*/
|
||||
`
|
||||
<van-action-sheet v-model="visible" title="查看详情">
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="请假人姓名">{{ viewData.userName }}</van-cell>
|
||||
<van-cell title="请假人工号">{{ viewData.loginName }}</van-cell>
|
||||
<van-cell title="所属单位">{{ viewData.unitName }}</van-cell>
|
||||
<van-cell title="所属工会">{{ viewData.unionName }}</van-cell>
|
||||
<van-cell title="会议名称">{{ viewData.periodName }}</van-cell>
|
||||
<van-cell title="开始时间">{{ viewData.startTime }}</van-cell>
|
||||
<van-cell title="结束时间">{{ viewData.endTime }}</van-cell>
|
||||
<van-cell title="请假事由" class="direction-column-cell">{{ viewData.leaveReason }}</van-cell>
|
||||
<van-cell title="所属会议">{{ viewData.meetingName }}</van-cell>
|
||||
<van-cell title="会议类型">{{ viewData.typeName }}</van-cell>
|
||||
</van-cell-group>
|
||||
<template v-for="task in doneTasks">
|
||||
<van-cell-group :title="task.displayName" v-if="task.ext.isFirstTaskNode">
|
||||
<van-cell title="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})
|
||||
</van-cell>
|
||||
<van-cell title="申请时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group :title="task.displayName" v-else>
|
||||
<van-cell title="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="办理意见" v-if="!task.ext.isFirstTaskNode" class="direction-column-cell">
|
||||
<div v-html="task.taskFormData.tf_opinion"></div>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</van-action-sheet>
|
||||
`,
|
||||
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
visible:false,
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
row.leaveReason = JSON.parse(row.instanceVariable).f_data.leaveReason || ''
|
||||
this.row = row
|
||||
this.visible = true
|
||||
this.viewData = clone(row)
|
||||
this.getDoneTasks()
|
||||
},
|
||||
onClose(){
|
||||
this.visible = false
|
||||
},
|
||||
getDoneTasks() {
|
||||
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doneTasks = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
const meetingInfo = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<van-action-sheet v-model="visible" title="会议信息">
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="会议名称">{{ viewData.name }}</van-cell>
|
||||
<van-cell title="会议地点">{{ viewData.address }}</van-cell>
|
||||
<van-cell title="会议类型">{{ viewData.typeName }}</van-cell>
|
||||
<van-cell title="会议描述" class="direction-column-cell">
|
||||
<span v-html="viewData.description"></span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="场次信息" v-if="viewData.timePeriods && viewData.timePeriods.length > 0">
|
||||
<table class="table-class">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>场次名称</th>
|
||||
<th>开始时间</th>
|
||||
<th>结束时间</th>
|
||||
<th>是否可以请假</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item,index) in viewData.timePeriods" :key="index">
|
||||
<td>{{ item.periodName }}</td>
|
||||
<td>{{ item.startTime }}</td>
|
||||
<td>{{ item.endTime }}</td>
|
||||
<td>{{ item.canLeave ? '是' : '否' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="会议参与人员" v-if="viewData.users && viewData.users.length > 0">
|
||||
<table class="table-class">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>工号</th>
|
||||
<th>姓名</th>
|
||||
<th>性别</th>
|
||||
<th>所属单位</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item,index) in viewData.users" :key="index">
|
||||
<td>{{ item.loginName }}</td>
|
||||
<td>{{ item.userName }}</td>
|
||||
<td>{{ item.sex }}</td>
|
||||
<td>{{ item.unitName }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</van-cell-group>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
viewData: {},
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
this.$axios.post('/platform/meeting/manage/info', {id: row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
}
|
||||
})
|
||||
this.visible = true
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
/deep/ .table-class{
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
line-height: 1.5rem;
|
||||
font-size: 13px;
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
/deep/ .table-class th {
|
||||
background-color: #f2f2f2;
|
||||
border: 1px solid #dddddd;
|
||||
}
|
||||
/deep/ .table-class tr {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
/deep/ .table-class td {
|
||||
border: 1px solid #dddddd;
|
||||
}
|
||||
`
|
||||
}
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="团长审核" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入名称或地点查询"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.type" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/meeting/delegationApproval/pageData" :page_form.sync="pageForm" ref="tableListRef" title="periodName" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="开始时间">{{row.startTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.endTime}}</table-column>
|
||||
<table-column label="请假人">{{row.userName}}</table-column>
|
||||
<table-column label="请假事由">{{JSON.parse(row.instanceVariable).f_data.leaveReason || ''}}</table-column>
|
||||
<table-column label="所属会议">{{row.meetingName}}</table-column>
|
||||
<table-column label="会议类型">{{row.typeName}}</table-column>
|
||||
<table-column label="当前节点">{{row.curTaskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onApproval(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-reply"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<leave-info ref="infoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
name="tf_opinion"
|
||||
label="审批意见"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
required
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
</van-form>
|
||||
<div style="display: flex; justify-content: space-between; column-gap: 10px; padding: 10px">
|
||||
<van-button type="danger" block @click="handleTaskAction(6)">退回</van-button>
|
||||
<van-button type="danger" block @click="handleTaskAction(20)">不同意</van-button>
|
||||
<van-button type="primary" block @click="handleTaskAction(1)">同意</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</leave-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/leaveInfo.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
'leave-info': leaveInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
year: new Date().getFullYear(),
|
||||
type: null,
|
||||
},
|
||||
typeOptions: [],
|
||||
formData: {},
|
||||
showApprovalForm: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onReady() {
|
||||
const typeList = await this.queryMeetingType()
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: "全部类型",
|
||||
value: null
|
||||
}
|
||||
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
|
||||
if (this.typeOptions.length > 0) {
|
||||
this.pageForm.type = this.typeOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
onApproval(row) {
|
||||
this.showApprovalForm = true
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
this.formData = {
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
},
|
||||
async handleTaskAction(val) {
|
||||
try {
|
||||
await this.$refs.formRef.validate();
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/executeTask", {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.infoRef.onClose()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
},
|
||||
onRevoke(row){
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
async queryMeetingType() {
|
||||
const res = await this.$axios.post('/platform/meeting/type/queryMeetingType')
|
||||
return res.data
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,197 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="我的请假" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入名称或地点查询"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.type" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/meeting/leave/pageData" :page_form.sync="pageForm" ref="tableListRef" title="periodName" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="开始时间">{{row.startTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.endTime}}</table-column>
|
||||
<table-column label="请假人">{{row.userName}}</table-column>
|
||||
<table-column label="请假事由">{{JSON.parse(row.instanceVariable).f_data.leaveReason || ''}}</table-column>
|
||||
<table-column label="所属会议">{{row.meetingName}}</table-column>
|
||||
<table-column label="会议类型">{{row.typeName}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onEdit(row)"
|
||||
v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>编辑</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onRevoke(row)"
|
||||
v-if="row.canRevoke">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onDelete(row)"
|
||||
v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>删除</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<van-dialog v-model="visible" title="请假事由" show-cancel-button
|
||||
:before-close="handleBeforeClose">
|
||||
<van-field
|
||||
style="padding: 20px 16px"
|
||||
v-model="leaveReason"
|
||||
label="请假事由"
|
||||
placeholder="请输入请假事由"
|
||||
required
|
||||
rows="1"
|
||||
autosize
|
||||
type="textarea"
|
||||
></van-field>
|
||||
</van-dialog>
|
||||
|
||||
<leave-info ref="infoRef"></leave-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/leaveInfo.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
'leave-info': leaveInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
type: null
|
||||
},
|
||||
typeOptions: [],
|
||||
visible: false,
|
||||
leaveReason: '',
|
||||
editRow: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onReady() {
|
||||
const typeList = await this.queryMeetingType()
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: "全部类型",
|
||||
value: null
|
||||
}
|
||||
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
|
||||
if (this.typeOptions.length > 0) {
|
||||
this.pageForm.type = this.typeOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
handleBeforeClose(action, done) {
|
||||
if (action === 'confirm') {
|
||||
if(!this.leaveReason) {
|
||||
this.$toast('请输入请假事由')
|
||||
done(false)
|
||||
} else {
|
||||
this.$axios.post("/platform/meeting/mine/submitAgain", {
|
||||
id: this.editRow.id,
|
||||
leaveReason: this.leaveReason,
|
||||
taskId: this.editRow.taskId
|
||||
})
|
||||
.then((res) => {
|
||||
done()
|
||||
this.$toast(res.msg)
|
||||
if (res.code === 0) {
|
||||
this.doSearch()
|
||||
this.reasonVisible = false
|
||||
}
|
||||
}).catch(() => { done() })
|
||||
}
|
||||
} else {
|
||||
done()
|
||||
}
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
onEdit(row) {
|
||||
if(!row.canLeave) {
|
||||
this.$toast.success('该场次不能请假')
|
||||
return
|
||||
}
|
||||
this.editRow = row
|
||||
this.visible = true
|
||||
},
|
||||
onDelete(row) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "确定要删除此申请吗?"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/platform/meeting/leave/delete", { id: row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$toast.fail(res.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
async queryMeetingType() {
|
||||
const res = await this.$axios.post('/platform/meeting/type/queryMeetingType')
|
||||
return res.data
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,194 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
.sign_button .van-button{
|
||||
width: 66px;
|
||||
height: 30px;
|
||||
font-size: 14px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="我的会议" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入名称或地点查询"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.type" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/meeting/mine/pageData" :page_form.sync="pageForm" ref="tableListRef" title="name" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="会议类型">{{row.typeName}}</table-column>
|
||||
<table-column label="会议地点">{{row.address}}</table-column>
|
||||
<table-column label="创建时间">{{row.createTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="leaveRow = row; leaveVisible = true">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>展开</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<van-action-sheet title="会议信息" v-model="leaveVisible" cancel-text="取消" close-on-click-action>
|
||||
<button v-for="(item,index) in leaveRow.timePeriods" type="button" class="van-action-sheet__item">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div>
|
||||
<div class="van-action-sheet__name">{{item.periodName}}</div>
|
||||
<div class="van-action-sheet__subname">
|
||||
{{$moment(item.startTime).format('MM-DD HH:mm') + ' 至 ' + $moment(item.endTime).format('MM-DD HH:mm')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="sign_button">
|
||||
<van-button v-if="item.joinStatus === true" @click.stop="onLeave(item)" size="mini" type="info">请假</van-button>
|
||||
<van-button v-if="item.joinStatus === false" size="mini" type="info" disabled>您已请假</van-button>
|
||||
<van-button v-if="item.signStatus === false" @click.stop="onSign(item)" size="mini" type="info">签到</van-button>
|
||||
<van-button v-if="item.signStatus === true" size="mini" type="info" disabled>您已签到</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</van-action-sheet>
|
||||
|
||||
<van-dialog v-model="reasonVisible" title="请假事由" show-cancel-button
|
||||
:before-close="handleBeforeClose">
|
||||
<van-field
|
||||
style="padding: 20px 16px"
|
||||
v-model="leaveReason"
|
||||
label="请假事由"
|
||||
placeholder="请输入请假事由"
|
||||
required
|
||||
rows="1"
|
||||
autosize
|
||||
type="textarea"
|
||||
></van-field>
|
||||
</van-dialog>
|
||||
|
||||
<meeting-info ref="infoRef"></meeting-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/meetingInfo.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
'meeting-info': meetingInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
type: null
|
||||
},
|
||||
typeOptions: [],
|
||||
|
||||
leaveRow: {},
|
||||
leaveVisible: false,
|
||||
|
||||
reasonVisible: false,
|
||||
leaveReason: '',
|
||||
periodRow: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onReady() {
|
||||
const typeList = await this.queryMeetingType()
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: "全部类型",
|
||||
value: null
|
||||
}
|
||||
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
|
||||
if (this.typeOptions.length > 0) {
|
||||
this.pageForm.siteType = this.typeOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
handleBeforeClose(action, done) {
|
||||
if (action === 'confirm') {
|
||||
if(!this.leaveReason) {
|
||||
this.$toast('请输入请假事由')
|
||||
done(false)
|
||||
} else {
|
||||
this.$axios.post("/platform/meeting/mine/leave", {
|
||||
periodId: this.periodRow.id,
|
||||
leaveReason: this.leaveReason,
|
||||
})
|
||||
.then((res) => {
|
||||
done()
|
||||
this.$toast(res.msg)
|
||||
if (res.code === 0) {
|
||||
this.doSearch()
|
||||
this.reasonVisible = false
|
||||
}
|
||||
}).catch(() => { done() })
|
||||
}
|
||||
} else {
|
||||
done()
|
||||
}
|
||||
},
|
||||
onLeave(row) {
|
||||
if(!row.canLeave) {
|
||||
this.$toast('该场次不能请假')
|
||||
return
|
||||
}
|
||||
this.periodRow = row
|
||||
this.reasonVisible = true
|
||||
},
|
||||
onSign(row) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要签到吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/meeting/mine/sign", { periodId: row.id })
|
||||
.then((res) => {
|
||||
this.$toast(res.msg)
|
||||
if (res.code === 0) {
|
||||
this.doSearch()
|
||||
this.leaveVisible = false
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
async queryMeetingType() {
|
||||
const res = await this.$axios.post('/platform/meeting/type/queryMeetingType')
|
||||
return res.data
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="校工会审核" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入名称或地点查询"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.type" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/meeting/schoolUnionApproval/pageData" :page_form.sync="pageForm" ref="tableListRef" title="periodName" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="开始时间">{{row.startTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.endTime}}</table-column>
|
||||
<table-column label="请假人">{{row.userName}}</table-column>
|
||||
<table-column label="请假事由">{{JSON.parse(row.instanceVariable).f_data.leaveReason || ''}}</table-column>
|
||||
<table-column label="所属会议">{{row.meetingName}}</table-column>
|
||||
<table-column label="会议类型">{{row.typeName}}</table-column>
|
||||
<table-column label="当前节点">{{row.curTaskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onApproval(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-reply"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<leave-info ref="infoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
name="tf_opinion"
|
||||
label="审批意见"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
required
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
</van-form>
|
||||
<div style="display: flex; justify-content: space-between; column-gap: 10px; padding: 10px">
|
||||
<van-button type="danger" block @click="handleTaskAction(6)">退回</van-button>
|
||||
<van-button type="danger" block @click="handleTaskAction(20)">不同意</van-button>
|
||||
<van-button type="primary" block @click="handleTaskAction(1)">同意</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</leave-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/leaveInfo.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
'leave-info': leaveInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
year: new Date().getFullYear(),
|
||||
type: null,
|
||||
},
|
||||
typeOptions: [],
|
||||
formData: {},
|
||||
showApprovalForm: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onReady() {
|
||||
const typeList = await this.queryMeetingType()
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: "全部类型",
|
||||
value: null
|
||||
}
|
||||
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
|
||||
if (this.typeOptions.length > 0) {
|
||||
this.pageForm.type = this.typeOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
onApproval(row) {
|
||||
this.showApprovalForm = true
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
this.formData = {
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
},
|
||||
async handleTaskAction(val) {
|
||||
try {
|
||||
await this.$refs.formRef.validate();
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/executeTask", {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.infoRef.onClose()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
},
|
||||
onRevoke(row){
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
async queryMeetingType() {
|
||||
const res = await this.$axios.post('/platform/meeting/type/queryMeetingType')
|
||||
return res.data
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,464 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<div id="app">
|
||||
<!-- 导航栏 -->
|
||||
<van-nav-bar title="报销申请" left-text="返回" left-arrow
|
||||
@click-left="historyBack" fixed></van-nav-bar>
|
||||
|
||||
<!-- 表单容器 -->
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-cell-group title="活动类型">
|
||||
<van-field
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.outlayManageSourceName"
|
||||
label="活动类型"
|
||||
placeholder="请选择活动类型"
|
||||
required
|
||||
is-link
|
||||
readonly
|
||||
@click="showOutlayManageSourcePopup = true"
|
||||
></van-field>
|
||||
<van-popup v-model="showOutlayManageSourcePopup" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="budgetTypeOption.map(i => i.name)"
|
||||
@confirm="onOutlayManageSourceConfirm"
|
||||
@cancel="showOutlayManageSourcePopup = false"
|
||||
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="申请人信息">
|
||||
<van-field label="申请人姓名" :rules="[{ required: true }]" v-model="formData.userName" readonly
|
||||
required></van-field>
|
||||
<van-field label="申请人工号" :rules="[{ required: true }]" v-model="formData.loginName" readonly
|
||||
required></van-field>
|
||||
<van-field label="手机号码" name="mobile" :rules="[{ required: true }]" v-model="formData.mobile"
|
||||
required
|
||||
placeholder="请输入手机号码"
|
||||
maxlength="11"
|
||||
type="tel"></van-field>
|
||||
|
||||
<van-field
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.clubName"
|
||||
label="所属协会"
|
||||
placeholder="请选择所属协会"
|
||||
required
|
||||
is-link
|
||||
readonly
|
||||
@click="showClubNamePopup = true"
|
||||
v-if="['ACTIVITY_BUDGET_TYPE_THREE'].includes(formData.outlayManageSource)"
|
||||
></van-field>
|
||||
<van-popup v-model="showClubNamePopup" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="clubOption.map(i => i.clubName)"
|
||||
@confirm="onClubNameConfirm"
|
||||
@cancel="showClubNamePopup = false"
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-field label="经费余额" :rules="[{ required: true }]" v-model="budgetMoney" readonly
|
||||
required></van-field>
|
||||
|
||||
<van-field label="活动事项" name="activityMatter"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.activityMatter"
|
||||
required
|
||||
maxlength="50"
|
||||
placeholder="请输入活动事项"
|
||||
v-if="['ACTIVITY_BUDGET_TYPE_THREE'].includes(formData.outlayManageSource)"></van-field>
|
||||
|
||||
<van-field
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.budgetName"
|
||||
label="活动事项"
|
||||
placeholder="请选择活动事项"
|
||||
required
|
||||
is-link
|
||||
readonly
|
||||
@click="showBudgetNamePopup = true"
|
||||
v-if="!['ACTIVITY_BUDGET_TYPE_THREE'].includes(formData.outlayManageSource)"
|
||||
></van-field>
|
||||
<van-popup v-model="showBudgetNamePopup" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="activityList.map(i => i.activityMatter)"
|
||||
@confirm="onBudgetNameConfirm"
|
||||
@cancel="showBudgetNamePopup = false"
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-field label="活动人数" name="activityNumber"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.activityNumber"
|
||||
required
|
||||
maxlength="4"
|
||||
placeholder="请输入活动人数"
|
||||
type="digit"></van-field>
|
||||
|
||||
<van-field label="金额" name="money"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.money"
|
||||
required
|
||||
:placeholder="moneyPlaceholder"
|
||||
type="number"></van-field>
|
||||
|
||||
<van-field label="活动时间"
|
||||
name="activityTime"
|
||||
:rules="[{ required: true }]"
|
||||
:value="formData.activityTime"
|
||||
readonly
|
||||
is-link
|
||||
placeholder="请填写活动时间"
|
||||
required
|
||||
@click="showActivityTimePopup = true"></van-field>
|
||||
<van-popup v-model="showActivityTimePopup" position="bottom">
|
||||
<van-datetime-picker
|
||||
v-model="formData.activityTimeDate"
|
||||
type="date"
|
||||
title="选择活动时间"
|
||||
:max-date="activityTimeMaxDate"
|
||||
@confirm="onActivityTimeConfirm"
|
||||
@cancel="showActivityTimePopup=false"
|
||||
></van-datetime-picker>
|
||||
</van-popup>
|
||||
|
||||
<van-field label="支付内容"
|
||||
:rules="[{ required: true }]"
|
||||
v-model="formData.paymentContent"
|
||||
required
|
||||
type="textarea"
|
||||
name="paymentContent"
|
||||
rows="4"
|
||||
autosize
|
||||
maxlength="500"
|
||||
class="more-text"
|
||||
placeholder="请填写支付内容"></van-field>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="附件">
|
||||
<van-field class="more-text" name="files"
|
||||
:rules="[{ required: true,message:'请上传附件' }]"
|
||||
label="" required>
|
||||
<template #input>
|
||||
<h5-file-upload
|
||||
slot="input"
|
||||
:value.sync="formData.files"
|
||||
:upload_number="10"
|
||||
upload_mode="file"
|
||||
upload_result_category="array"
|
||||
upload_result_type="url"
|
||||
complete_result
|
||||
></h5-file-upload>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group title="电子签名">
|
||||
<van-field class="more-text"
|
||||
name="userSign"
|
||||
label=""
|
||||
required>
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button native-type="button" plain type="info" @click="onSave">保存</van-button>
|
||||
<van-button type="primary" @click="onSubmit" v-if="!taskId">提交</van-button>
|
||||
<van-button type="primary" @click="onFinishTask" v-else>提交</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ACTIVITY_BUDGET_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
bizId: GetQueryString("bizId"),
|
||||
taskId: GetQueryString("taskId"),
|
||||
formData: {},
|
||||
|
||||
|
||||
moneyPlaceholder: "请输入金额",
|
||||
budgetMoney: 0,
|
||||
|
||||
budgetTypeOption: [],
|
||||
showOutlayManageSourcePopup: false,
|
||||
|
||||
clubOption: [],
|
||||
showClubNamePopup: false,
|
||||
|
||||
activityList: [],
|
||||
showBudgetNamePopup: false,
|
||||
|
||||
showActivityTimePopup: false,
|
||||
activityTimeMaxDate: new Date(),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSave() {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定保存吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/outlay/reimburse/apply/save', {
|
||||
data: JSON.stringify(this.formData)
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
pjaxReplace("/platform/outlay/reimburse/applyList/h5")
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onSubmit() {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/outlay/reimburse/apply/submit', {
|
||||
data: JSON.stringify(this.formData),
|
||||
taskId: GetQueryString("taskId")
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
pjaxReplace("/platform/outlay/reimburse/applyList/h5")
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onFinishTask() {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/outlay/reimburse/apply/submitAgain', {
|
||||
data: JSON.stringify(this.formData),
|
||||
taskId: GetQueryString("taskId")
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
pjaxReplace("/platform/outlay/reimburse/applyList/h5")
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onActivityTimeConfirm(value, index) {
|
||||
this.formData.activityTimeDate = value
|
||||
this.formData.activityTime = this.$moment(value).format("YYYY-MM-DD")
|
||||
this.showActivityTimePopup = false
|
||||
},
|
||||
async budgetIdChange(val) {
|
||||
if (val) {
|
||||
if (["ACTIVITY_BUDGET_TYPE_TWO", "ACTIVITY_BUDGET_TYPE_ONE"].includes(this.formData.outlayManageSource)) {
|
||||
//如果是分工会和校工会
|
||||
const data = this.activityList.find(a => a.id === val)
|
||||
if (this.formData.outlayManageSource === "ACTIVITY_BUDGET_TYPE_TWO") {
|
||||
//如果是分工会
|
||||
const money = await this.getBxMoneyByBudgetId(val)
|
||||
if (data.isSchoolBudget) {
|
||||
//如果这一条分工会活动预算金额是属于校工会的
|
||||
this.moneyPlaceholder = "预算金额" + data.totalBudgetMoney + "元,已报销金额:" + money
|
||||
} else {
|
||||
//如果这一条分工会活动活动,并且预算金额也是自己分工会的
|
||||
if (data.isRepeatReimburse) {
|
||||
//如果这一条活动预算可以重复报销
|
||||
this.moneyPlaceholder = "预算金额:" + data.totalBudgetMoney + "元,已报销金额:" + money + ",不能超过20%"
|
||||
} else {
|
||||
//如果如果不能重复报销暂无判断
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//如果是校工会
|
||||
if (data.twoLevelBudgetList.length > 0) {
|
||||
//如果大于0代表肯定有分工会使用校工会的预算,这里要减去分工会的预算
|
||||
this.moneyPlaceholder = "预算金额:" + data.totalBudgetMoney + "元,已报销金额:" + data.twoLevelTotalBudgetMoney
|
||||
} else {
|
||||
if (data.isRepeatReimburse) {
|
||||
const money = await this.getBxMoneyByBudgetId(val)
|
||||
this.moneyPlaceholder = "预算金额:" + data.totalBudgetMoney + "元,已报销金额:" + money + ",不能超过20%"
|
||||
} else {
|
||||
//如果如果不能重复报销暂无判断
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
this.totalBudgetMoney = data.totalBudgetMoney
|
||||
this.$set(this.formData, 'activityMatter', data.activityMatter)
|
||||
} else {
|
||||
this.moneyPlaceholder = "预算金额" + this.budgetMoney + "元"
|
||||
this.totalBudgetMoney = this.budgetMoney
|
||||
this.$set(this.formData, 'activityMatter', val)
|
||||
}
|
||||
} else {
|
||||
this.moneyPlaceholder = "请输入金额"
|
||||
this.totalBudgetMoney = 0
|
||||
this.$set(this.formData, 'activityMatter', null)
|
||||
}
|
||||
},
|
||||
async getBxMoneyByBudgetId(budgetId) {
|
||||
const resp = await this.$axios.post("/platform/outlay/reimburse/apply/getBxMoneyByBudgetId", {
|
||||
budgetId
|
||||
})
|
||||
if (resp.code === 0) {
|
||||
return resp.data
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
async onBudgetNameConfirm(value, index) {
|
||||
this.formData.budgetId = this.activityList[index].id;
|
||||
this.formData.budgetName = value;
|
||||
await this.budgetIdChange(this.formData.budgetId)
|
||||
this.showBudgetNamePopup = false
|
||||
},
|
||||
async onClubNameConfirm(value, index) {
|
||||
this.formData.clubId = this.clubOption[index].id;
|
||||
this.formData.clubName = value;
|
||||
await this.getBudgetMoneyOrActivity();
|
||||
this.showClubNamePopup = false
|
||||
},
|
||||
async onOutlayManageSourceConfirm(value, index) {
|
||||
this.formData.outlayManageSource = this.budgetTypeOption[index].code;
|
||||
this.formData.outlayManageSourceName = value;
|
||||
if (!this.formData.outlayManageSource) {
|
||||
this.budgetMoney = 0
|
||||
return
|
||||
}
|
||||
this.$set(this.formData, "budgetId", null)
|
||||
this.$set(this.formData, "clubId", null)
|
||||
this.$set(this.formData, "clubName", null)
|
||||
await this.getBudgetMoneyOrActivity()
|
||||
if (this.formData.outlayManageSource === "ACTIVITY_BUDGET_TYPE_TWO") {
|
||||
this.$set(this.formData, "unionId", this.$store.state.user.union.id)
|
||||
}
|
||||
this.showOutlayManageSourcePopup = false;
|
||||
},
|
||||
async getBudgetMoneyOrActivity() {
|
||||
const resp = await this.$axios.post("/platform/outlay/reimburse/apply/getBudgetMoneyOrActivity", {
|
||||
outlayManageSource: this.formData.outlayManageSource,
|
||||
clubId: this.formData.clubId,
|
||||
unionId: this.formData.unionId,
|
||||
id: this.formData.id
|
||||
})
|
||||
if (resp.code === 0) {
|
||||
this.budgetMoney = resp.data.budgetMoney
|
||||
this.activityList = resp.data.activityList
|
||||
}
|
||||
},
|
||||
async findOne(id) {
|
||||
const resp = await $.get('/platform/outlay/reimburse/apply/findOne', {id})
|
||||
if (resp.code === 0) {
|
||||
return resp.data
|
||||
}
|
||||
},
|
||||
async init() {
|
||||
this.clubOption = await this.$businessTool.listCLubByRole()
|
||||
this.budgetTypeOption = await this.$businessTool.getDictOptions("ACTIVITY_BUDGET_TYPE")
|
||||
const budgetTypeOption = []
|
||||
if (this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])) {
|
||||
|
||||
} else {
|
||||
if (this.$auth.hasRoleOr(["SCHOOL_OUTLAY_ADMIN", "SCHOOL_UNION_ADMIN"])) {
|
||||
this.budgetTypeOption.map(v => {
|
||||
if (["ACTIVITY_BUDGET_TYPE_ONE"].includes(v.code)) {
|
||||
budgetTypeOption.push(v)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.$auth.hasRoleOr(["BRANCH_UNION_CHAIRMAN", "BRANCH_UNION_ADMIN"])) {
|
||||
this.budgetTypeOption.map(v => {
|
||||
if (["ACTIVITY_BUDGET_TYPE_TWO"].includes(v.code)) {
|
||||
budgetTypeOption.push(v)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.$auth.hasRoleOr(["CLUB_MANAGER", "CLUB_PRESIDENT"])) {
|
||||
this.budgetTypeOption.map(v => {
|
||||
if (["ACTIVITY_BUDGET_TYPE_THREE"].includes(v.code)) {
|
||||
budgetTypeOption.push(v)
|
||||
}
|
||||
})
|
||||
}
|
||||
this.budgetTypeOption = budgetTypeOption
|
||||
}
|
||||
if (this.bizId) {
|
||||
this.findOne(this.bizId).then(async data => {
|
||||
this.formData = data
|
||||
await this.getBudgetMoneyOrActivity()
|
||||
if (data.budgetId) {
|
||||
await this.budgetIdChange(data.budgetId)
|
||||
}
|
||||
//活动时间回显
|
||||
if (data.activityTime) {
|
||||
this.$set(this.formData, "activityTimeDate", new Date(data.activityTime))
|
||||
}
|
||||
//活动类型
|
||||
const outlayManageSource = this.dict.type.ACTIVITY_BUDGET_TYPE.find(v => v.code === data.outlayManageSource)
|
||||
if (outlayManageSource) {
|
||||
this.$set(this.formData, "outlayManageSourceName", outlayManageSource.name)
|
||||
}
|
||||
if (data.budgetId) {
|
||||
const activity= this.activityList.find(v => v.id === data.budgetId)
|
||||
this.$set(this.formData, "budgetName", activity.activityMatter)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const {id, username, loginname, mobile, union, unit} = this.$store.state.user
|
||||
this.formData = {
|
||||
userId: id,
|
||||
userName: username,
|
||||
loginName: loginname,
|
||||
unitName: unit.name,
|
||||
unitId: unit.id,
|
||||
unionName: union.name,
|
||||
unionId: union.id,
|
||||
mobile: mobile,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<!-- 导航栏 -->
|
||||
<van-nav-bar title="我的申请" left-text="返回" left-arrow placeholder
|
||||
@click-left="historyBack" fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
|
||||
<table-list api="/platform/outlay/reimburse/applyList/pageData" :page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
@ready="doSearch" title="taskName">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人工号">{{row.loginName}}</table-column>
|
||||
<table-column label="姓名">{{row.userName}}</table-column>
|
||||
<table-column label="活动类型">
|
||||
<dict-tag :options="dict.type.ACTIVITY_BUDGET_TYPE"
|
||||
:value="row.outlayManageSource"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="活动事项">{{row.activityMatter}}</table-column>
|
||||
<table-column label="申报单位">
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_ONE'].includes(row.outlayManageSource)">校工会</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_TWO'].includes(row.outlayManageSource)">{{row.unionName}}</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_THREE','ACTIVITY_BUDGET_TYPE_FOUR'].includes(row.outlayManageSource)">{{row.clubName}}</span>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
<table-column label="申请时间">{{row.applyTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onEdit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>编辑</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onDelete(row.id)"
|
||||
v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>删除</span>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<h5-outlay-reimburse-info ref="h5OutlayReimburseInfo"></h5-outlay-reimburse-info>
|
||||
</div>
|
||||
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ACTIVITY_BUDGET_TYPE"],
|
||||
components: {
|
||||
"h5-outlay-reimburse-info": H5_OUTLAY_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
onEdit(row) {
|
||||
pjaxReplace('/platform/outlay/reimburse/apply/h5?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
|
||||
},
|
||||
onDelete(id) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要删除吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/outlay/reimburse/applyList/doDelete", {id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$toast.fail(res.msg)
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.startTaskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$toast.fail(res.msg)
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
doSearch() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
},
|
||||
|
||||
},
|
||||
created() {
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="协会审核" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名搜索"
|
||||
v-model="pageForm.searchKeyword"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/outlay/reimburse/clubAudit/pageData" :page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
title="curTaskName" @ready="doSearch">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人工号">{{row.loginName}}</table-column>
|
||||
<table-column label="姓名">{{row.userName}}</table-column>
|
||||
<table-column label="活动类型">
|
||||
<dict-tag :options="dict.type.ACTIVITY_BUDGET_TYPE"
|
||||
:value="row.outlayManageSource"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="活动事项">{{row.activityMatter}}</table-column>
|
||||
<table-column label="申报单位">
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_ONE'].includes(row.outlayManageSource)">校工会</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_TWO'].includes(row.outlayManageSource)">{{row.unionName}}</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_THREE','ACTIVITY_BUDGET_TYPE_FOUR'].includes(row.outlayManageSource)">{{row.clubName}}</span>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
<table-column label="申请时间">{{row.applyTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<h5-outlay-reimburse-info ref="h5OutlayReimburseInfo">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-field label="审批意见"
|
||||
:rules="[{ required: true,message:'请填审批意见' }]"
|
||||
v-model="formData.tf_opinion"
|
||||
required
|
||||
type="textarea"
|
||||
name="tf_opinion"
|
||||
rows="4"
|
||||
autosize
|
||||
placeholder="请填审批意见"></van-field>
|
||||
|
||||
<van-field name="tf_userSign" label="签字">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button @click="handleTaskAction(6)">退回到发起人</van-button>
|
||||
<van-button type="danger" @click="handleTaskAction(2)">拒绝申请</van-button>
|
||||
<van-button type="primary" @click="handleTaskAction(1)">同意申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</h5-outlay-reimburse-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ACTIVITY_BUDGET_TYPE"],
|
||||
components: {
|
||||
"h5-outlay-reimburse-info": H5_OUTLAY_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
searchName: "info.userName",
|
||||
},
|
||||
formData: {},
|
||||
infoShow: false,
|
||||
showApprovalForm: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/outlay/reimburse/clubAudit/submit', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.$refs.h5OutlayReimburseInfo.onClose()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
tf_opinion: null,
|
||||
tf_userSign: null,
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.infoShow = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="协会分管主席审核" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名搜索"
|
||||
v-model="pageForm.searchKeyword"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/outlay/reimburse/clubZxAudit/pageData" :page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
title="curTaskName" @ready="doSearch">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人工号">{{row.loginName}}</table-column>
|
||||
<table-column label="姓名">{{row.userName}}</table-column>
|
||||
<table-column label="活动类型">
|
||||
<dict-tag :options="dict.type.ACTIVITY_BUDGET_TYPE"
|
||||
:value="row.outlayManageSource"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="活动事项">{{row.activityMatter}}</table-column>
|
||||
<table-column label="申报单位">
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_ONE'].includes(row.outlayManageSource)">校工会</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_TWO'].includes(row.outlayManageSource)">{{row.unionName}}</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_THREE','ACTIVITY_BUDGET_TYPE_FOUR'].includes(row.outlayManageSource)">{{row.clubName}}</span>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
<table-column label="申请时间">{{row.applyTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<h5-outlay-reimburse-info ref="h5OutlayReimburseInfo">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-field label="审批意见"
|
||||
:rules="[{ required: true,message:'请填审批意见' }]"
|
||||
v-model="formData.tf_opinion"
|
||||
required
|
||||
type="textarea"
|
||||
name="tf_opinion"
|
||||
rows="4"
|
||||
autosize
|
||||
placeholder="请填审批意见"></van-field>
|
||||
|
||||
<van-field name="tf_userSign" label="签字">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button @click="handleTaskAction(6)">退回到发起人</van-button>
|
||||
<van-button type="danger" @click="handleTaskAction(2)">拒绝申请</van-button>
|
||||
<van-button type="primary" @click="handleTaskAction(1)">同意申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</h5-outlay-reimburse-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ACTIVITY_BUDGET_TYPE"],
|
||||
components: {
|
||||
"h5-outlay-reimburse-info": H5_OUTLAY_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
searchName: "info.userName",
|
||||
},
|
||||
formData: {},
|
||||
infoShow: false,
|
||||
showApprovalForm: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/flow/common/executeTask', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.$refs.h5OutlayReimburseInfo.onClose()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
tf_opinion: null,
|
||||
tf_userSign: null,
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.infoShow = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,146 @@
|
||||
const H5_OUTLAY_REIMBURSE_INFO = {
|
||||
template: /*language=HTML*/ `
|
||||
<van-action-sheet v-model="visible" title="查看详情">
|
||||
<div>
|
||||
<div class="process-title">申请信息</div>
|
||||
<van-cell-group>
|
||||
<van-cell title="申请人">
|
||||
{{ viewData.userName }}
|
||||
</van-cell>
|
||||
<van-cell title="工号">
|
||||
{{ viewData.loginName }}
|
||||
</van-cell>
|
||||
<van-cell title="联系方式">
|
||||
{{ viewData.mobile }}
|
||||
</van-cell>
|
||||
<van-cell title="预算类型">
|
||||
<dict-tag :options="dict.type.ACTIVITY_BUDGET_TYPE"
|
||||
:value="viewData.outlayManageSource"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="预算类型">
|
||||
{{viewData.activityMatter}}
|
||||
</van-cell>
|
||||
<van-cell title="申请金额">
|
||||
{{viewData.money}}
|
||||
</van-cell>
|
||||
<van-cell title="活动时间">
|
||||
{{viewData.activityTime}}
|
||||
</van-cell>
|
||||
<van-cell title="活动人数">
|
||||
{{viewData.activityNumber}}
|
||||
</van-cell>
|
||||
<van-cell title="支付内容">
|
||||
<div style="white-space: pre-line">{{viewData.paymentContent}}</div>
|
||||
</van-cell>
|
||||
<van-cell title="附件">
|
||||
<template #label>
|
||||
<template v-for="(item,index) in viewData.files">
|
||||
<van-image :src="item.url"
|
||||
v-if="item.url"
|
||||
class="signature-image"
|
||||
@click="previewOptionImg(viewData.files,index)"></van-image>
|
||||
</template>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="签字" >
|
||||
<van-image :src="viewData.userSign"
|
||||
class="signature-image"></van-image>
|
||||
</van-cell>
|
||||
|
||||
</van-cell-group>
|
||||
|
||||
<template v-for="(task,index) in doneTasks">
|
||||
<div class="process-title">
|
||||
{{ task.displayName }}
|
||||
</div>
|
||||
<van-cell-group v-if="task.ext.isFirstTaskNode">
|
||||
<van-cell title="申请用户">
|
||||
{{ task.ext.initiatorName}}({{task.ext.initiatorAccount}})
|
||||
</van-cell>
|
||||
<van-cell title="申请时间">
|
||||
{{ task.finishTime}}
|
||||
</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group v-else>
|
||||
<van-cell title="办理用户">
|
||||
{{ task.taskFormData.userName}}({{task.taskFormData.loginName}})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">
|
||||
{{ task.finishTime}}
|
||||
</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="办理意见" v-if="!task.ext.isFirstTaskNode">
|
||||
<template #label>
|
||||
{{
|
||||
task.taskFormData.opinion
|
||||
}}
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="签字" v-if="!task.ext.isFirstTaskNode">
|
||||
<van-image :src="task.ext.tf_userSign"
|
||||
v-if="task.ext.tf_userSign"
|
||||
class="signature-image"></van-image>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
|
||||
<slot></slot>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
`,
|
||||
dicts: ["PROCESS_TASK_SUBMIT_TYPE","ACTIVITY_BUDGET_TYPE","ACTIVITY_BUDGET_DETAILS_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//预览图片
|
||||
previewOptionImg(files, index) {
|
||||
const urls = files.map(item => item.url)
|
||||
vant.ImagePreview({images: urls, startPosition: index})
|
||||
},
|
||||
// 打开
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
|
||||
|
||||
|
||||
this.getInfo()
|
||||
this.getDoneTasks()
|
||||
},
|
||||
|
||||
// 关闭
|
||||
onClose() {
|
||||
this.visible = false
|
||||
},
|
||||
|
||||
// 获取申请信息
|
||||
getInfo() {
|
||||
this.$axios.post('/platform/outlay/reimburse/apply/findOne', {id: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取已办任务审批记录
|
||||
getDoneTasks() {
|
||||
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doneTasks = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="校工会出纳审核" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名搜索"
|
||||
v-model="pageForm.searchKeyword"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/outlay/reimburse/schoolCnAudit/pageData" :page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
title="curTaskName" @ready="doSearch">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人工号">{{row.loginName}}</table-column>
|
||||
<table-column label="姓名">{{row.userName}}</table-column>
|
||||
<table-column label="活动类型">
|
||||
<dict-tag :options="dict.type.ACTIVITY_BUDGET_TYPE"
|
||||
:value="row.outlayManageSource"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="活动事项">{{row.activityMatter}}</table-column>
|
||||
<table-column label="申报单位">
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_ONE'].includes(row.outlayManageSource)">校工会</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_TWO'].includes(row.outlayManageSource)">{{row.unionName}}</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_THREE','ACTIVITY_BUDGET_TYPE_FOUR'].includes(row.outlayManageSource)">{{row.clubName}}</span>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
<table-column label="申请时间">{{row.applyTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<h5-outlay-reimburse-info ref="h5OutlayReimburseInfo">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-field label="审批意见"
|
||||
:rules="[{ required: true,message:'请填审批意见' }]"
|
||||
v-model="formData.tf_opinion"
|
||||
required
|
||||
type="textarea"
|
||||
name="tf_opinion"
|
||||
rows="4"
|
||||
autosize
|
||||
placeholder="请填审批意见"></van-field>
|
||||
|
||||
<van-field name="tf_userSign" label="签字">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button @click="handleTaskAction(6)">退回到发起人</van-button>
|
||||
<van-button type="danger" @click="handleTaskAction(2)">拒绝申请</van-button>
|
||||
<van-button type="primary" @click="handleTaskAction(1)">同意申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</h5-outlay-reimburse-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ACTIVITY_BUDGET_TYPE"],
|
||||
components: {
|
||||
"h5-outlay-reimburse-info": H5_OUTLAY_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
searchName: "info.userName",
|
||||
},
|
||||
formData: {},
|
||||
infoShow: false,
|
||||
showApprovalForm: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/flow/common/executeTask', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.$refs.h5OutlayReimburseInfo.onClose()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
tf_opinion: null,
|
||||
tf_userSign: null,
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.infoShow = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="校工会会计审核" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名搜索"
|
||||
v-model="pageForm.searchKeyword"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/outlay/reimburse/schoolKjAudit/pageData"
|
||||
:page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
title="curTaskName" @ready="doSearch">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人工号">{{row.loginName}}</table-column>
|
||||
<table-column label="姓名">{{row.userName}}</table-column>
|
||||
<table-column label="活动类型">
|
||||
<dict-tag :options="dict.type.ACTIVITY_BUDGET_TYPE"
|
||||
:value="row.outlayManageSource"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="活动事项">{{row.activityMatter}}</table-column>
|
||||
<table-column label="申报单位">
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_ONE'].includes(row.outlayManageSource)">校工会</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_TWO'].includes(row.outlayManageSource)">{{row.unionName}}</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_THREE','ACTIVITY_BUDGET_TYPE_FOUR'].includes(row.outlayManageSource)">{{row.clubName}}</span>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
<table-column label="申请时间">{{row.applyTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<h5-outlay-reimburse-info ref="h5OutlayReimburseInfo">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-field label="审批意见"
|
||||
:rules="[{ required: true,message:'请填审批意见' }]"
|
||||
v-model="formData.tf_opinion"
|
||||
required
|
||||
type="textarea"
|
||||
name="tf_opinion"
|
||||
rows="4"
|
||||
autosize
|
||||
placeholder="请填审批意见"></van-field>
|
||||
|
||||
<van-field name="tf_userSign" label="签字">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
<van-popup v-model="showDetailsTypePopup" position="bottom">
|
||||
<van-picker
|
||||
show-toolbar
|
||||
:columns="detailsTypeOption.map(i => i.name)"
|
||||
@confirm="onDetailsTypeConfirm"
|
||||
@cancel="showDetailsTypePopup = false"
|
||||
|
||||
></van-picker>
|
||||
</van-popup>
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button @click="handleTaskAction(6)">退回到发起人</van-button>
|
||||
<van-button type="danger" @click="handleTaskAction(2)">拒绝申请</van-button>
|
||||
<van-button type="primary" @click="openHandleTaskAction">同意申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</h5-outlay-reimburse-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ACTIVITY_BUDGET_TYPE"],
|
||||
components: {
|
||||
"h5-outlay-reimburse-info": H5_OUTLAY_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
searchName: "info.userName",
|
||||
},
|
||||
formData: {},
|
||||
detailsTypeOption: [],
|
||||
showApprovalForm: false,
|
||||
|
||||
showDetailsTypePopup: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async openHandleTaskAction() {
|
||||
await this.$refs.formRef.validate();
|
||||
this.detailsTypeOption = await this.$businessTool.getDictOptions("ACTIVITY_BUDGET_DETAILS_TYPE")
|
||||
this.showDetailsTypePopup = true
|
||||
},
|
||||
onDetailsTypeConfirm(value, index) {
|
||||
this.formData.detailsType = this.detailsTypeOption[index].value
|
||||
this.handleTaskAction(1)
|
||||
},
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/flow/common/executeTask', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.$refs.h5OutlayReimburseInfo.onClose()
|
||||
this.showDetailsTypePopup = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
tf_opinion: null,
|
||||
tf_userSign: null,
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.infoShow = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="校工会主席终审" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名搜索"
|
||||
v-model="pageForm.searchKeyword"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/outlay/reimburse/schoolZxAudit/pageData" :page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
title="curTaskName" @ready="doSearch">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人工号">{{row.loginName}}</table-column>
|
||||
<table-column label="姓名">{{row.userName}}</table-column>
|
||||
<table-column label="活动类型">
|
||||
<dict-tag :options="dict.type.ACTIVITY_BUDGET_TYPE"
|
||||
:value="row.outlayManageSource"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="活动事项">{{row.activityMatter}}</table-column>
|
||||
<table-column label="申报单位">
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_ONE'].includes(row.outlayManageSource)">校工会</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_TWO'].includes(row.outlayManageSource)">{{row.unionName}}</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_THREE','ACTIVITY_BUDGET_TYPE_FOUR'].includes(row.outlayManageSource)">{{row.clubName}}</span>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
<table-column label="申请时间">{{row.applyTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<h5-outlay-reimburse-info ref="h5OutlayReimburseInfo">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-field label="审批意见"
|
||||
:rules="[{ required: true,message:'请填审批意见' }]"
|
||||
v-model="formData.tf_opinion"
|
||||
required
|
||||
type="textarea"
|
||||
name="tf_opinion"
|
||||
rows="4"
|
||||
autosize
|
||||
placeholder="请填审批意见"></van-field>
|
||||
|
||||
<van-field name="tf_userSign" label="签字">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button @click="handleTaskAction(6)">退回到发起人</van-button>
|
||||
<van-button type="danger" @click="handleTaskAction(2)">拒绝申请</van-button>
|
||||
<van-button type="primary" @click="handleTaskAction(1)">同意申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</h5-outlay-reimburse-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ACTIVITY_BUDGET_TYPE"],
|
||||
components: {
|
||||
"h5-outlay-reimburse-info": H5_OUTLAY_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
searchName: "info.userName",
|
||||
},
|
||||
formData: {},
|
||||
infoShow: false,
|
||||
showApprovalForm: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/flow/common/executeTask', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.$refs.h5OutlayReimburseInfo.onClose()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
tf_opinion: null,
|
||||
tf_userSign: null,
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.infoShow = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="分工会审核" placeholder
|
||||
fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名搜索"
|
||||
v-model="pageForm.searchKeyword"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/outlay/reimburse/unionAudit/pageData" :page_form.sync="pageForm"
|
||||
ref="tableListRef"
|
||||
title="curTaskName" @ready="doSearch">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人工号">{{row.loginName}}</table-column>
|
||||
<table-column label="姓名">{{row.userName}}</table-column>
|
||||
<table-column label="活动类型">
|
||||
<dict-tag :options="dict.type.ACTIVITY_BUDGET_TYPE"
|
||||
:value="row.outlayManageSource"></dict-tag>
|
||||
</table-column>
|
||||
<table-column label="活动事项">{{row.activityMatter}}</table-column>
|
||||
<table-column label="申报单位">
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_ONE'].includes(row.outlayManageSource)">校工会</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_TWO'].includes(row.outlayManageSource)">{{row.unionName}}</span>
|
||||
<span v-if="['ACTIVITY_BUDGET_TYPE_THREE','ACTIVITY_BUDGET_TYPE_FOUR'].includes(row.outlayManageSource)">{{row.clubName}}</span>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
<table-column label="申请时间">{{row.applyTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<h5-outlay-reimburse-info ref="h5OutlayReimburseInfo">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-field label="审批意见"
|
||||
:rules="[{ required: true,message:'请填审批意见' }]"
|
||||
v-model="formData.tf_opinion"
|
||||
required
|
||||
type="textarea"
|
||||
name="tf_opinion"
|
||||
rows="4"
|
||||
autosize
|
||||
placeholder="请填审批意见"></van-field>
|
||||
|
||||
<van-field name="tf_userSign" label="签字">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button @click="handleTaskAction(6)">退回到发起人</van-button>
|
||||
<van-button type="danger" @click="handleTaskAction(2)">拒绝申请</van-button>
|
||||
<van-button type="primary" @click="handleTaskAction(1)">同意申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</h5-outlay-reimburse-info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["ACTIVITY_BUDGET_TYPE"],
|
||||
components: {
|
||||
"h5-outlay-reimburse-info": H5_OUTLAY_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
searchName: "info.userName",
|
||||
},
|
||||
formData: {},
|
||||
infoShow: false,
|
||||
showApprovalForm: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/flow/common/executeTask', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.$refs.h5OutlayReimburseInfo.onClose()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
tf_opinion: null,
|
||||
tf_userSign: null,
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.infoShow = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.h5OutlayReimburseInfo.onOpen(row)
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,95 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="问卷列表" placeholder fixed></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-tabs v-model="pageForm.category" @change="doSearch">
|
||||
<van-tab v-for="item in dict.type.ACTIVITY_QSV_CATEGORY" :name="item.code" :title="item.label"
|
||||
:key="item.code"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/h5/qsv/pageData" :page_form.sync="pageForm" ref="tableListRef" title="title"
|
||||
@ready="doSearch">
|
||||
<!-- <template #header="{index,row}"></template>-->
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="开始时间">{{row.startTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.endTime}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onEnter(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
dicts: ['ACTIVITY_QSV_CATEGORY'],
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
category: "QUIZ"
|
||||
},
|
||||
categoryPaths: {
|
||||
QUIZ: "/platform/h5/qsv/quiz",
|
||||
SURVEY: "/platform/h5/qsv/survey",
|
||||
VOTE: "/platform/h5/qsv/vote"
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack() {
|
||||
this.$pjaxReplace('/platform/h5/home')
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
|
||||
async onEnter(item) {
|
||||
debugger
|
||||
if (item.groupId) {
|
||||
const {
|
||||
code,
|
||||
data
|
||||
} = await $.get('/platform/activity/basic/scope/getScopeUser', {activityGroupId: item.groupId})
|
||||
if (code === 0 && data === 0) {
|
||||
this.$toast.fail("您没有权限参与")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const {startTime, endTime} = item
|
||||
if (this.$moment(startTime).unix() > this.$moment().unix()) {
|
||||
this.$toast("未开始")
|
||||
return
|
||||
}
|
||||
|
||||
const path = this.categoryPaths[item.category]
|
||||
if (path) {
|
||||
pjaxReplace(path + "?id=" + item.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,406 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="问卷列表" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="container" :style="{'padding-bottom': answerRecord.isFinish ? 0 : '84px'}">
|
||||
<van-sticky offset-top="46px">
|
||||
<!--开启计时 未完成 活动未结束-->
|
||||
<div class="timer" v-if="activity.timeLimit > 0 && !answerRecord.isFinish && !isEnd">⏰{{ remainingTime }}s
|
||||
</div>
|
||||
<h2 class="title">{{ activity.title }}</h2>
|
||||
</van-sticky>
|
||||
|
||||
<div v-if="!answerRecord.isFinish">
|
||||
<div v-for="(subject, index) in subjects" :key="index" class="subject">
|
||||
<p>{{index+1}}、{{ subject.title }}</p>
|
||||
<div class="tag">
|
||||
<van-tag v-if="subject.type === 'checkbox'" type="primary" size="large">多选</van-tag>
|
||||
<van-tag v-if="subject.type === 'radio'" type="primary" size="large">单选</van-tag>
|
||||
<van-tag v-if="subject.score" type="primary" size="large">{{subject.score}}分</van-tag>
|
||||
</div>
|
||||
|
||||
<van-checkbox-group v-model="subject.userSelectOptionIds" :ref="'subject'+subject.id">
|
||||
<van-cell-group>
|
||||
<van-cell
|
||||
v-for="(option,index) in subject.options"
|
||||
clickable
|
||||
:key="option.id"
|
||||
:title="option.text"
|
||||
@click="cellToggle(subject,option.id)"
|
||||
>
|
||||
<template #icon>
|
||||
<van-checkbox
|
||||
:name="option.id"
|
||||
:ref="'option'+option.id"
|
||||
:disabled="answerRecord.isFinish"
|
||||
:shape="subject.type==='checkbox' ? 'square' : 'round'"
|
||||
style="margin-right: 10px"
|
||||
></van-checkbox>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</van-checkbox-group>
|
||||
</div>
|
||||
<div class="button-control" v-if="!answerRecord.isFinish">
|
||||
<van-button type="info" @click="onSubmit" block :disabled="isEnd">{{isEnd ? '已结束' : '提交'}}
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
id: GetQueryString("id"),
|
||||
H5JumpTo: GetQueryString("H5JumpTo"),
|
||||
subjects: [],
|
||||
activity: {},
|
||||
isFinished: false,
|
||||
answerRecord: {},
|
||||
answerRecordId: null,
|
||||
//历史记录
|
||||
historyScores: [],
|
||||
//答题用时
|
||||
answerTime: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isEnd() {
|
||||
if (this.activity) {
|
||||
return this.$moment().unix() > this.$moment(this.activity.endTime).unix()
|
||||
}
|
||||
return true
|
||||
},
|
||||
remainingTime() {
|
||||
if (this.activity && this.activity.timeLimit > 0) {
|
||||
return this.activity.timeLimit * 60 - this.answerTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//获取活动、题目
|
||||
listSubjects() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/subjects", {activityId: this.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.activity = res.data.activity
|
||||
this.subjects = res.data.subjects
|
||||
this.answerRecordId = res.data.answerRecordId
|
||||
// this.checkGroupPermission()
|
||||
if (!this.H5JumpTo && this.activity.repeatable && res.data.repeatTips) {
|
||||
// 如果是可重复答题,第二次答题进来弹出提示
|
||||
vant.Dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您已完成本次答题,是否要重新答题?',
|
||||
confirmButtonText: '重新答题',
|
||||
cancelButtonText: '查看答题记录',
|
||||
}).then(() => {
|
||||
this.getAnswerRecord()
|
||||
}).catch(() => {
|
||||
pjaxReplace("/platform/h5/qsv/quiz/result?answerRecordId=" + this.answerRecordId)
|
||||
// pjaxReplace("/mobile/index")
|
||||
});
|
||||
} else {
|
||||
this.getAnswerRecord()
|
||||
}
|
||||
} else {
|
||||
vant.Dialog.alert({
|
||||
title: '温馨提示',
|
||||
message: res.msg,
|
||||
}).then(() => {
|
||||
pjaxReplace("/mobile/index")
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//获取回答记录
|
||||
getAnswerRecord() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/answerRecord", {answerRecordId: this.answerRecordId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.answerRecord = res.data
|
||||
|
||||
if (this.answerRecord.isFinish || this.$moment().unix() > this.$moment(this.activity.endTime)) {
|
||||
pjaxReplace("/platform/h5/qsv/quiz/result?answerRecordId=" + this.answerRecordId)
|
||||
}
|
||||
|
||||
this.initAnswer()
|
||||
this.checkTimer()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//答案回显
|
||||
initAnswer() {
|
||||
this.subjects.forEach((subject, subjectIndex) => {
|
||||
if (subject.type === "radio") {
|
||||
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||
}
|
||||
if (this.answerRecord.optionIds) {
|
||||
this.answerRecord.optionIds[subjectIndex].forEach((optionId) => {
|
||||
this.$refs["option" + optionId][0].toggle()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
historyBack() {
|
||||
if (this.timerInterval) {
|
||||
clearInterval(this.timerInterval)
|
||||
}
|
||||
historyBack()
|
||||
},
|
||||
|
||||
//答题计时器
|
||||
checkTimer() {
|
||||
if (this.timerInterval) {
|
||||
clearInterval(this.timerInterval)
|
||||
}
|
||||
|
||||
//开启计时
|
||||
const startInterval = () => {
|
||||
this.timerInterval = setInterval(() => {
|
||||
this.answerTime++
|
||||
if (this.activity.timeLimit > 0 && this.answerTime >= this.activity.timeLimit * 60) {
|
||||
clearInterval(this.timerInterval)
|
||||
|
||||
this.$dialog.alert({
|
||||
title: "提示",
|
||||
message: "答题时间到,请刷新页面重新答题",
|
||||
}).then(() => {
|
||||
window.location.reload()
|
||||
})
|
||||
|
||||
// const loading = this.$toast.loading({
|
||||
// message: "答题时间到,自动提交中",
|
||||
// forbidClick: true
|
||||
// })
|
||||
// setTimeout(() => {
|
||||
// this.autoSubmit(loading)
|
||||
// }, 1500)
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
if (!this.isEnd && !this.answerRecord.isFinish) {
|
||||
if (this.activity.timeLimit > 0) {
|
||||
this.$dialog
|
||||
.alert({
|
||||
title: "提示",
|
||||
message: "本次答题时间" + this.activity.timeLimit + "分钟,点击确认开始答题"
|
||||
})
|
||||
.then(() => {
|
||||
startInterval()
|
||||
})
|
||||
} else {
|
||||
startInterval()
|
||||
}
|
||||
}
|
||||
|
||||
// if (this.activity.timeLimit > 0 && !this.isEnd) {
|
||||
// if (!this.answerRecord.isFinish) {
|
||||
// this.$dialog
|
||||
// .alert({
|
||||
// title: "提示",
|
||||
// message: "本次答题时间" + this.activity.timeLimit + "分钟,点击确认开始答题"
|
||||
// })
|
||||
// .then(() => {
|
||||
// this.remainingTime = this.activity.timeLimit * 60
|
||||
// this.timerInterval = setInterval(() => {
|
||||
// if (this.remainingTime > 0) {
|
||||
// this.remainingTime--
|
||||
// } else {
|
||||
// clearInterval(this.timerInterval)
|
||||
// const loading = this.$toast.loading({
|
||||
// message: "答题时间到,自动提交中",
|
||||
// forbidClick: true
|
||||
// })
|
||||
// this.autoSubmit(loading)
|
||||
// }
|
||||
// }, 1000)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
},
|
||||
|
||||
historyScore() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/historyScore", {activityId: this.activityId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.historyScores = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//选项点击
|
||||
cellToggle(subject, optionId) {
|
||||
if (this.answerRecord.isFinish) {
|
||||
return
|
||||
}
|
||||
|
||||
if (subject.type === "radio") {
|
||||
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||
}
|
||||
this.$refs["option" + optionId][0].toggle()
|
||||
},
|
||||
|
||||
//手动提交
|
||||
onSubmit() {
|
||||
if (this.isEnd) {
|
||||
this.$toast("调查已结束")
|
||||
return
|
||||
}
|
||||
|
||||
//提示那些题没有作答
|
||||
for (let i = 0; i < this.subjects.length; i++) {
|
||||
let subject = this.subjects[i]
|
||||
//["radio", "checkbox"].includes(subject.type) &&
|
||||
if (!subject.userSelectOptionIds || subject.userSelectOptionIds.length === 0) {
|
||||
this.$toast.fail("第" + (i + 1) + "题未做答")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (this.timerInterval) {
|
||||
clearInterval(this.timerInterval)
|
||||
}
|
||||
|
||||
this.autoSubmit()
|
||||
},
|
||||
|
||||
//自动提交
|
||||
autoSubmit(loading = null) {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/submitAnswer", {
|
||||
answer: JSON.stringify({
|
||||
activityId: this.id,
|
||||
answerRecordId: this.answerRecordId,
|
||||
subjects: this.subjects.map((subject) => {
|
||||
return {
|
||||
id: subject.id,
|
||||
userSelectOptionIds: ["checkbox", "radio"].includes(subject.type) ? subject.userSelectOptionIds : []
|
||||
}
|
||||
}),
|
||||
answerTime: this.answerTime
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
pjaxReplace("/platform/h5/qsv/quiz/result?answerRecordId=" + this.answerRecordId)
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
if (loading) {
|
||||
loading.clear()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// async checkGroupPermission() {
|
||||
// const groupId = this.activity.groupId
|
||||
// if (groupId) {
|
||||
// const { code, data } = await this.$axios.post("/open/common/checkGroupPermission", { groupId })
|
||||
// if (code === 0) {
|
||||
// if (!data) {
|
||||
// this.$dialog
|
||||
// .alert({
|
||||
// title: "提示",
|
||||
// message: "您没有权限参与"
|
||||
// })
|
||||
// .then(() => {
|
||||
// location.back()
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
},
|
||||
created() {
|
||||
if (this.timerInterval) {
|
||||
clearInterval(this.timerInterval)
|
||||
}
|
||||
if (this.id) {
|
||||
this.listSubjects()
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/deep/ .container .title {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
background: #ffffff;
|
||||
margin: 0 0 10px 0 !important;
|
||||
color: var(--color-primary);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.container .card {
|
||||
padding: 10px;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.subject {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.subject p {
|
||||
font-size: 16px;
|
||||
margin: 20px 0 10px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.subject .tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/deep/ .timer {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
background: #fff;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.result {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.button-control {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
`
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,359 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="问卷列表" placeholder fixed></van-nav-bar>
|
||||
|
||||
<div class="container" :style="{'padding-bottom': answerRecord.isFinish ? 0 : '84px'}">
|
||||
<van-sticky offset-top="46px">
|
||||
<h2 class="title">{{ activity.title }}</h2>
|
||||
<div class="score-form">
|
||||
<div class="score-form-total">
|
||||
<div class="score-font-style">{{totalScore}}</div>
|
||||
<i class="score-underline"></i>
|
||||
</div>
|
||||
</div>
|
||||
</van-sticky>
|
||||
|
||||
<div>
|
||||
<div v-for="(subject, index) in subjects" :key="index" class="subject">
|
||||
<p>{{index+1}}、{{ subject.title }}</p>
|
||||
<div class="tag">
|
||||
<van-tag v-if="subject.type === 'checkbox'" type="primary" size="large">多选</van-tag>
|
||||
<van-tag v-if="subject.type === 'radio'" type="primary" size="large">单选</van-tag>
|
||||
<van-tag v-if="subject.score" type="primary" size="large">{{subject.score}}分</van-tag>
|
||||
</div>
|
||||
|
||||
<van-checkbox-group v-model="subject.userSelectOptionIds" :ref="'subject'+subject.id">
|
||||
<van-cell-group>
|
||||
<van-cell
|
||||
v-for="(option,index) in subject.options"
|
||||
clickable
|
||||
:key="option.id"
|
||||
:title="option.text"
|
||||
>
|
||||
<template #title>
|
||||
<span :style="{color : option.isCorrect ? 'green' : ''}">{{option.text}}</span>
|
||||
</template>
|
||||
<template #icon>
|
||||
<van-checkbox
|
||||
:name="option.id"
|
||||
:ref="'option'+option.id"
|
||||
:disabled="answerRecord.isFinish"
|
||||
style="margin-right: 10px"
|
||||
></van-checkbox>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</van-checkbox-group>
|
||||
|
||||
<div class="answer-container">
|
||||
<div v-if="answerRecord.extJson?.[subject.id]?.isCorrect" class="correct-answer">
|
||||
<van-icon name="passed"></van-icon>
|
||||
回答正确
|
||||
</div>
|
||||
<div v-else-if="answerRecord.extJson?.[subject.id]" class="incorrect-answer">
|
||||
<van-icon name="close"></van-icon>
|
||||
回答错误
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="button-control">
|
||||
<van-button v-if="canAgainQuestion" type="primary" @click="againQuestion" block>重新答题</van-button>
|
||||
<van-button type="primary" @click="openHistory" block>查看全部答题记录</van-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<van-action-sheet v-model="historyShow" title="历史记录" >
|
||||
<div class="history-list">
|
||||
<div v-for="item in historyList" class="history-item">
|
||||
<div class="history-header">
|
||||
<span>{{ item.date }}</span>
|
||||
<van-tag v-if="item.isHighestScore" type="danger" class="tag">最高分</van-tag>
|
||||
<van-tag v-if="item.isLatestScore" type="primary" class="tag">最新得分</van-tag>
|
||||
</div>
|
||||
<div class="history-info">答题分数:{{ item.totalScore }}</div>
|
||||
<div class="history-info">答题用时:{{ item.answerTime | formatSeconds }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
answerRecordId: GetQueryString("answerRecordId"),
|
||||
answerRecord: {},
|
||||
subjects: [],
|
||||
activity: {},
|
||||
list: [],
|
||||
historyShow: false,
|
||||
historyList: [],
|
||||
canAgainQuestion: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalScore() {
|
||||
if (!this.answerRecord || !this.answerRecord.extJson) {
|
||||
return 0
|
||||
}
|
||||
let totalScore = 0
|
||||
for (const key in this.answerRecord.extJson) {
|
||||
if (this.answerRecord.extJson.hasOwnProperty(key)) {
|
||||
totalScore += this.answerRecord.extJson[key].score || 0
|
||||
}
|
||||
}
|
||||
return totalScore
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
formatSeconds(seconds) {
|
||||
if (seconds) {
|
||||
const minutes = Math.floor(seconds / 60) // 获取总分钟数
|
||||
const remainingSeconds = seconds % 60 // 获取剩余秒数
|
||||
// 格式化输出,确保秒数始终为两位数
|
||||
return minutes + "分钟" + String(remainingSeconds).padStart(2, "0") + "秒"
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 重新答题
|
||||
*/
|
||||
againQuestion() {
|
||||
vant.Dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '确定要重新答题吗?',
|
||||
}).then(() => {
|
||||
pjaxReplace('/platform/h5/qsv/quiz?id=' + this.activity.id + "&H5JumpTo=true")
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
getAnswerResult() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/answerResult", { answerRecordId: this.answerRecordId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.subjects = res.data.subjects
|
||||
this.activity = res.data.activity
|
||||
this.getAnswerRecord()
|
||||
this.getHistoryQuestion()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//获取回答记录
|
||||
getAnswerRecord() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/answerRecord", { answerRecordId: this.answerRecordId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.answerRecord = res.data
|
||||
this.initAnswer()
|
||||
}
|
||||
})
|
||||
},
|
||||
//答案回显
|
||||
initAnswer() {
|
||||
this.subjects.forEach((subject, subjectIndex) => {
|
||||
const answer = this.answerRecord.extJson[subject.id]
|
||||
if (["radio", "checkbox"].includes(subject.type)) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||
})
|
||||
answer?.optionIds.forEach((optionId) => {
|
||||
this.$nextTick(() => {
|
||||
this.$refs["option" + optionId][0].toggle()
|
||||
})
|
||||
})
|
||||
} else if (subject.type === "text") {
|
||||
subject.userFillContent = answer?.text
|
||||
}
|
||||
})
|
||||
},
|
||||
historyBack() {
|
||||
pjaxReplace('/platform/h5/qsv')
|
||||
},
|
||||
openHistory() {
|
||||
this.historyShow = true
|
||||
},
|
||||
getHistoryQuestion() {
|
||||
this.$axios.post("/platform/h5/qsv/quiz/historyScore", { activityId: this.activity.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.historyList = res.data
|
||||
if (this.activity.maxAttempts > res.data.length) {
|
||||
this.canAgainQuestion = true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getAnswerResult()
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/deep/ .container .title {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
margin: 0 !important;
|
||||
background: #ffffff;
|
||||
color: var(--color-primary);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.container .score {
|
||||
}
|
||||
|
||||
.container .card {
|
||||
padding: 10px;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.subject {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.subject p {
|
||||
font-size: 16px;
|
||||
margin: 20px 0 10px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.subject .tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
/deep/ .score-form {
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
border-top: 1px solid #f1f1f1;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/deep/ .score-form-total {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
padding: 10px 20px 10px 0;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
/deep/ .score-text-news {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/deep/ .score-font-style {
|
||||
font-size: 32px;
|
||||
color: #ff6a00;
|
||||
word-break: keep-all;
|
||||
line-height: 38px;
|
||||
min-width: 47px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/deep/ .score-underline {
|
||||
background: url(//image.wjx.cn/images/newimg/score-form/score-underline@2x.png) no-repeat center;
|
||||
background-size: 47px 16px;
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
width: 47px;
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.van-checkbox__icon--checked .van-icon {
|
||||
color: #fff !important;
|
||||
background-color: var(--color-primary) !important;
|
||||
border-color: var(--color-primary) !important;
|
||||
}
|
||||
|
||||
.van-checkbox__icon--disabled .van-icon {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.answer-container {
|
||||
padding: 16px;
|
||||
}
|
||||
.correct-answer {
|
||||
color: green;
|
||||
}
|
||||
.incorrect-answer {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.button-control {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/deep/ .history-list {
|
||||
background: #f1f1f1;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/deep/ .history-item {
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
margin: 20px 10px;
|
||||
box-shadow:
|
||||
8px 8px 16px #d9d9d9,
|
||||
-8px -8px 16px #ffffff;
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
/deep/ .history-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
/deep/ .history-header span {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/deep/ .history-header .tag {
|
||||
margin-left: 8px;
|
||||
color: #fff;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
/deep/ .history-info {
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
`
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,292 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.container .title {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
background: #ffffff;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
.container .card {
|
||||
padding: 10px;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.subject {
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.subject p {
|
||||
font-size: 16px;
|
||||
margin: 20px 0 10px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.subject .tag {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.button-control {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.van-checkbox__icon--checked .van-icon {
|
||||
color: #fff !important;
|
||||
background-color: var(--color-primary) !important;
|
||||
border-color: var(--color-primary) !important;
|
||||
}
|
||||
|
||||
.van-checkbox__icon--disabled .van-icon {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.ui-input-box {
|
||||
border: 1px solid #e3e3e3;
|
||||
margin: 5px 0;
|
||||
background-color: #fff;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ui-input-box input {
|
||||
background-color: #fff;
|
||||
border: none !important;
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
-webkit-appearance: none;
|
||||
resize: none;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar title="问卷调查" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar>
|
||||
<div class="container" :style="{'padding-bottom': answerRecord.isFinish ? 0 : '84px'}">
|
||||
<h2 class="title">{{ activity.title }}</h2>
|
||||
<div v-if="!isFinished">
|
||||
<div v-for="(subject, index) in subjects" :key="index" class="subject">
|
||||
<p>{{index+1}}、{{ subject.title }}</p>
|
||||
<div class="tag">
|
||||
<van-tag v-if="subject.type === 'checkbox'" type="primary" size="large">多选</van-tag>
|
||||
<van-tag v-if="subject.type === 'radio'" type="primary" size="large">单选</van-tag>
|
||||
<van-tag v-if="subject.score" type="primary" size="large">{{subject.score}}分</van-tag>
|
||||
</div>
|
||||
|
||||
<!--单选、多选-->
|
||||
<van-checkbox-group
|
||||
v-model="subject.userSelectOptionIds"
|
||||
:ref="'subject'+subject.id"
|
||||
v-if="['radio','checkbox'].includes(subject.type)"
|
||||
>
|
||||
<van-cell-group>
|
||||
<van-cell
|
||||
v-for="(option,index) in subject.options"
|
||||
clickable
|
||||
:key="option.id"
|
||||
:title="option.text"
|
||||
@click="cellToggle(subject,option.id)"
|
||||
>
|
||||
<template #icon>
|
||||
<van-checkbox :name="option.id" :ref="'option'+option.id" style="margin-right: 10px"></van-checkbox>
|
||||
</template>
|
||||
<img
|
||||
slot="right-icon"
|
||||
v-if="option.imgUrl"
|
||||
:src="option.imgUrl"
|
||||
alt=""
|
||||
style="width: 40px; height: 40px"
|
||||
@click.stop="previewOptionImg(option.imgUrl)"
|
||||
/>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</van-checkbox-group>
|
||||
|
||||
<!--填空题-->
|
||||
<div class="ui-input-box" v-if="subject.type==='text'">
|
||||
<input type="text" v-model="subject.userFillContent" :readonly="answerRecord.isFinish" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="button-control" v-if="!answerRecord.isFinish">
|
||||
<van-button type="primary" @click="onSubmit" block :disabled="isEnd">{{isEnd ? '已结束' : '提交'}}</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
list: [],
|
||||
id: null,
|
||||
subjects: [],
|
||||
activity: {},
|
||||
remainingTime: 0,
|
||||
isFinished: false,
|
||||
answerRecord: {},
|
||||
answerRecordId: null
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isEnd() {
|
||||
if (this.activity) {
|
||||
return this.$moment().unix() > this.$moment(this.activity.endTime).unix()
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
//获取活动、题目
|
||||
listSubjects() {
|
||||
this.$axios.post("/platform/h5/qsv/survey/subjects", { activityId: this.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.activity = res.data.activity
|
||||
this.subjects = res.data.subjects
|
||||
this.answerRecordId = res.data.answerRecordId
|
||||
this.getAnswerRecord()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//获取回答记录
|
||||
getAnswerRecord() {
|
||||
this.$axios.post("/platform/h5/qsv/survey/answerRecord", { answerRecordId: this.answerRecordId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.answerRecord = res.data
|
||||
if (this.answerRecord.isFinish) {
|
||||
this.$toast.success("您已完成该调查")
|
||||
}
|
||||
this.initAnswer()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//答案回显
|
||||
initAnswer() {
|
||||
this.subjects.forEach((subject, subjectIndex) => {
|
||||
const answer = this.answerRecord.extJson[subject.id]
|
||||
|
||||
if (["radio", "checkbox"].includes(subject.type)) {
|
||||
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||
answer?.optionIds.forEach((optionId) => {
|
||||
this.$nextTick(() => {
|
||||
this.$refs["option" + optionId][0].toggle()
|
||||
})
|
||||
})
|
||||
} else if (subject.type === "text") {
|
||||
subject.userFillContent = answer?.text
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//选项点击
|
||||
cellToggle(subject, optionId) {
|
||||
if (this.answerRecord.isFinish) {
|
||||
return
|
||||
}
|
||||
|
||||
if (subject.type === "radio") {
|
||||
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||
}
|
||||
this.$refs["option" + optionId][0].toggle()
|
||||
},
|
||||
|
||||
//预览图片
|
||||
previewOptionImg(img) {
|
||||
vant.ImagePreview([img])
|
||||
},
|
||||
|
||||
//手动提交
|
||||
onSubmit() {
|
||||
const endTime = this.activity.endTime
|
||||
if (this.isEnd) {
|
||||
this.$toast("调查已结束")
|
||||
return
|
||||
}
|
||||
|
||||
//提示那些题没有作答
|
||||
for (let i = 0; i < this.subjects.length; i++) {
|
||||
const subject = this.subjects[i]
|
||||
if (["radio", "checkbox"].includes(subject.type)) {
|
||||
if (!subject.userSelectOptionIds || subject.userSelectOptionIds.length === 0) {
|
||||
this.$toast.fail("第" + (i + 1) + "题未做答")
|
||||
return
|
||||
}
|
||||
} else if ("text" === subject.type) {
|
||||
if (!subject.userFillContent) {
|
||||
this.$toast.fail("第" + (i + 1) + "题未作答")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
this.autoSubmit()
|
||||
},
|
||||
|
||||
//自动提交
|
||||
autoSubmit(loading = null) {
|
||||
this.$axios
|
||||
.post("/platform/h5/qsv/survey/submitAnswer", {
|
||||
answer: JSON.stringify({
|
||||
activityId: this.id,
|
||||
answerRecordId: this.answerRecordId,
|
||||
subjects: this.subjects.map((subject) => {
|
||||
return {
|
||||
id: subject.id,
|
||||
userSelectOptionIds: ["checkbox", "radio"].includes(subject.type) ? subject.userSelectOptionIds : [],
|
||||
userFillContent: subject.type === "text" ? subject.userFillContent : null
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.getAnswerRecord()
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
if (loading) {
|
||||
loading.clear()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const id = GetQueryString("id")
|
||||
if (id) {
|
||||
this.id = id
|
||||
this.listSubjects()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,366 @@
|
||||
const apply = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<van-popup v-model:show="visible" :style="{ height: '100%',width: '100%', 'background-color': '#F7F8FA'}" position="right" safe-area-inset-bottom>
|
||||
<van-nav-bar :title="row.name" left-text="返回" left-arrow @click-left="visible = false" fixed placeholder></van-nav-bar>
|
||||
|
||||
<div class="top-calendar">
|
||||
<div class="calendar-left">
|
||||
<div :class="getDayClass(item)" @click="dayClick(item)" v-for="item in weekList">
|
||||
<div class="day-info-week">
|
||||
{{item.weekdayCN}}
|
||||
</div>
|
||||
<div class="day-info-month">
|
||||
{{$moment(item.day).format('MM-DD')}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calendar-right">
|
||||
<van-icon size="16" color="white" name="arrow-down" @click="calendarVisible = true"></van-icon>
|
||||
<van-calendar class="calendar-popup" v-model="calendarVisible" color="#246fb4" position="top" @confirm="calendarConfirm"
|
||||
:default-date="new Date(selectDate)"
|
||||
:formatter="calendarFormatter"
|
||||
:first-day-of-week="1"
|
||||
title="选择开始日期"></van-calendar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<table v-if="weekList.find(o => $moment(o.day).unix() === $moment(selectDate).unix())?.disabled === false" style="width: 100%">
|
||||
<template v-for="item in allowTimeList">
|
||||
<tr>
|
||||
<td class="container-times">{{item.startTime + '-' + item.endTime}}</td>
|
||||
<td>
|
||||
<div v-if="item.disabled === true" class="container-state">{{ item.tooltip }}</div>
|
||||
<div @click="selectTime(item)" v-else class="container-state" style="background-color: #e8ffef; color: #52986a">
|
||||
<label v-if="(item.dateStr + ' ' + item.startTime + '-' + item.endTime) !== (selected.dateStr + ' ' + selected.startTime + '-' + selected.endTime)">
|
||||
可预约
|
||||
</label>
|
||||
<span v-else>
|
||||
<van-icon name="passed" size="26" style="line-height: 36px;position: unset"></van-icon>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
<van-empty v-else image="error" :description="selectDate + '不能预约'"></van-empty>
|
||||
</div>
|
||||
|
||||
<div style="position: fixed; bottom: 0; width: 100%">
|
||||
<van-button @click="onApply" type="primary" color="#246fb4" style="width: 100%">确定预约</van-button>
|
||||
</div>
|
||||
</van-popup>
|
||||
|
||||
<van-action-sheet v-model="formVisible" title="确认预约信息">
|
||||
<van-notice-bar left-icon="volume-o"
|
||||
:text="'您已选择的预约日期为:' + selectDate"></van-notice-bar>
|
||||
<van-form ref="formRef" class="form-container">
|
||||
<van-field label="预约人" :rules="[{ required: true }]" v-model="formData.applyUserName" readonly
|
||||
required name="applyUserName"></van-field>
|
||||
<van-field label="性别" :rules="[{ required: true }]" v-model="formData.sex" readonly
|
||||
required name="sex"></van-field>
|
||||
<van-field label="工号" :rules="[{ required: true }]" v-model="formData.applyLoginName" readonly
|
||||
required name="applyLoginName"></van-field>
|
||||
<van-field label="所属单位" :rules="[{ required: true }]" v-model="formData.applyUnitName" readonly
|
||||
required name="applyUnitName"></van-field>
|
||||
<van-field label="联系电话" :rules="[{ required: true }]" v-model="formData.applyMobile" type="number"
|
||||
required name="applyMobile"></van-field>
|
||||
<van-field label="预约时间" :rules="[{ required: true }]" v-model="formData.applyTime"
|
||||
required readonly name="applyTime"></van-field>
|
||||
<van-field name="stepper" label="预约人数" required :rules="[{ required: true }]">
|
||||
<template #input>
|
||||
<van-stepper
|
||||
:disabled="row.reserveTarget === 1 || row.reserveTarget === 3"
|
||||
v-model="formData.joinCount"></van-stepper>
|
||||
</template>
|
||||
</van-field>
|
||||
<van-field
|
||||
v-model="formData.applyCause"
|
||||
rows="4"
|
||||
autosize
|
||||
label="预约事由"
|
||||
type="textarea"
|
||||
maxlength="50"
|
||||
placeholder="请输入预约事由"
|
||||
show-word-limit
|
||||
required
|
||||
name="applyCause"
|
||||
:rules="[{ required: true }]"
|
||||
></van-field>
|
||||
<div class="form-actions">
|
||||
<van-button @click="formVisible = false" type="info" plain round>关闭</van-button>
|
||||
<van-button @click="onSubmit" v-if="!taskId" type="info" round>提交</van-button>
|
||||
<van-button @click="onFinishTask" v-else type="info" round>提交</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</van-action-sheet>
|
||||
</div>
|
||||
`,
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
taskId: '',
|
||||
bizId: '',
|
||||
row: {},
|
||||
visible: false,
|
||||
selectDate: '',
|
||||
selected: {},
|
||||
weekList: [],
|
||||
allowDayList: [],
|
||||
allowTimeList: [],
|
||||
weekdayCNMap: {0: '周日', 1: '周一', 2: '周二', 3: '周三', 4: '周四', 5: '周五', 6: '周六'},
|
||||
|
||||
formVisible: false,
|
||||
formData: {
|
||||
applyCause: '',
|
||||
},
|
||||
|
||||
calendarVisible: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
calendarFormatter(day) {
|
||||
return (day) => {
|
||||
if(!this.allowDayList.includes(this.$moment(day.date).format('YYYY-MM-DD'))) {
|
||||
day.type = 'disabled'
|
||||
}
|
||||
return day
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onOpen(row, applyRow = null) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
await this.init()
|
||||
if(applyRow) {
|
||||
this.taskId = applyRow.taskId
|
||||
this.bizId = applyRow.bizId
|
||||
this.applyTime = applyRow.applyDay
|
||||
this.selectDate = applyRow.applyDay
|
||||
this.selected = {
|
||||
dateStr: applyRow.applyDay,
|
||||
startTime: applyRow.startTime,
|
||||
endTime: applyRow.endTime,
|
||||
}
|
||||
this.formVisible = true
|
||||
this.formData = clone(applyRow)
|
||||
this.$set(this.formData, 'applyTime', this.formData.startTime + '-' + this.formData.endTime)
|
||||
this.$set(this.formData, 'sex', this.$store.state.user.sex)
|
||||
const day = this.weekList.find(o => o.dateStr === applyRow.applyDay)
|
||||
if(day) {
|
||||
await this.dayClick(day)
|
||||
}
|
||||
}
|
||||
},
|
||||
async init() {
|
||||
this.selectDate = this.$moment().format('YYYY-MM-DD')
|
||||
await this.queryAllowDay()
|
||||
await this.queryTimesByDay()
|
||||
this.setWeekList(this.selectDate)
|
||||
},
|
||||
async calendarConfirm(date) {
|
||||
this.selectDate = this.$moment(date).format('YYYY-MM-DD')
|
||||
this.setWeekList(date)
|
||||
await this.queryTimesByDay()
|
||||
this.calendarVisible = false
|
||||
},
|
||||
onApply() {
|
||||
if(Object.keys(this.selected).length === 0) {
|
||||
this.$toast('请选择要预约的时间')
|
||||
return
|
||||
}
|
||||
this.$set(this.formData, "applyUserId", this.$store.state.user.id)
|
||||
this.$set(this.formData, "applyUserName", this.$store.state.user.username)
|
||||
this.$set(this.formData, "applyLoginName", this.$store.state.user.loginname,)
|
||||
this.$set(this.formData, "applyUnitId", this.$store.state.user?.unit?.id)
|
||||
this.$set(this.formData, "applyUnitName", this.$store.state.user?.unit?.name)
|
||||
this.$set(this.formData, "applyUnionId", this.$store.state.user?.union?.id)
|
||||
this.$set(this.formData, "applyUnionName", this.$store.state.user?.union?.name)
|
||||
this.$set(this.formData, "applyMobile", this.$store.state.user.mobile)
|
||||
this.$set(this.formData, "sex", this.$store.state.user.sex)
|
||||
this.$set(this.formData, "siteId", this.row.id)
|
||||
this.$set(this.formData, "applyTime", this.selected.startTime + '-' + this.selected.endTime)
|
||||
this.$set(this.formData, "startTime", this.selected.startTime)
|
||||
this.$set(this.formData, "endTime", this.selected.endTime)
|
||||
if (this.row.reserveTarget === 1 || this.row.reserveTarget === 3) {
|
||||
this.$set(this.formData, "joinCount", this.row.maxNum)
|
||||
} else {
|
||||
this.$set(this.formData, "joinCount", 1)
|
||||
}
|
||||
this.formVisible = true
|
||||
},
|
||||
onSubmit() {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(async () => {
|
||||
const res = await this.$axios.post("/platform/site/apply/submit", {
|
||||
data: JSON.stringify(this.formData),
|
||||
days: JSON.stringify([this.selected.dateStr])
|
||||
})
|
||||
this.$toast(res.msg)
|
||||
if (res.code === 0) {
|
||||
this.$pjaxReplace("/platform/site/mine/h5")
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
onFinishTask() {
|
||||
if (!this.formData.applyTime) {
|
||||
this.$toast('未选择预约时间')
|
||||
return
|
||||
}
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/site/apply/submitAgain', {
|
||||
data: JSON.stringify(this.formData),
|
||||
days: JSON.stringify([this.selected.dateStr]),
|
||||
taskId: this.taskId
|
||||
}).then(res => {
|
||||
this.$toast(res.msg)
|
||||
if (res.code === 0) {
|
||||
this.$pjaxReplace("/platform/site/mine/h5")
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
selectTime(item) {
|
||||
if((item.dateStr + ' ' + item.startTime + '-' + item.endTime) !== (this.selected.dateStr + ' ' + this.selected.startTime + '-' + this.selected.endTime)) {
|
||||
this.$set(this.selected, 'day', item.dateStr)
|
||||
this.$set(this.selected, "dateStr", item.dateStr)
|
||||
this.$set(this.selected, 'startTime', item.startTime)
|
||||
this.$set(this.selected, 'endTime', item.endTime)
|
||||
} else {
|
||||
this.selected = {}
|
||||
}
|
||||
},
|
||||
// 获取每天的样式
|
||||
getDayClass(row) {
|
||||
let classStr = 'calendar-left-day'
|
||||
if(row.disabled) {
|
||||
classStr += ' left-day-disabled'
|
||||
} else {
|
||||
classStr += this.$moment(row.day).unix() === this.$moment(this.selectDate).unix() ? ' left-day-active' : ''
|
||||
}
|
||||
return classStr
|
||||
},
|
||||
// 点击某一天
|
||||
async dayClick(item) {
|
||||
this.selectDate = item.dateStr
|
||||
if(item.disabled) {
|
||||
this.$toast(this.$moment(item.day).format('YYYY-MM-DD') + '不可预约')
|
||||
} else {
|
||||
await this.queryTimesByDay()
|
||||
}
|
||||
},
|
||||
// 获取一周
|
||||
setWeekList(startDate) {
|
||||
const start = this.$moment(startDate)
|
||||
const allowDaySet = new Set(this.allowDayList)
|
||||
this.weekList = Array.from({ length: 8 }, (_, index) => {
|
||||
const day = start.clone().add(index, 'd')
|
||||
const dateStr = day.format('YYYY-MM-DD')
|
||||
const disabled = this.allowDayList.length > 0 && !allowDaySet.has(dateStr)
|
||||
const weekdayCN = this.weekdayCNMap[day.day()]
|
||||
return { day, disabled, weekdayCN, dateStr }
|
||||
})
|
||||
},
|
||||
// 查询哪些天是开放的
|
||||
async queryAllowDay() {
|
||||
const {data} = await this.$axios.post("/platform/site/apply/queryAllowDay", {
|
||||
siteId: this.row.id,
|
||||
})
|
||||
this.allowDayList = data
|
||||
},
|
||||
// 查询时间段
|
||||
async queryTimesByDay() {
|
||||
const {data} = await this.$axios.post("/platform/site/apply/queryTimesByDay", {
|
||||
siteId: this.row.id,
|
||||
day: this.selectDate,
|
||||
})
|
||||
this.allowTimeList = data
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
/deep/ .top-calendar {
|
||||
height: 70px;
|
||||
max-height: 70px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #0e78c5;
|
||||
}
|
||||
/deep/ .calendar-left {
|
||||
/*width: calc(100% - 20px);*/
|
||||
overflow-x: auto;
|
||||
display: flex;
|
||||
height: 90%;
|
||||
}
|
||||
/deep/ .calendar-left-day {
|
||||
min-width: 65px;
|
||||
height: 100%;
|
||||
margin: 0 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #FFF;
|
||||
border-radius: 10px;
|
||||
}
|
||||
/deep/ .left-day-active {
|
||||
background-color: #0000cc;
|
||||
}
|
||||
/deep/ .left-day-disabled {
|
||||
background-color: lightgrey;
|
||||
}
|
||||
/deep/ .container {
|
||||
background-color: white;
|
||||
margin: 10px 0;
|
||||
padding: 10px 0;
|
||||
overflow-y: auto;
|
||||
height: calc(100vh - 46px - 70px - 56px - 30px);
|
||||
}
|
||||
/deep/ .container-times {
|
||||
width: 58%;
|
||||
text-align: center;
|
||||
}
|
||||
/deep/ .container-state {
|
||||
width: 80px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
background-color: #f2f2f2;
|
||||
border-radius: 2px;
|
||||
color: #929292;
|
||||
}
|
||||
/deep/ table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
/deep/ .calendar-right {
|
||||
width: 30px;
|
||||
max-width: 30px;
|
||||
text-align: center;
|
||||
height: 60%;
|
||||
border-left: 1px solid #fff3f3;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/deep/ .calendar-popup {
|
||||
top: 46px;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="场地预约" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名或者工号搜索"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.type" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/site/apply/pageData" :page_form.sync="pageForm" ref="tableListRef" title="name" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="场地地址">{{row.address}}</table-column>
|
||||
<table-column label="联系人">{{row.contactName}}</table-column>
|
||||
<table-column label="联系方式">{{row.contactPhone}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onApply(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>预约</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<info ref="infoRef"></info>
|
||||
<site-apply ref="applyRef"></site-apply>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/siteInfo.js'){}#-->
|
||||
<!--#include('apply.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
"info": siteInfo,
|
||||
"site-apply": apply,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
year: new Date().getFullYear(),
|
||||
type: null
|
||||
},
|
||||
typeOptions: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
onApply(row) {
|
||||
if(row.reserveTarget === 1 && !this.$auth.hasRoleOr('BRANCH_UNION_ADMIN, BRANCH_UNION_CHAIRMAN') && !this.$auth.hasRole('SYSADMIN')) {
|
||||
this.$message.warning('该场地只能分工会预约')
|
||||
return
|
||||
}
|
||||
if (row.sexLimit === 1 || row.sexLimit === 2) {
|
||||
const sex = row.sexLimit === 1 ? '男' : '女'
|
||||
if(!this.$store.state.user.sex.includes(sex)) {
|
||||
this.$toast('抱歉,该场地仅限' + sex + '性会员预约')
|
||||
return
|
||||
}
|
||||
}
|
||||
this.$refs.applyRef.onOpen(row)
|
||||
},
|
||||
async onReady() {
|
||||
const typeList = await this.querySiteType()
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: "全部类型",
|
||||
value: null
|
||||
}
|
||||
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
|
||||
if (this.typeOptions.length > 0) {
|
||||
this.pageForm.type = this.typeOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
async querySiteType() {
|
||||
const res = await this.$axios.post("/platform/site/type/querySiteType")
|
||||
return res.data
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,76 @@
|
||||
const applyInfo = {
|
||||
template:
|
||||
/*language=HTML*/
|
||||
`
|
||||
<van-action-sheet v-model="visible" title="查看详情">
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="预约场地">{{ viewData.siteName }}</van-cell>
|
||||
<van-cell title="预约人">{{ viewData.applyUserName }}</van-cell>
|
||||
<van-cell title="预约人工号">{{ viewData.applyLoginName }}</van-cell>
|
||||
<van-cell title="所属单位">{{ viewData.applyUnitName }}</van-cell>
|
||||
<van-cell title="预约日期">{{ viewData.applyDay }}</van-cell>
|
||||
<van-cell title="开始时间">{{ viewData.startTime }}</van-cell>
|
||||
<van-cell title="结束时间">{{ viewData.endTime }}</van-cell>
|
||||
<van-cell title="联系电话">{{ viewData.applyMobile }}</van-cell>
|
||||
<van-cell title="预约人数">{{ viewData.joinCount }}</van-cell>
|
||||
<van-cell title="预约事由" class="direction-column-cell">{{ viewData.applyCause }}</van-cell>
|
||||
</van-cell-group>
|
||||
<template v-for="task in doneTasks">
|
||||
<van-cell-group :title="task.displayName" v-if="task.ext.isFirstTaskNode">
|
||||
<van-cell title="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})
|
||||
</van-cell>
|
||||
<van-cell title="申请时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group :title="task.displayName" v-else>
|
||||
<van-cell title="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">{{ task.finishTime }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="办理意见" v-if="!task.ext.isFirstTaskNode" class="direction-column-cell">
|
||||
<div v-html="task.taskFormData.tf_opinion"></div>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</van-action-sheet>
|
||||
`,
|
||||
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
visible:false,
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
this.viewData = row
|
||||
this.getDoneTasks()
|
||||
},
|
||||
onClose(){
|
||||
this.visible = false
|
||||
},
|
||||
getDoneTasks() {
|
||||
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doneTasks = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
const siteInfo = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<van-action-sheet v-model="visible" title="场地信息">
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="基本信息">
|
||||
<van-cell title="创建人">{{ viewData.createUserName }}</van-cell>
|
||||
<van-cell title="创建时间">{{ viewData.createTime }}</van-cell>
|
||||
<van-cell title="场地名称">{{ viewData.name }}</van-cell>
|
||||
<van-cell title="场地地址" class="direction-column-cell">{{ viewData.address }}</van-cell>
|
||||
<van-cell title="联系人">{{ viewData.contactName }}</van-cell>
|
||||
<van-cell title="联系电话">{{ viewData.contactPhone }}</van-cell>
|
||||
<van-cell title="排序编号">{{ viewData.sortNum }}</van-cell>
|
||||
<van-cell title="容纳人数">{{ viewData.maxNum }}</van-cell>
|
||||
<van-cell title="场地类型">{{ viewData.typeName }}</van-cell>
|
||||
<van-cell title="面向对象">
|
||||
<span v-if="viewData.reserveTarget === 1">面向分工会</span>
|
||||
<span v-if="viewData.reserveTarget === 2">面向个人</span>
|
||||
<span v-if="viewData.reserveTarget === 3">面向集体</span>
|
||||
</van-cell>
|
||||
<van-cell title="性别限制">
|
||||
<span v-if="viewData.sexLimit === 0">不限制</span>
|
||||
<span v-if="viewData.sexLimit === 1">男</span>
|
||||
<span v-if="viewData.sexLimit === 2">女</span>
|
||||
</van-cell>
|
||||
<van-cell title="开启状态">
|
||||
<span v-if="viewData.state">开启</span>
|
||||
<span v-else>禁用</span>
|
||||
</van-cell>
|
||||
<van-cell title="排除节假日">
|
||||
<span v-if="viewData.state">是</span>
|
||||
<span v-else>否</span>
|
||||
</van-cell>
|
||||
<van-cell title="场地介绍" class="direction-column-cell">
|
||||
<div v-if="viewData.introduce" v-html="viewData.introduce"></div>
|
||||
<div v-else>暂无场地介绍</div>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="禁用时间" v-if="viewData.notApplyTimeList && viewData.notApplyTimeList.length > 0">
|
||||
<table class="table-class">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日期</th>
|
||||
<th>开始时间</th>
|
||||
<th>结束时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item,index) in viewData.notApplyTimeList" :key="index">
|
||||
<td>{{ item.date }}</td>
|
||||
<td>{{ item.startTime }}</td>
|
||||
<td>{{ item.endTime }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="场次" v-if="viewData.openHours && viewData.openHours.length > 0">
|
||||
<table class="table-class">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>星期</th>
|
||||
<th>开始时间</th>
|
||||
<th>结束时间</th>
|
||||
<th>预约时间单位(小时)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item,index) in viewData.openHours" :key="index">
|
||||
<td>
|
||||
<span v-if="item.weekNum === 1">周一</span>
|
||||
<span v-if="item.weekNum === 2">周二</span>
|
||||
<span v-if="item.weekNum === 3">周三</span>
|
||||
<span v-if="item.weekNum === 4">周四</span>
|
||||
<span v-if="item.weekNum === 5">周五</span>
|
||||
<span v-if="item.weekNum === 6">周六</span>
|
||||
<span v-if="item.weekNum === 0">周日</span>
|
||||
</td>
|
||||
<td>{{ item.startTime }}</td>
|
||||
<td>{{ item.endTime }}</td>
|
||||
<td>{{ item.timeUnit }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</van-cell-group>
|
||||
</div>
|
||||
</van-action-sheet>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
viewData: {},
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
this.viewData = row
|
||||
this.visible = true
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
/deep/ .table-class{
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
line-height: 1.5rem;
|
||||
font-size: 13px;
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
/deep/ .table-class th {
|
||||
background-color: #f2f2f2;
|
||||
border: 1px solid #dddddd;
|
||||
}
|
||||
/deep/ .table-class tr {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
}
|
||||
/deep/ .table-class td {
|
||||
border: 1px solid #dddddd;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="我的申请" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名或者工号搜索"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.siteType" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/site/mine/pageData" :page_form.sync="pageForm" ref="tableListRef" title="applyUserName" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="场地名称">{{row.siteName}}</table-column>
|
||||
<table-column label="所属单位">{{row.applyUnitName}}</table-column>
|
||||
<table-column label="预约日期">{{row.applyDay}}</table-column>
|
||||
<table-column label="开始时间">{{row.startTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.endTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onEdit(row)"
|
||||
v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>编辑</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onRevoke(row)"
|
||||
v-if="row.canRevoke">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onDelete(row)"
|
||||
v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>删除</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<info ref="infoRef"></info>
|
||||
<site-apply ref="applyRef"></site-apply>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../apply/apply.js'){}#-->
|
||||
<!--#include('../common/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
info: applyInfo,
|
||||
"site-apply": apply,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
siteType: null
|
||||
},
|
||||
typeOptions: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onReady() {
|
||||
const typeList = await this.querySiteType()
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: "全部类型",
|
||||
value: null
|
||||
}
|
||||
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
|
||||
if (this.typeOptions.length > 0) {
|
||||
this.pageForm.siteType = this.typeOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
async onEdit(row) {
|
||||
const res = await this.$axios.post('/platform/site/manage/info', { id: row.siteId })
|
||||
this.$refs.applyRef.onOpen(res.data, row)
|
||||
},
|
||||
onDelete(row) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "确定要删除此申请吗?"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/platform/site/mine/delete", { id: row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$toast.fail(res.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
async querySiteType() {
|
||||
const res = await this.$axios.post("/platform/site/type/querySiteType")
|
||||
return res.data
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,189 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<van-nav-bar title="校工会审核" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
|
||||
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
:show-action="false"
|
||||
:reverse-color="false"
|
||||
input-align="left"
|
||||
placeholder="请输入姓名或者工号搜索"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
|
||||
<van-dropdown-item v-model="pageForm.siteType" :options="typeOptions" :multiple="false"
|
||||
@change="doSearch"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
<table-list api="/platform/site/schoolUnionAudit/pageData" :page_form.sync="pageForm" ref="tableListRef" title="applyUserName" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="场地名称">{{row.siteName}}</table-column>
|
||||
<table-column label="所属单位">{{row.applyUnitName}}</table-column>
|
||||
<table-column label="预约日期">{{row.applyDay}}</table-column>
|
||||
<table-column label="开始时间">{{row.startTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.endTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.curTaskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onApproval(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-reply"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<info ref="infoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.taskName}}</div>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
name="tf_opinion"
|
||||
label="审批意见"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
required
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
</van-form>
|
||||
<div style="display: flex; justify-content: space-between; column-gap: 10px; padding: 10px">
|
||||
<van-button type="danger" block @click="handleTaskAction(6)">退回</van-button>
|
||||
<van-button type="danger" block @click="handleTaskAction(20)">不同意</van-button>
|
||||
<van-button type="primary" block @click="handleTaskAction(1)">同意</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</info>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
info: applyInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
year: new Date().getFullYear(),
|
||||
siteType: null,
|
||||
},
|
||||
typeOptions: [],
|
||||
formData: {},
|
||||
showApprovalForm: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onReady() {
|
||||
const typeList = await this.querySiteType()
|
||||
this.typeOptions = [
|
||||
{
|
||||
text: "全部类型",
|
||||
value: null
|
||||
}
|
||||
].concat(typeList.map((v) => ({ text: v.name, value: v.id })))
|
||||
if (this.typeOptions.length > 0) {
|
||||
this.pageForm.siteType = this.typeOptions[0].value
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
onApproval(row) {
|
||||
this.showApprovalForm = true
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
this.formData = {
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
},
|
||||
async handleTaskAction(val) {
|
||||
try {
|
||||
await this.$refs.formRef.validate();
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/executeTask", {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$refs.infoRef.onClose()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
},
|
||||
onRevoke(row){
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
async querySiteType() {
|
||||
const res = await this.$axios.post("/platform/site/type/querySiteType")
|
||||
return res.data
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,149 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="报销统计" placeholder fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-item :options="yearList" @change="doSearch" v-model="pageForm.year"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入经办人搜索"
|
||||
v-model="pageForm.userName"
|
||||
></van-search>
|
||||
</van-sticky>
|
||||
|
||||
|
||||
<table-list api="/platform/unionReimburse/collect/pageData" :page_form.sync="pageForm" ref="tableListRef"
|
||||
@ready="doSearch" >
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人">{{row.userName}}</table-column>
|
||||
<table-column label="所属工会">{{row.unionName}}</table-column>
|
||||
<table-column label="所属单位">{{row.unitName}}</table-column>
|
||||
<table-column label="报销类别">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_TYPE"
|
||||
:value="row.reimburseType">
|
||||
</dict-tag>
|
||||
</table-column>
|
||||
<table-column label="报销项目">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
|
||||
:value="row.reimburseProject">
|
||||
</dict-tag>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onEdit(row)" v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>编辑</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(item)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onDelete(row)" v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>删除</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<union-reimburse-info ref="unionReimburseInfoRef"></union-reimburse-info>
|
||||
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["UNION_REIMBURSE_TYPE","UNION_REIMBURSE_PROJECT"],
|
||||
components: {
|
||||
"union-reimburse-info":UNION_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
viewShow: false,
|
||||
yearList: [],
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: "",
|
||||
year: "",
|
||||
},
|
||||
infoShow: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.unionReimburseInfoRef.onOpen(row)
|
||||
},
|
||||
onEdit(row) {
|
||||
this.$pjaxReplace("/platform/unionReimburse/apply/h5?bizId=" + row.id + "&taskId=" + row.startTaskId)
|
||||
},
|
||||
|
||||
onRevoke(row){
|
||||
this.$dialog
|
||||
.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤销申请吗?"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.startTaskId}).then((resp) => {
|
||||
this.$toast.success(resp.msg)
|
||||
this.doSearch()
|
||||
})
|
||||
})
|
||||
},
|
||||
onDelete(row) {
|
||||
this.$dialog
|
||||
.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要删除吗?"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/platform/unionReimburse/mine/delete", {id: row.id}).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$toast.success(resp.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
initData() {
|
||||
for (let i = new Date().getFullYear() - 10; i <= new Date().getFullYear(); i++) {
|
||||
this.yearList.unshift({value: i, text: i + "年"})
|
||||
}
|
||||
this.$set(this.pageForm, "year", this.yearList[0].value)
|
||||
},
|
||||
|
||||
},
|
||||
created() {
|
||||
this.initData()
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,142 @@
|
||||
const UNION_REIMBURSE_INFO = {
|
||||
template:
|
||||
/*language=HTML*/`
|
||||
<van-action-sheet v-model="visible" title="查看详情">
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="报销申请">
|
||||
<van-cell title="经办人">{{ viewData.userName }}</van-cell>
|
||||
<van-cell title="工号">{{ viewData.loginName }}</van-cell>
|
||||
<van-cell title="单位">{{ viewData.unitName }}</van-cell>
|
||||
<van-cell title="工会">{{ viewData.unionName }}</van-cell>
|
||||
<van-cell title="报销类别">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_TYPE"
|
||||
:value="viewData.reimburseType">
|
||||
</dict-tag></van-cell>
|
||||
<van-cell title="支付方式">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_PAYMENT_WAY"
|
||||
:value="viewData.paymentWay">
|
||||
</dict-tag></van-cell>
|
||||
<van-cell title="报销项目">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
|
||||
:value="viewData.reimburseProject">
|
||||
</dict-tag></van-cell>
|
||||
<van-cell title="报销经费来源">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_FUND_SOURCE"
|
||||
:value="viewData.reimburseFundSource">
|
||||
</dict-tag></van-cell>
|
||||
<van-cell title="联系方式">{{ viewData.mobile }}</van-cell>
|
||||
<van-cell title="所属社团" v-if="viewData.reimburseFundSource === 'UNION_REIMBURSE_FUND_SOURCE_3'">{{ viewData.clubName }}</van-cell>
|
||||
<van-cell title="经费余额">{{ viewData.fundBalance }}</van-cell>
|
||||
<van-cell title="户名">{{ viewData.bankUserName }}</van-cell>
|
||||
<van-cell title="银行账号">{{ viewData.bankCardNumber }}</van-cell>
|
||||
<van-cell title="开户行">{{ viewData.bankOfDeposit }}</van-cell>
|
||||
<van-cell title="慰问对象" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">{{ viewData.condolenceName }}</van-cell>
|
||||
<van-cell title="联系方式" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">{{ viewData.condolenceMobile }}</van-cell>
|
||||
<van-cell title="慰问类型" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">{{ viewData.typeName }}</van-cell>
|
||||
<van-cell title="慰问金额" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">{{ viewData.money }}</van-cell>
|
||||
<van-cell title="慰问时间" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">{{$moment(viewData.condolenceTime).format('YYYY-MM-DD')}}</van-cell>
|
||||
<van-cell title="活动名称" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">{{ viewData.activityName }}</van-cell>
|
||||
<van-cell title="活动类型" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">{{ viewData.activityType }}</van-cell>
|
||||
<van-cell title="活动人数" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">{{ viewData.activityNumber }}</van-cell>
|
||||
<van-cell title="活动地点" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">{{ viewData.activityPlace }}</van-cell>
|
||||
<van-cell title="报销金额" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">{{ viewData.money }}</van-cell>
|
||||
<van-cell title="活动时间" v-if="viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">{{$moment(viewData.activityTime).format('YYYY-MM-DD')}}</van-cell>
|
||||
<van-cell title="发票张数" v-if="viewData.reimburseType === 'UNION_REIMBURSE_TYPE_1'">{{ viewData.invoiceNumber }}</van-cell>
|
||||
<van-cell title="发票号码" v-if="viewData.reimburseType === 'UNION_REIMBURSE_TYPE_1'">{{ viewData.invoice }}</van-cell>
|
||||
<van-cell title="支付内容">{{ viewData.paymentNotes }}</van-cell>
|
||||
<van-cell title="附件">
|
||||
<file-preview :files="viewData.files" complete_result></file-preview>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<template v-for="(task,index) in doneTasks">
|
||||
<div class="process-title">
|
||||
{{ task.displayName }}
|
||||
</div>
|
||||
<van-cell-group v-if="task.ext.isFirstTaskNode">
|
||||
<van-cell title="申请用户">
|
||||
{{ task.ext.initiatorName}}({{task.ext.initiatorAccount}})
|
||||
</van-cell>
|
||||
<van-cell title="申请时间">
|
||||
{{ task.finishTime}}
|
||||
</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group v-else>
|
||||
<van-cell title="办理用户">
|
||||
{{ task.taskFormData.userName}}({{task.taskFormData.loginName}})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">
|
||||
{{ task.finishTime}}
|
||||
</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="办理意见" v-if="!task.ext.isFirstTaskNode">
|
||||
<template #label>
|
||||
{{
|
||||
task.taskFormData.opinion
|
||||
}}
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="签字" v-if="!task.ext.isFirstTaskNode">
|
||||
<van-image :src="task.ext.tf_userSign"
|
||||
v-if="task.ext.tf_userSign"
|
||||
class="signature-image"></van-image>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
<slot></slot>
|
||||
</van-action-sheet>
|
||||
`,
|
||||
dicts: ["UNION_REIMBURSE_TYPE", "UNION_REIMBURSE_PAYMENT_WAY", "UNION_REIMBURSE_FUND_SOURCE","UNION_REIMBURSE_PROJECT","PROCESS_TASK_SUBMIT_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
visible:false,
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
this.getInfo()
|
||||
this.getDoneTasks()
|
||||
},
|
||||
// 关闭
|
||||
onClose(){
|
||||
this.visible = false
|
||||
},
|
||||
// 获取申请信息
|
||||
getInfo() {
|
||||
this.$axios.post("/platform/unionReimburse/apply/info", {id: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 查看
|
||||
openView(id) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.infoDialogRef.onOpen(id)
|
||||
})
|
||||
},
|
||||
// 获取已办任务审批记录
|
||||
getDoneTasks() {
|
||||
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doneTasks = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="我的报销" placeholder fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-dropdown-menu :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-item :options="yearList" @change="doSearch" v-model="pageForm.year"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
</van-sticky>
|
||||
|
||||
|
||||
<table-list api="/platform/unionReimburse/mine/pageData" :page_form.sync="pageForm" ref="tableListRef"
|
||||
@ready="doSearch" >
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人">{{row.userName}}</table-column>
|
||||
<table-column label="所属工会">{{row.unionName}}</table-column>
|
||||
<table-column label="所属单位">{{row.unitName}}</table-column>
|
||||
<table-column label="报销类别">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_TYPE"
|
||||
:value="row.reimburseType">
|
||||
</dict-tag>
|
||||
</table-column>
|
||||
<table-column label="报销项目">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
|
||||
:value="row.reimburseProject">
|
||||
</dict-tag>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" @click="onEdit(row)" v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>编辑</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onDelete(row)" v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>删除</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<union-reimburse-info ref="unionReimburseInfoRef"></union-reimburse-info>
|
||||
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["UNION_REIMBURSE_TYPE","UNION_REIMBURSE_PROJECT"],
|
||||
components: {
|
||||
"union-reimburse-info":UNION_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
viewShow: false,
|
||||
yearList: [],
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: "",
|
||||
year: "",
|
||||
},
|
||||
infoShow: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.unionReimburseInfoRef.onOpen(row)
|
||||
},
|
||||
onEdit(row) {
|
||||
this.$pjaxReplace('/platform/unionReimburse/apply/h5?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
|
||||
},
|
||||
|
||||
onRevoke(row){
|
||||
this.$dialog
|
||||
.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤销申请吗?"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.startTaskId}).then((resp) => {
|
||||
this.$toast.success(resp.msg)
|
||||
this.doSearch()
|
||||
})
|
||||
})
|
||||
},
|
||||
onDelete(row) {
|
||||
this.$dialog
|
||||
.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要删除吗?"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/platform/unionReimburse/mine/delete", {id: row.id}).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$toast.success(resp.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
initData() {
|
||||
for (let i = new Date().getFullYear() - 10; i <= new Date().getFullYear(); i++) {
|
||||
this.yearList.unshift({value: i, text: i + "年"})
|
||||
}
|
||||
this.$set(this.pageForm, "year", this.yearList[0].value)
|
||||
},
|
||||
|
||||
},
|
||||
created() {
|
||||
this.initData()
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,195 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<van-nav-bar @click-left="historyBack" left-arrow left-text="返回" title="报销审核" placeholder fixed></van-nav-bar>
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
:reverse-color="false"
|
||||
:show-action="false"
|
||||
@search="doSearch"
|
||||
input-align="left"
|
||||
placeholder="请输入经办人搜索"
|
||||
v-model="pageForm.userName"
|
||||
></van-search>
|
||||
<van-tabs v-model="pageForm.approvalText"
|
||||
@change="(val)=>{this.pageForm.approval = val==='1';this.doSearch();}">
|
||||
<van-tab title="已审核" name="1"></van-tab>
|
||||
<van-tab title="未审核" name="0"></van-tab>
|
||||
</van-tabs>
|
||||
</van-sticky>
|
||||
|
||||
|
||||
<table-list api="/platform/unionReimburse/review/pageData" :page_form.sync="pageForm" ref="tableListRef"
|
||||
@ready="doSearch" >
|
||||
<template v-slot="{index,row}">
|
||||
<table-column label="经办人">{{row.userName}}</table-column>
|
||||
<table-column label="所属工会">{{row.unionName}}</table-column>
|
||||
<table-column label="所属单位">{{row.unitName}}</table-column>
|
||||
<table-column label="报销类别">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_TYPE"
|
||||
:value="row.reimburseType">
|
||||
</dict-tag>
|
||||
</table-column>
|
||||
<table-column label="报销项目">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
|
||||
:value="row.reimburseProject">
|
||||
</dict-tag>
|
||||
</table-column>
|
||||
<table-column label="金额">{{row.money}}</table-column>
|
||||
<table-column label="当前节点">{{row.curTaskName}}</table-column>
|
||||
</template>
|
||||
<template #actions="{index,row}">
|
||||
<div class="action-btn" @click="onView(row)">
|
||||
<i class="fa fa-eye"></i>
|
||||
<span>查看</span>
|
||||
</div>
|
||||
<div class="action-btn" v-if="row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
|
||||
<i class="fa fa-undo"></i>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
|
||||
<union-reimburse-info ref="unionReimburseInfoRef">
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">
|
||||
校工会审核
|
||||
</div>
|
||||
<div class="form-container">
|
||||
<van-form ref="formRef">
|
||||
<van-cell-group title="审批意见">
|
||||
<van-field label=""
|
||||
:rules="[{ required: true,message:'请填审批意见' }]"
|
||||
v-model="formData.tf_opinion"
|
||||
required
|
||||
type="textarea"
|
||||
name="tf_opinion"
|
||||
rows="4"
|
||||
autosize
|
||||
class="more-text"
|
||||
placeholder="请填审批意见"></van-field>
|
||||
</van-cell-group>
|
||||
<van-cell-group title="电子签名" class="form-section">
|
||||
<van-field class="more-text" name="tf_userSign" label="">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.tf_userSign" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
<!-- 按钮区域 -->
|
||||
<div class="form-actions">
|
||||
<van-button type="danger" @click="handleTaskAction(6)">退回到发起人</van-button>
|
||||
<van-button type="danger" @click="handleTaskAction(2)">拒绝申请</van-button>
|
||||
<van-button type="primary" @click="handleTaskAction(1)">同意申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
</div>
|
||||
</union-reimburse-info>
|
||||
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../info.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["UNION_REIMBURSE_TYPE","UNION_REIMBURSE_PROJECT"],
|
||||
components: {
|
||||
"union-reimburse-info":UNION_REIMBURSE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: "",
|
||||
approvalText: "0",
|
||||
approval: false,
|
||||
year: new Date().getFullYear(),
|
||||
},
|
||||
formData: {},
|
||||
showApprovalForm: false,
|
||||
infoShow: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.infoShow = false
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
},
|
||||
handleTaskAction(val) {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
this.$dialog.confirm({
|
||||
title: '温馨提示',
|
||||
message: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/flow/common/executeTask', {
|
||||
data: JSON.stringify({
|
||||
...this.formData,
|
||||
submitType: val
|
||||
})
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success("提交成功")
|
||||
this.doSearch()
|
||||
this.$refs.unionReimburseInfoRef.onClose()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
// on cancel
|
||||
});
|
||||
}).catch();
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.unionReimburseInfoRef.onOpen(row)
|
||||
},
|
||||
onAudit(row) {
|
||||
this.showApprovalForm = true
|
||||
this.formData = {
|
||||
tf_opinion: null,
|
||||
tf_userSign: null,
|
||||
processTaskId: row.taskId,
|
||||
taskName: row.curTaskName
|
||||
}
|
||||
this.$refs.unionReimburseInfoRef.onOpen(row)
|
||||
},
|
||||
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
created() {
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
Reference in New Issue
Block a user