Merge branch 'main' of https://dd3skj.picp.vip/JyuHsin/zhgh_cug_v4
This commit is contained in:
@@ -78,10 +78,10 @@ layout("/layouts/platform.html"){
|
||||
<el-table-column prop="userState" label="在职状态" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="arrivalAtSchoolDate" label="来校时间" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="personType" label="人员类型" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
|
||||
<!-- <el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="position" label="干部职务" sortable width="120" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="education" label="学历" show-overflow-tooltip sortable width="120"></el-table-column>
|
||||
<el-table-column prop="academicDegree" label="学位" show-overflow-tooltip sortable width="120"></el-table-column>
|
||||
<el-table-column prop="academicDegree" label="学位" show-overflow-tooltip sortable width="120"></el-table-column>-->
|
||||
<el-table-column prop="unitName" label="单位" show-overflow-tooltip sortable width="120"></el-table-column>
|
||||
<el-table-column prop="unitId" label="单位编码" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="political" label="政治面貌" sortable></el-table-column>
|
||||
|
||||
@@ -71,10 +71,10 @@ layout("/layouts/platform.html"){
|
||||
<el-table-column prop="userState" label="在职状态" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="personType" label="人员类型" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="arrivalAtSchoolDate" label="来校年月" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
|
||||
<!--<el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="position" label="职务" sortable width="120" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="education" label="学历" show-overflow-tooltip sortable width="120"></el-table-column>
|
||||
<el-table-column prop="academicDegree" label="学位" show-overflow-tooltip sortable width="120"></el-table-column>
|
||||
<el-table-column prop="academicDegree" label="学位" show-overflow-tooltip sortable width="120"></el-table-column>-->
|
||||
<el-table-column prop="unitName" label="单位" show-overflow-tooltip sortable width="120"></el-table-column>
|
||||
<el-table-column prop="unitId" label="单位编码" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="political" label="政治面貌" sortable></el-table-column>
|
||||
@@ -120,9 +120,9 @@ layout("/layouts/platform.html"){
|
||||
</div>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
<span slot="footer" class="dialog-footer" v-loading="updateLoading">
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="updateDialog = false" :disabled="updateLoading">取 消</el-button>
|
||||
<el-button type="primary" @click="execUpdate" :disabled="updateLoading">确 定</el-button>
|
||||
<el-button type="primary" @click="execUpdate" :disabled="updateLoading" :loading="updateLoading">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
@@ -239,6 +239,12 @@ const basicForm = {
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="手机号" prop="courseInstructorMobile">
|
||||
<template v-slot="{row}">
|
||||
<el-input size="small" v-model="row.courseInstructorMobile" placeholder="请输入手机号"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="分类标识" prop="assort">
|
||||
<template v-slot="{row}">
|
||||
<el-input size="small" v-model="row.assort" placeholder="请输入分类标识"></el-input>
|
||||
@@ -328,7 +334,7 @@ const basicForm = {
|
||||
formData: {
|
||||
notice: false,
|
||||
courseList: [
|
||||
{ orderNum: 1, courseName: "", courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false },
|
||||
{ orderNum: 1, courseName: "", courseInstructorMobile: "", courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false },
|
||||
],
|
||||
conditionStructure: {
|
||||
method: "AND",
|
||||
@@ -462,7 +468,7 @@ const basicForm = {
|
||||
this.formData.courseList = this.formData.courseList.sort((a, b) => a.orderNum - b.orderNum)
|
||||
},
|
||||
addCourse() {
|
||||
this.formData.courseList.push({ courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false })
|
||||
this.formData.courseList.push({ courseInstructorMobile: "", courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false })
|
||||
},
|
||||
async historicalActChange(val) {
|
||||
const resp = await this.$axios.post("/platform/trainSignUp/manage/findOne", {id: val})
|
||||
@@ -572,6 +578,10 @@ const basicForm = {
|
||||
this.$message.warning("第" + (i + 1) + "行信息填写有误,请核查")
|
||||
return true
|
||||
}
|
||||
if (v.courseInstructorMobile && !/^1[3-9]\d{9}$/.test(v.courseInstructorMobile)) {
|
||||
this.$message.warning("第" + (i + 1) + "行手机号格式填写有误,请核查")
|
||||
return true
|
||||
}
|
||||
if (v.isMobileSign === true && v.signType === 3 && (v.courseLocationCoordinates === undefined || v.courseLocationCoordinates.length < 2)) {
|
||||
this.$message.warning("第" + (i + 1) + "行地点坐标填写有误,请核查")
|
||||
return true
|
||||
|
||||
@@ -61,7 +61,7 @@ layout("/layouts/platform.html"){
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150px">
|
||||
<template v-slot="{row}">
|
||||
<el-button @click="handleUser(row.userId)" size="mini" type="danger" v-if="!row.isDisabled">拉黑</el-button>
|
||||
<el-button @click="handleUser(row.userId)" size="mini" type="danger" v-if="!row.isDisabled">冻结</el-button>
|
||||
<el-button @click="handleUser(row.userId)" size="mini" type="success" v-if="row.isDisabled">解封</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
+130
-40
@@ -18,9 +18,9 @@ layout("/layouts/platform.html"){
|
||||
value-format="yyyy">
|
||||
</el-date-picker>
|
||||
</search-item>
|
||||
<search-item label="所属季度">
|
||||
<search-item label="分配项目">
|
||||
<dict-select clearable code="OUTLAY_QUARTERLY"
|
||||
placeholder="请选择所属季度"
|
||||
placeholder="请选择分配项目"
|
||||
v-model="pageForm.quarterly"></dict-select>
|
||||
</search-item>
|
||||
<search-item label="所属工会">
|
||||
@@ -42,10 +42,13 @@ layout("/layouts/platform.html"){
|
||||
<table-tool label="预算分配">
|
||||
<el-button @click="showBatchAllocateDialog" size="small" type="primary" :loading="formLoading">一键分配
|
||||
</el-button>
|
||||
<el-button @click="doAllocateRecord" size="small" type="primary" :loading="formLoading">季度记录生成
|
||||
<el-button @click="showAwardAllocateDialog" size="small" type="primary" :loading="formLoading">
|
||||
新增评优奖励
|
||||
</el-button>
|
||||
<el-button @click="doAllocateRecord" size="small" type="primary" :loading="formLoading">分配记录生成
|
||||
</el-button>
|
||||
|
||||
<el-button @click="deleteAllocateRecord" size="small" type="danger" :loading="formLoading">重置季度记录
|
||||
<el-button @click="deleteAllocateRecord" size="small" type="danger" :loading="formLoading">重置分配记录
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%" row-key="id"
|
||||
@@ -118,17 +121,15 @@ layout("/layouts/platform.html"){
|
||||
</el-form-item>
|
||||
<el-form-item label="上传文件">
|
||||
<el-upload
|
||||
name="file"
|
||||
class="upload-demo"
|
||||
ref="importUploadRef"
|
||||
:limit="1"
|
||||
action="/platform/outlay/outlayManage/unionAllocate/readImportExcel"
|
||||
:on-success="onImportSuccess"
|
||||
:on-remove="onImportRemove"
|
||||
:before-upload="beforeImportUpload"
|
||||
:file-list="importFileList"
|
||||
drag>
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text">将Excel文件拖到此处,或<em>点击上传</em></div>
|
||||
:file-list="importFileList">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="导入预览" v-if="batchAllocateForm.importPreviewList.length > 0">
|
||||
@@ -152,6 +153,41 @@ layout("/layouts/platform.html"){
|
||||
<el-button type="primary" @click="doBatchAllocate" :loading="formLoading">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="新增评优奖励" :visible.sync="awardAllocateDialogVisible" width="520px">
|
||||
<el-form :model="awardAllocateForm" label-width="120px">
|
||||
<el-form-item label="年度">
|
||||
<el-date-picker
|
||||
placeholder="选择年度"
|
||||
style="width: 100%"
|
||||
type="year"
|
||||
v-model="awardAllocateForm.year"
|
||||
:clearable="false"
|
||||
value-format="yyyy">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属工会">
|
||||
<el-select placeholder="请选择所属工会" v-model="awardAllocateForm.unionId"
|
||||
style="width: 100%;"
|
||||
clearable
|
||||
filterable>
|
||||
<el-option v-for="item in unionList"
|
||||
:label="item.name"
|
||||
:key="item.id"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="评优奖励金额">
|
||||
<el-input-number v-model="awardAllocateForm.allocateMoney" :min="0" :precision="2"
|
||||
style="width: 100%" placeholder="请输入评优奖励金额">
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeAwardAllocateDialog">取 消</el-button>
|
||||
<el-button type="primary" @click="doAddAwardAllocate" :loading="formLoading">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
@@ -170,48 +206,62 @@ layout("/layouts/platform.html"){
|
||||
unionList: [],
|
||||
tableColumns: [
|
||||
{prop: 'year', label: '年度'},
|
||||
{prop: 'quarterly', label: '季度'},
|
||||
{prop: 'quarterly', label: '分配项目'},
|
||||
{prop: 'unionName', label: '工会名称'},
|
||||
{prop: 'allocateHeadMoney', label: '分配前额度'},
|
||||
{prop: 'allocateMoney', label: '分配额度'},
|
||||
],
|
||||
quarterlyList: [],
|
||||
periodList: [],
|
||||
batchAllocateDialogVisible: false,
|
||||
batchAllocateForm: {
|
||||
allocateMode: "uniform",
|
||||
allocateMoney: 0,
|
||||
importPreviewList: []
|
||||
},
|
||||
importFileList: []
|
||||
importFileList: [],
|
||||
awardAllocateDialogVisible: false,
|
||||
awardAllocateForm: {
|
||||
year: this.$moment().format("YYYY"),
|
||||
unionId: "",
|
||||
allocateMoney: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 确认提示文案优先展示页面当前筛选季度。
|
||||
* 未选择季度时再回退到系统当前自然季度,避免提示文案与用户当前查看条件不一致。
|
||||
* 确认提示文案优先展示页面当前筛选的分配项目名称。
|
||||
* 未选择分配项目时再回退到当前会费项目,避免提示文案与用户当前查看条件不一致。
|
||||
*/
|
||||
getPromptQuarter() {
|
||||
return this.pageForm.quarterly || this.$moment().quarter()
|
||||
getPromptProjectName() {
|
||||
return this.getProjectName(this.pageForm.quarterly || this.getCurrentFeeProject())
|
||||
},
|
||||
/**
|
||||
* 季度记录生成、重置记录都要按页面当前筛选的年度和季度执行。
|
||||
* 这里统一封装请求参数,避免前后端再次出现“提示季度”和“实际执行季度”不一致的问题。
|
||||
* 分配记录生成、重置记录都要按页面当前筛选的年度和分配项目执行。
|
||||
* quarterly 参数承载 OUTLAY_QUARTERLY 字典编码,例如 1-4月会费、5-8月会费、9-12月会费、评优奖励。
|
||||
*/
|
||||
getCurrentQuarterParams() {
|
||||
getCurrentProjectParams() {
|
||||
return {
|
||||
quarterly: this.pageForm.quarterly || this.$moment().quarter(),
|
||||
quarterly: this.pageForm.quarterly || this.getCurrentFeeProject(),
|
||||
year: this.pageForm.year
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 生成、重置、一键分配都只允许操作当前自然季度。
|
||||
* 这里统一做前端入口校验,避免同类判断分散在多个按钮方法里难维护。
|
||||
* 生成、重置、一键分配都只允许操作当前会费项目。
|
||||
* 当前会费项目按月份划分:1-4月会费、5-8月会费、9-12月会费。
|
||||
*/
|
||||
validateCurrentQuarterAction(actionName) {
|
||||
const currentQuarter = this.$moment().quarter()
|
||||
const selectedQuarter = Number(this.getCurrentQuarterParams().quarterly)
|
||||
if (selectedQuarter !== currentQuarter) {
|
||||
this.$message.warning('当前仅允许操作第' + currentQuarter + '季度' + actionName + ',请切换后再操作')
|
||||
getCurrentFeeProject() {
|
||||
return Math.floor(this.$moment().month() / 4) + 1
|
||||
},
|
||||
getProjectName(code) {
|
||||
const options = this.dict.type.OUTLAY_QUARTERLY || []
|
||||
const project = options.find((item) => String(item.code || item.value || item.dictValue) === String(code))
|
||||
return project ? (project.label || project.name || project.dictLabel || code) : code
|
||||
},
|
||||
validateCurrentProjectAction(actionName) {
|
||||
const currentProject = this.getCurrentFeeProject()
|
||||
const selectedProject = Number(this.getCurrentProjectParams().quarterly)
|
||||
if (selectedProject !== currentProject) {
|
||||
this.$message.warning('当前仅允许操作【' + this.getProjectName(currentProject) + '】' + actionName + ',请切换后再操作')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -237,7 +287,7 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
},
|
||||
deleteAllocateRecord() {
|
||||
if (!this.validateCurrentQuarterAction('记录重置')) {
|
||||
if (!this.validateCurrentProjectAction('记录重置')) {
|
||||
return
|
||||
}
|
||||
// 重置动作以当前列表是否已有记录为前置条件,避免用户在空列表场景下误操作。
|
||||
@@ -245,13 +295,13 @@ layout("/layouts/platform.html"){
|
||||
this.$message.warning('当前列表无可重置记录')
|
||||
return
|
||||
}
|
||||
this.$confirm('确定要重置【第' + this.getPromptQuarter() + '季度】的预算记录吗?', '提示', {
|
||||
this.$confirm('确定要重置【' + this.getPromptProjectName() + '】的预算记录吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.formLoading = true
|
||||
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/deleteAllocateRecord", this.getCurrentQuarterParams()).then((resp) => {
|
||||
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/deleteAllocateRecord", this.getCurrentProjectParams()).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.doSearch()
|
||||
@@ -262,16 +312,16 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
},
|
||||
doAllocateRecord() {
|
||||
if (!this.validateCurrentQuarterAction('记录生成')) {
|
||||
if (!this.validateCurrentProjectAction('记录生成')) {
|
||||
return
|
||||
}
|
||||
this.$confirm('确定要生成【第' + this.getPromptQuarter() + '季度】的预算记录吗?', '提示', {
|
||||
this.$confirm('确定要生成【' + this.getPromptProjectName() + '】的预算记录吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.formLoading = true
|
||||
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doAllocateRecord", this.getCurrentQuarterParams()).then((resp) => {
|
||||
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doAllocateRecord", this.getCurrentProjectParams()).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.doSearch()
|
||||
@@ -282,14 +332,14 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
},
|
||||
showBatchAllocateDialog() {
|
||||
if (!this.validateCurrentQuarterAction('一键分配')) {
|
||||
if (!this.validateCurrentProjectAction('一键分配')) {
|
||||
return
|
||||
}
|
||||
if (this.tableData.length === 0) {
|
||||
this.$message.warning('当前没有可分配的工会记录,请先生成季度记录')
|
||||
this.$message.warning('当前没有可分配的工会记录,请先生成分配记录')
|
||||
return
|
||||
}
|
||||
const currentParams = this.getCurrentQuarterParams()
|
||||
const currentParams = this.getCurrentProjectParams()
|
||||
const openDialog = () => {
|
||||
this.resetBatchAllocateForm()
|
||||
this.batchAllocateDialogVisible = true
|
||||
@@ -302,7 +352,7 @@ layout("/layouts/platform.html"){
|
||||
return
|
||||
}
|
||||
if (resp.data) {
|
||||
this.$confirm('温馨提示:当前季度已分配过额度,再次分配将覆盖本季度原有分配结果,是否继续?', '温馨提示', {
|
||||
this.$confirm('温馨提示:当前分配项目已分配过额度,再次分配将覆盖本项目原有分配结果,是否继续?', '温馨提示', {
|
||||
confirmButtonText: '继续',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
@@ -323,6 +373,46 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
this.importFileList = []
|
||||
},
|
||||
showAwardAllocateDialog() {
|
||||
this.$set(this.awardAllocateForm, "year", this.pageForm.year)
|
||||
this.$set(this.awardAllocateForm, "unionId", this.pageForm.unionId || "")
|
||||
this.$set(this.awardAllocateForm, "allocateMoney", 0)
|
||||
this.$set(this, "awardAllocateDialogVisible", true)
|
||||
},
|
||||
closeAwardAllocateDialog() {
|
||||
this.$set(this, "awardAllocateDialogVisible", false)
|
||||
},
|
||||
doAddAwardAllocate() {
|
||||
if (!this.awardAllocateForm.year) {
|
||||
this.$message.warning("请选择年度")
|
||||
return
|
||||
}
|
||||
if (!this.awardAllocateForm.unionId) {
|
||||
this.$message.warning("请选择所属工会")
|
||||
return
|
||||
}
|
||||
if (!this.awardAllocateForm.allocateMoney || this.awardAllocateForm.allocateMoney <= 0) {
|
||||
this.$message.warning("请输入有效的评优奖励金额")
|
||||
return
|
||||
}
|
||||
this.formLoading = true
|
||||
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doAddAwardAllocate", {
|
||||
year: this.awardAllocateForm.year,
|
||||
unionId: this.awardAllocateForm.unionId,
|
||||
allocateMoney: this.awardAllocateForm.allocateMoney
|
||||
}).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.closeAwardAllocateDialog()
|
||||
this.$set(this.pageForm, "year", this.awardAllocateForm.year)
|
||||
this.$set(this.pageForm, "quarterly", "4")
|
||||
this.$set(this.pageForm, "unionId", this.awardAllocateForm.unionId)
|
||||
this.doSearch()
|
||||
}
|
||||
}).finally(() => {
|
||||
this.formLoading = false
|
||||
})
|
||||
},
|
||||
downloadImportTemplate() {
|
||||
this.$downLoad("/platform/outlay/outlayManage/unionAllocate/downloadImportTemplate")
|
||||
},
|
||||
@@ -349,7 +439,7 @@ layout("/layouts/platform.html"){
|
||||
this.$set(this.batchAllocateForm, "importPreviewList", [])
|
||||
},
|
||||
doBatchAllocate() {
|
||||
const currentParams = this.getCurrentQuarterParams()
|
||||
const currentParams = this.getCurrentProjectParams()
|
||||
if (this.batchAllocateForm.allocateMode === "uniform") {
|
||||
if (!this.batchAllocateForm.allocateMoney || this.batchAllocateForm.allocateMoney <= 0) {
|
||||
this.$message.warning('请输入有效的分配额度')
|
||||
@@ -401,8 +491,8 @@ layout("/layouts/platform.html"){
|
||||
this.unionList = data
|
||||
})
|
||||
this.$businessTool.getDictOptions("OUTLAY_QUARTERLY").then((data) => {
|
||||
let quarter = this.$moment().quarter();
|
||||
this.$set(this.pageForm, "quarterly", data[quarter - 1].code)
|
||||
let project = this.getCurrentFeeProject();
|
||||
this.$set(this.pageForm, "quarterly", data[project - 1].code)
|
||||
this.pageData()
|
||||
})
|
||||
|
||||
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
|
||||
<div class="platform" id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度">
|
||||
<el-date-picker
|
||||
@change="doSearch"
|
||||
placeholder="选择年度"
|
||||
style="width: 100%" type="year"
|
||||
v-model="pageForm.year"
|
||||
:clearable="false"
|
||||
value-format="yyyy">
|
||||
</el-date-picker>
|
||||
</search-item>
|
||||
|
||||
<search-item label="所属工会" v-if="$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN'])">
|
||||
<el-select placeholder="请选择所属工会" v-model="pageForm.unionId"
|
||||
style="width: 100%;"
|
||||
clearable
|
||||
@change="doSearch"
|
||||
filterable>
|
||||
<el-option v-for="item in unions"
|
||||
:label="item.name"
|
||||
:key="item.id"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="经费收支使用情况表">
|
||||
<el-button size="mini" type="primary" @click="doExport">导出</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%" row-key="unionId"
|
||||
v-loading="tableLoading" :size="tableSize" class="vi-table"
|
||||
border>
|
||||
<el-table-column
|
||||
show-overflow-tooltip
|
||||
align="center"
|
||||
header-align="center"
|
||||
label="单位"
|
||||
prop="unionName"
|
||||
min-width="140"></el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
label="年初数"
|
||||
prop="beginMoney"
|
||||
min-width="120">
|
||||
<template v-slot="{row}">
|
||||
{{formatMoney(row.beginMoney)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" :label="pageForm.year + '年会费收入'">
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
label="1-4月会费"
|
||||
prop="feeJanApr"
|
||||
min-width="120">
|
||||
<template v-slot="{row}">
|
||||
{{formatMoney(row.feeJanApr)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
label="5-8月会费"
|
||||
prop="feeMayAug"
|
||||
min-width="120">
|
||||
<template v-slot="{row}">
|
||||
{{formatMoney(row.feeMayAug)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
label="9-12月会费"
|
||||
prop="feeSepDec"
|
||||
min-width="120">
|
||||
<template v-slot="{row}">
|
||||
{{formatMoney(row.feeSepDec)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
label="评优奖励"
|
||||
prop="awardMoney"
|
||||
min-width="120">
|
||||
<template v-slot="{row}">
|
||||
{{formatMoney(row.awardMoney)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
label="1-12月支出"
|
||||
prop="usedMoney"
|
||||
min-width="120">
|
||||
<template v-slot="{row}">
|
||||
{{formatMoney(row.usedMoney)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
header-align="center"
|
||||
label="经费余额"
|
||||
prop="remainMoney"
|
||||
min-width="120">
|
||||
<template v-slot="{row}">
|
||||
{{formatMoney(row.remainMoney)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const vue = new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
year: this.$moment().format("YYYY"),
|
||||
unionId: ""
|
||||
},
|
||||
unions: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatMoney(value) {
|
||||
return Number(value || 0).toFixed(2)
|
||||
},
|
||||
doExport() {
|
||||
const unionId = this.pageForm.unionId || ""
|
||||
window.open(loc() + "/doExport?year=" + this.pageForm.year + "&unionId=" + unionId)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$businessTool.listUnion().then((data) => {
|
||||
this.unions = data
|
||||
})
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+2
-2
@@ -4,10 +4,10 @@ let OUTLAY_MANAGE_UNION_QUARTERLY_ALLOCATE = {
|
||||
`
|
||||
<div>
|
||||
<template>
|
||||
<table-tool label="季度分配记录"></table-tool>
|
||||
<table-tool label="分配记录"></table-tool>
|
||||
<el-table :data="tableData" style="width: 100%" row-key="id" class="vi-table">
|
||||
<el-table-column type="index" label="序号" width="80px"></el-table-column>
|
||||
<el-table-column label="季度" prop="quarterly">
|
||||
<el-table-column label="分配项目" prop="quarterly">
|
||||
<template v-slot="{row}">
|
||||
<dict-tag :options="dict.type.OUTLAY_QUARTERLY"
|
||||
:value="row.quarterly"></dict-tag>
|
||||
|
||||
@@ -175,9 +175,9 @@ const apply = {
|
||||
<el-col :span="24">
|
||||
<el-form-item label="批量预约">
|
||||
<div style="display: flex; align-items: flex-start; column-gap: 12px; flex-wrap: wrap; line-height: 1.7;">
|
||||
<el-checkbox v-model="yearlyReserve">预约本年后续每周同一时段</el-checkbox>
|
||||
<el-checkbox v-model="yearlyReserve">预约本月后续每周同一时段</el-checkbox>
|
||||
<span style="color: #909399;">
|
||||
例如先选某个周一 09:00-11:00,勾选后会自动预约本年剩余所有周一的这个时段。
|
||||
例如先选某个周一 09:00-11:00,勾选后会自动预约本月剩余所有周一的这个时段。
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="yearlyReserve" style="margin-top: 10px; max-width: 320px;">
|
||||
@@ -222,6 +222,8 @@ const apply = {
|
||||
filterHolidays: false,
|
||||
holidayList: [],
|
||||
notApplyTimeList: [],
|
||||
termStartDate: '',
|
||||
termEndDate: '',
|
||||
},
|
||||
availabilityData: {
|
||||
date: '',
|
||||
@@ -342,7 +344,10 @@ const apply = {
|
||||
if (!this.formData.reserveStartTime) {
|
||||
return false
|
||||
}
|
||||
return this.$moment(time).format('YYYY-MM-DD') < this.formData.reserveStartTime.slice(0, 10)
|
||||
const targetDay = this.$moment(time).format('YYYY-MM-DD')
|
||||
const startDay = this.formData.reserveStartTime.slice(0, 10)
|
||||
const monthEndDay = this.$moment(this.formData.reserveStartTime).endOf('month').format('YYYY-MM-DD')
|
||||
return targetDay < startDay || targetDay > monthEndDay
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -395,10 +400,10 @@ const apply = {
|
||||
return ''
|
||||
}
|
||||
if (!this.formData.reserveStartTime || !this.formData.reserveEndTime) {
|
||||
return '请先选择开始和结束时间后,再批量预约本年同星期时段'
|
||||
return '请先选择开始和结束时间后,再批量预约本月同星期时段'
|
||||
}
|
||||
if (!this.yearlyReserveDates.length) {
|
||||
return '当前时间段无法生成本年批量预约日期'
|
||||
return '当前时间段无法生成本月批量预约日期'
|
||||
}
|
||||
return '将从 ' + this.yearlyReserveDates[0] + ' 开始,自动预约到 ' + this.yearlyReserveDates[this.yearlyReserveDates.length - 1] + ',共 ' + this.yearlyReserveDates.length + ' 个时段'
|
||||
},
|
||||
@@ -496,6 +501,10 @@ const apply = {
|
||||
}
|
||||
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate < this.formData.reserveStartTime.slice(0, 10)) {
|
||||
this.$set(this.formData, 'yearlyReserveEndDate', defaultDate)
|
||||
return
|
||||
}
|
||||
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > defaultDate) {
|
||||
this.$set(this.formData, 'yearlyReserveEndDate', defaultDate)
|
||||
}
|
||||
},
|
||||
getInitialScheduleDate() {
|
||||
@@ -513,6 +522,8 @@ const apply = {
|
||||
filterHolidays: !!this.row.filterHolidays,
|
||||
holidayList: [],
|
||||
notApplyTimeList: Array.isArray(this.row.notApplyTimeList) ? this.row.notApplyTimeList : [],
|
||||
termStartDate: this.row.termStartDate || '',
|
||||
termEndDate: this.row.termEndDate || '',
|
||||
}
|
||||
try {
|
||||
const res = await this.$axios.post('/platform/siteCug/apply/timeLimitConfig', {
|
||||
@@ -523,6 +534,8 @@ const apply = {
|
||||
filterHolidays: !!res.data.filterHolidays,
|
||||
holidayList: Array.isArray(res.data.holidayList) ? res.data.holidayList : [],
|
||||
notApplyTimeList: Array.isArray(res.data.notApplyTimeList) ? res.data.notApplyTimeList : [],
|
||||
termStartDate: res.data.termStartDate || '',
|
||||
termEndDate: res.data.termEndDate || '',
|
||||
}
|
||||
} else {
|
||||
this.timeLimitConfig = fallback
|
||||
@@ -599,6 +612,9 @@ const apply = {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.formRef?.clearValidate(['applyUnionName', 'clubId'])
|
||||
})
|
||||
this.pickerRefreshKey += 1
|
||||
this.scheduleDate = this.getInitialScheduleDate()
|
||||
await this.queryAvailability(this.scheduleDate)
|
||||
},
|
||||
async loadManagedClubs() {
|
||||
try {
|
||||
@@ -671,6 +687,11 @@ const apply = {
|
||||
if (currentDay.day() === 0 || currentDay.day() === 6) {
|
||||
return true
|
||||
}
|
||||
if (this.formData.reserveType === 'union' && this.timeLimitConfig.termStartDate && this.timeLimitConfig.termEndDate) {
|
||||
if (currentDay.isBefore(this.timeLimitConfig.termStartDate) || currentDay.isAfter(this.timeLimitConfig.termEndDate)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return this.timeLimitConfig.filterHolidays && this.timeLimitConfig.holidayList.includes(day)
|
||||
},
|
||||
normalizeTime(timeStr) {
|
||||
@@ -1006,12 +1027,16 @@ const apply = {
|
||||
this.$message.warning('批量预约截止日期不能早于开始日期')
|
||||
return false
|
||||
}
|
||||
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > this.$moment(this.formData.reserveStartTime).endOf('month').format('YYYY-MM-DD')) {
|
||||
this.$message.warning('批量预约截止日期不能超过预约开始时间所在月份')
|
||||
return false
|
||||
}
|
||||
if (!this.yearlyReserveDates.length) {
|
||||
this.$message.warning('当前选择的时间段在截止日期内无法生成可批量预约的日期')
|
||||
return false
|
||||
}
|
||||
if (!this.yearlyReserveDates.length) {
|
||||
this.$message.warning('当前选择的时间段无法生成本年批量预约日期')
|
||||
this.$message.warning('当前选择的时间段无法生成本月批量预约日期')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -1024,7 +1049,7 @@ const apply = {
|
||||
if (!this.yearlyReserve) {
|
||||
return baseText + ',是否确定提交预约?'
|
||||
}
|
||||
return baseText + '。系统将继续预约本年后续 ' + this.yearlyReserveDates.length + ' 个同星期时段,是否确定提交?'
|
||||
return baseText + '。系统将继续预约本月后续 ' + this.yearlyReserveDates.length + ' 个同星期时段,是否确定提交?'
|
||||
},
|
||||
validateYearlyReserve() {
|
||||
if (!this.yearlyReserve) {
|
||||
@@ -1038,6 +1063,10 @@ const apply = {
|
||||
this.$message.warning('批量预约截止日期不能早于开始日期')
|
||||
return false
|
||||
}
|
||||
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > this.$moment(this.formData.reserveStartTime).endOf('month').format('YYYY-MM-DD')) {
|
||||
this.$message.warning('批量预约截止日期不能超过预约开始时间所在月份')
|
||||
return false
|
||||
}
|
||||
if (!this.yearlyReserveDates.length) {
|
||||
this.$message.warning('当前选择的时间段在截止日期内无法生成可批量预约的日期')
|
||||
return false
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
<el-tab-pane label="设置场地" name="siteSetting">
|
||||
<el-row :gutter="20" type="flex">
|
||||
<el-col :span="12">
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="state" label="开启状态">
|
||||
<el-radio-group v-model="formData.state" size="medium">
|
||||
<el-radio-button :label="true">开启</el-radio-button>
|
||||
@@ -89,7 +89,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="sexLimit" label="性别限制">
|
||||
<el-radio-group v-model="formData.sexLimit" size="medium">
|
||||
<el-radio-button :label="0">不限制</el-radio-button>
|
||||
@@ -98,10 +98,23 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="本学期时间">
|
||||
<el-date-picker
|
||||
v-model="formData.termDateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
style="width: 100%">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20" type="flex">
|
||||
<el-col :span="12">
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="reserveTimeType" label="预约时间段类型">
|
||||
<el-radio-group v-model="formData.reserveTimeType" @change="handleReserveTimeTypeChange" size="medium">
|
||||
<el-radio-button :label="1">分段预约</el-radio-button>
|
||||
@@ -109,7 +122,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="filterHolidays" label="排除节假日">
|
||||
<el-radio-group v-model="formData.filterHolidays" size="medium">
|
||||
<el-radio-button :label="true">是</el-radio-button>
|
||||
@@ -117,7 +130,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="禁用时间">
|
||||
<el-button type="primary" @click="openSetUpTime" size="small">点击设置禁用时间</el-button>
|
||||
<span style="color: #c64120">您已设置{{ formData.notApplyTimeList ? formData.notApplyTimeList.length : 0 }}个禁用时间</span>
|
||||
@@ -125,6 +138,33 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20" type="flex">
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="unionYearReserveLimit" label="分工会每年预约次数">
|
||||
<el-input-number
|
||||
v-model="formData.unionYearReserveLimit"
|
||||
:min="1"
|
||||
:step="1"
|
||||
:precision="0"
|
||||
controls-position="right"
|
||||
style="width: 160px">
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="clubWeekReserveLimit" label="社团每周预约次数">
|
||||
<el-input-number
|
||||
v-model="formData.clubWeekReserveLimit"
|
||||
:min="1"
|
||||
:step="1"
|
||||
:precision="0"
|
||||
controls-position="right"
|
||||
style="width: 160px">
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider content-position="left">场次信息</el-divider>
|
||||
|
||||
<div v-if="formData.reserveTimeType === 1">
|
||||
@@ -325,6 +365,9 @@
|
||||
formData: {
|
||||
state: true,
|
||||
sexLimit: 0,
|
||||
termDateRange: [],
|
||||
unionYearReserveLimit: 2,
|
||||
clubWeekReserveLimit: 2,
|
||||
filterHolidays: false,
|
||||
reserveTimeType: 1,
|
||||
openHours: [{ startTime: '', endTime: '', timeUnit: 30 }],
|
||||
@@ -344,6 +387,8 @@
|
||||
maxNum: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
typeId: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
sexLimit: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
unionYearReserveLimit: [{required: true, type: 'number', min: 1, message: '必填且必须大于0', trigger: ['blur', 'change']}],
|
||||
clubWeekReserveLimit: [{required: true, type: 'number', min: 1, message: '必填且必须大于0', trigger: ['blur', 'change']}],
|
||||
filterHolidays: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
state: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
reserveTimeType: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
@@ -408,6 +453,14 @@
|
||||
} else {
|
||||
submitData.openHours = [clone(this.fullDayOpenHourCache || { startTime: '', endTime: '', timeUnit: 60 })]
|
||||
}
|
||||
if (Array.isArray(submitData.termDateRange) && submitData.termDateRange.length === 2) {
|
||||
submitData.termStartDate = submitData.termDateRange[0]
|
||||
submitData.termEndDate = submitData.termDateRange[1]
|
||||
} else {
|
||||
submitData.termStartDate = ''
|
||||
submitData.termEndDate = ''
|
||||
}
|
||||
delete submitData.termDateRange
|
||||
return submitData
|
||||
},
|
||||
initOpenHoursCache() {
|
||||
@@ -654,11 +707,19 @@
|
||||
if (!this.formData.fullDayOpenHour) {
|
||||
this.$set(this.formData, 'fullDayOpenHour', { startTime: '', endTime: '', timeUnit: 30 })
|
||||
}
|
||||
if (this.formData.termStartDate && this.formData.termEndDate) {
|
||||
this.$set(this.formData, 'termDateRange', [this.formData.termStartDate, this.formData.termEndDate])
|
||||
} else {
|
||||
this.$set(this.formData, 'termDateRange', [])
|
||||
}
|
||||
this.initOpenHoursCache()
|
||||
} else {
|
||||
this.formData = {
|
||||
state: true,
|
||||
sexLimit: 0,
|
||||
termDateRange: [],
|
||||
unionYearReserveLimit: 2,
|
||||
clubWeekReserveLimit: 2,
|
||||
filterHolidays: false,
|
||||
reserveTimeType: 1,
|
||||
openHours: [{ startTime: '', endTime: '', timeUnit: 30 }],
|
||||
@@ -698,6 +759,11 @@
|
||||
if (!this.formData.fullDayOpenHour) {
|
||||
this.$set(this.formData, 'fullDayOpenHour', { startTime: '', endTime: '', timeUnit: 30 })
|
||||
}
|
||||
if (this.formData.termStartDate && this.formData.termEndDate) {
|
||||
this.$set(this.formData, 'termDateRange', [this.formData.termStartDate, this.formData.termEndDate])
|
||||
} else {
|
||||
this.$set(this.formData, 'termDateRange', [])
|
||||
}
|
||||
this.initOpenHoursCache()
|
||||
}
|
||||
if (!stayOnPage) {
|
||||
|
||||
@@ -9,9 +9,7 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
|
||||
.record-batch-empty {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.record-batch-child-row {
|
||||
@@ -31,6 +29,13 @@ layout("/layouts/platform.html"){
|
||||
height: 1px;
|
||||
background: #c8d3df;
|
||||
}
|
||||
|
||||
.record-site-name-cell {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
max-width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
@@ -113,25 +118,16 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<el-card shadow="never">
|
||||
<table-tool label="申请列表">
|
||||
<el-button v-if="$auth.hasRole('SYSADMIN')" type="primary" size="small" @click="openBatchOccupyDialog">占用</el-button>
|
||||
<el-button type="primary" size="small" @click="doExport">导出表格</el-button>
|
||||
</table-tool>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
:row-class-name="tableRowClassName"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="pageOrder"
|
||||
style="width: 100%">
|
||||
<el-table-column label="" width="54" align="center" header-align="center">
|
||||
<template v-slot="{ row }">
|
||||
<el-button
|
||||
v-if="row._hasFoldChildren"
|
||||
class="record-batch-toggle"
|
||||
type="text"
|
||||
@click="toggleBatchGroup(row)">
|
||||
<i :class="row._expanded ? 'el-icon-caret-bottom' : 'el-icon-caret-right'"></i>
|
||||
</el-button>
|
||||
<span v-else class="record-batch-empty"></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="$auth.hasRole('SYSADMIN')" type="selection" width="48" :selectable="canSelectOccupy"></el-table-column>
|
||||
<el-table-column type="index" width="50" label="序号" :index="indexMethod"></el-table-column>
|
||||
<el-table-column
|
||||
v-for="column in tableColumns"
|
||||
@@ -144,8 +140,18 @@ layout("/layouts/platform.html"){
|
||||
header-align="center"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot="{ row }" v-if="column.prop === 'siteName'">
|
||||
<span v-if="row._isBatchChild" class="record-batch-child-label">{{ row.siteName }}</span>
|
||||
<span v-else>{{ row.siteName }}</span>
|
||||
<span class="record-site-name-cell">
|
||||
<el-button
|
||||
v-if="row._hasFoldChildren"
|
||||
class="record-batch-toggle"
|
||||
type="text"
|
||||
@click="toggleBatchGroup(row)">
|
||||
<i :class="row._expanded ? 'el-icon-caret-bottom' : 'el-icon-caret-right'"></i>
|
||||
</el-button>
|
||||
<span v-else class="record-batch-empty"></span>
|
||||
<span v-if="row._isBatchChild" class="record-batch-child-label">{{ row.siteName }}</span>
|
||||
<span v-else>{{ row.siteName }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template v-slot="{ row }" v-else-if="column.prop === 'reserveTargetName'">
|
||||
<span>{{ row.reserveType === 'club' ? (row.clubName || '-') : (row.applyUnionName || '-') }}</span>
|
||||
@@ -154,7 +160,7 @@ layout("/layouts/platform.html"){
|
||||
<span>{{ normalizeBatchFlag(row) ? '是' : '否' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" fixed="right" width="180">
|
||||
<el-table-column label="操作" fixed="right" width="150">
|
||||
<template v-slot="{ row }">
|
||||
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
|
||||
<el-button @click="onDelete(row.id)" size="mini" type="danger">删除</el-button>
|
||||
@@ -163,6 +169,32 @@ layout("/layouts/platform.html"){
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<el-dialog title="占用预约" :visible.sync="occupyDialogVisible" width="520px" append-to-body :close-on-click-modal="false">
|
||||
<el-form label-width="90px">
|
||||
<el-form-item label="预约信息">
|
||||
<div v-if="occupyForm.batch">已选择 {{ occupyForm.count }} 条预约</div>
|
||||
<template v-else>
|
||||
<div>{{ occupyForm.siteName || '-' }}</div>
|
||||
<div>{{ occupyForm.applyUserName || '-' }}:{{ occupyForm.reserveStartTime }} 至 {{ occupyForm.reserveEndTime }}</div>
|
||||
</template>
|
||||
</el-form-item>
|
||||
<el-form-item label="通知内容" required>
|
||||
<el-input
|
||||
type="textarea"
|
||||
:rows="6"
|
||||
maxlength="1000"
|
||||
show-word-limit
|
||||
v-model="occupyForm.message"
|
||||
placeholder="请输入发送给预约人的通知内容">
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="closeOccupyDialog">取消</el-button>
|
||||
<el-button type="primary" :loading="occupySubmitting" @click="submitOccupy">确定占用</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<template #edit>
|
||||
@@ -195,6 +227,20 @@ layout("/layouts/platform.html"){
|
||||
siteOptions: [],
|
||||
rawTableData: [],
|
||||
expandedBatchKeys: {},
|
||||
selectedOccupyRows: [],
|
||||
occupyDialogVisible: false,
|
||||
occupySubmitting: false,
|
||||
occupyForm: {
|
||||
id: '',
|
||||
ids: '',
|
||||
batch: false,
|
||||
count: 0,
|
||||
siteName: '',
|
||||
applyUserName: '',
|
||||
reserveStartTime: '',
|
||||
reserveEndTime: '',
|
||||
message: '',
|
||||
},
|
||||
tableColumns: [
|
||||
{ prop: 'siteName', label: '场地名称', sortable: 'custom' },
|
||||
{ prop: 'applyUserName', label: '预约人', sortable: 'custom' },
|
||||
@@ -267,6 +313,99 @@ layout("/layouts/platform.html"){
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
})
|
||||
},
|
||||
canSelectOccupy(row) {
|
||||
return this.canOccupy(row)
|
||||
},
|
||||
handleSelectionChange(rows) {
|
||||
this.$set(this, 'selectedOccupyRows', rows || [])
|
||||
},
|
||||
canOccupy(row) {
|
||||
if (!row || !row.reserveStartTime) {
|
||||
return false
|
||||
}
|
||||
const currentUserId = (this.$store.state.user && this.$store.state.user.id) || ''
|
||||
if (row.occupyUserId && row.occupyUserId !== currentUserId) {
|
||||
return false
|
||||
}
|
||||
return Number(row.instanceState) === 20 && this.$moment(row.reserveStartTime).isAfter(this.$moment())
|
||||
},
|
||||
buildOccupyMessage(row) {
|
||||
return '您预约的' + (row.siteName || '场地') + '(' + row.reserveStartTime + ' 至 ' + row.reserveEndTime + ')因场地安排需要被占用,请您知悉并重新协调预约时间。'
|
||||
},
|
||||
openOccupyDialog(row) {
|
||||
const occupyForm = {
|
||||
id: row.id || '',
|
||||
ids: row.id || '',
|
||||
batch: false,
|
||||
count: 1,
|
||||
siteName: row.siteName || '',
|
||||
applyUserName: row.applyUserName || '',
|
||||
reserveStartTime: row.reserveStartTime || '',
|
||||
reserveEndTime: row.reserveEndTime || '',
|
||||
message: row.occupyMessage || this.buildOccupyMessage(row),
|
||||
}
|
||||
Object.keys(occupyForm).forEach(key => {
|
||||
this.$set(this.occupyForm, key, occupyForm[key])
|
||||
})
|
||||
this.$set(this, 'occupyDialogVisible', true)
|
||||
},
|
||||
openBatchOccupyDialog() {
|
||||
if (!this.selectedOccupyRows || this.selectedOccupyRows.length === 0) {
|
||||
this.$message.warning('请选择需要占用的预约')
|
||||
return
|
||||
}
|
||||
const ids = this.selectedOccupyRows.map(row => row.id).filter(id => !!id)
|
||||
if (ids.length === 0) {
|
||||
this.$message.warning('请选择需要占用的预约')
|
||||
return
|
||||
}
|
||||
const occupyForm = {
|
||||
id: '',
|
||||
ids: ids.join(','),
|
||||
batch: true,
|
||||
count: ids.length,
|
||||
siteName: '',
|
||||
applyUserName: '',
|
||||
reserveStartTime: '',
|
||||
reserveEndTime: '',
|
||||
message: '您预约的场地因场地安排需要被占用,请您知悉并重新协调预约时间。',
|
||||
}
|
||||
Object.keys(occupyForm).forEach(key => {
|
||||
this.$set(this.occupyForm, key, occupyForm[key])
|
||||
})
|
||||
this.$set(this, 'occupyDialogVisible', true)
|
||||
},
|
||||
closeOccupyDialog() {
|
||||
this.$set(this, 'occupyDialogVisible', false)
|
||||
},
|
||||
async submitOccupy() {
|
||||
if (!this.occupyForm.message || !this.occupyForm.message.trim()) {
|
||||
this.$message.warning('请填写通知内容')
|
||||
return
|
||||
}
|
||||
this.$set(this, 'occupySubmitting', true)
|
||||
try {
|
||||
const url = this.occupyForm.batch ? '/platform/siteCug/record/occupyBatch' : '/platform/siteCug/record/occupy'
|
||||
const params = {
|
||||
message: this.occupyForm.message,
|
||||
}
|
||||
if (this.occupyForm.batch) {
|
||||
this.$set(params, 'ids', this.occupyForm.ids)
|
||||
} else {
|
||||
this.$set(params, 'id', this.occupyForm.id)
|
||||
}
|
||||
const res = await this.$axios.post(url, params)
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg || '占用成功')
|
||||
this.closeOccupyDialog()
|
||||
window.location.href = '/platform/siteCug/apply'
|
||||
} else {
|
||||
this.$message.warning(res.msg || '占用失败')
|
||||
}
|
||||
} finally {
|
||||
this.$set(this, 'occupySubmitting', false)
|
||||
}
|
||||
},
|
||||
onDelete(id) {
|
||||
this.$confirm('您确定要删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
@@ -299,6 +438,7 @@ layout("/layouts/platform.html"){
|
||||
if (res.code === 0) {
|
||||
this.rawTableData = Array.isArray(res.data.list) ? res.data.list : []
|
||||
this.tableData = this.buildTableData(this.rawTableData)
|
||||
this.$set(this, 'selectedOccupyRows', [])
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
}
|
||||
})
|
||||
|
||||
+2
-2
@@ -288,7 +288,7 @@ layout("/layouts/platform.html"){
|
||||
return
|
||||
}
|
||||
const message = this.formData.yearlyBatch
|
||||
? ('该记录属于“预约本年”批量预约,提交后将一并审核同批次的 ' + (this.formData.batchAuditCount || 0) + ' 条预约记录,是否继续?')
|
||||
? ('该记录属于“预约本月”批量预约,提交后将一并审核同批次的 ' + (this.formData.batchAuditCount || 0) + ' 条预约记录,是否继续?')
|
||||
: '您确定要提交吗?'
|
||||
this.$confirm(message, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
@@ -317,7 +317,7 @@ layout("/layouts/platform.html"){
|
||||
return
|
||||
}
|
||||
const message = this.normalizeBatchFlag(row)
|
||||
? ('该记录属于“预约本年”批量预约,撤回后将一并撤回同批次的 ' + (row.batchAuditCount || row._batchCount || 0) + ' 条审核任务,是否继续?')
|
||||
? ('该记录属于“预约本月”批量预约,撤回后将一并撤回同批次的 ' + (row.batchAuditCount || row._batchCount || 0) + ' 条审核任务,是否继续?')
|
||||
: '您确定要撤回吗?'
|
||||
this.$confirm(message, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
|
||||
+773
-472
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -47,7 +47,7 @@ layout("/layouts/platform.html"){
|
||||
<el-card shadow="never">
|
||||
<table-tool label="申请列表">
|
||||
<el-button type="primary" size="small" @click="exportSkr">导出收款人名册</el-button>
|
||||
<!-- <el-button @click="onExport" icon="el-icon-s-promotion" type="primary" size="small">导出</el-button>-->
|
||||
<el-button @click="onExport" icon="el-icon-s-promotion" type="primary" size="small">导出表格</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
|
||||
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
|
||||
@@ -89,7 +89,7 @@ layout("/layouts/platform.html"){
|
||||
<el-table-column label="操作" fixed="right" width="350px">
|
||||
<template slot-scope="{row}">
|
||||
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
|
||||
<el-button v-if="isAdmin" @click="openEdit(row)" size="mini" type="primary">实际金额</el-button>
|
||||
<el-button v-if="isAdmin && row.stateId == 3" @click="openEdit(row)" size="mini" type="primary">实际金额</el-button>
|
||||
<el-button v-if="row.stateId == 3" @click="doPrint(row)" size="mini" type="primary">打印</el-button>
|
||||
<el-button v-if="$auth.hasRole('SYSADMIN')" @click="onDelete(row.id)" size="mini" type="danger">删除</el-button>
|
||||
</template>
|
||||
|
||||
@@ -8,25 +8,19 @@ const unionReimburseInfo = {
|
||||
|
||||
<el-tabs v-model="activeTabName" style="margin-top: 10px;">
|
||||
<el-tab-pane label="申请基本信息" name="basic">
|
||||
<el-descriptions :column="2" border class="flow-task-form">
|
||||
<el-descriptions-item label="经费来源" :span="2">
|
||||
<el-descriptions :column="3" border class="flow-task-form">
|
||||
<el-descriptions-item label="经费来源" :span="3">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_FUND_SOURCE"
|
||||
:value="viewData.reimburseFundSource">
|
||||
</dict-tag>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="报销项目" :span="2">
|
||||
<el-descriptions-item label="报销项目" :span="3">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
|
||||
:value="viewData.reimburseProject">
|
||||
</dict-tag>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="支付方式">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_PAYMENT_WAY"
|
||||
:value="viewData.paymentWay">
|
||||
</dict-tag>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="经办人">{{viewData.userName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="单位">{{viewData.unitName}}</el-descriptions-item>
|
||||
@@ -44,20 +38,45 @@ const unionReimburseInfo = {
|
||||
<span>{{ viewData.mobile }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="付款人" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
|
||||
<span>{{ viewData.payerName }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="户名" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
|
||||
<span>{{ viewData.bankUserName }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="开户行" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
|
||||
<span>{{ viewData.bankOfDeposit }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="银行卡号" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
|
||||
<span>{{ viewData.bankCardNumber }}</span>
|
||||
<el-descriptions-item label="支付信息" :span="3">
|
||||
<el-table :data="paymentInfoRows" border empty-text="暂无支付信息" style="width: 100%">
|
||||
<el-table-column label="支付方式" min-width="140">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_PAYMENT_WAY"
|
||||
:value="scope.row.paymentWay">
|
||||
</dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="金额" min-width="120">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ formatMoney(scope.row.money) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="付款人" min-width="160">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">{{ scope.row.payerName }}</span>
|
||||
<span v-else>无需填写</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="户名" min-width="160">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">{{ scope.row.bankUserName }}</span>
|
||||
<span v-else>无需填写</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开户行" min-width="200">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">{{ scope.row.bankOfDeposit }}</span>
|
||||
<span v-else>无需填写</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="银行卡号" min-width="200">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">{{ scope.row.bankCardNumber }}</span>
|
||||
<span v-else>无需填写</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="慰问对象" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
|
||||
@@ -159,20 +178,20 @@ const unionReimburseInfo = {
|
||||
<span>{{ viewData.condolenceRelationship }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="参加随行人员" :span="2"
|
||||
<el-descriptions-item label="参加随行人员" :span="3"
|
||||
v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
|
||||
<span>{{ viewData.participants }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="报销事由" :span="2" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
|
||||
<el-descriptions-item label="报销事由" :span="3" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
|
||||
<span>{{ viewData.paymentNotes }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="备注" :span="2" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
|
||||
<el-descriptions-item label="备注" :span="3" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
|
||||
<span>{{ viewData.notes }}</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="附件" :span="2">
|
||||
<el-descriptions-item label="附件" :span="3">
|
||||
<file-preview v-if="viewData.files && viewData.files.length > 0"
|
||||
:files="viewData.files"
|
||||
complete_result></file-preview>
|
||||
@@ -285,7 +304,8 @@ const unionReimburseInfo = {
|
||||
visible: false,
|
||||
viewData: {
|
||||
files: [],
|
||||
invoiceDetails: []
|
||||
invoiceDetails: [],
|
||||
paymentDetails: []
|
||||
},
|
||||
typeName: '',
|
||||
row: null
|
||||
@@ -294,6 +314,9 @@ const unionReimburseInfo = {
|
||||
computed: {
|
||||
showInvoiceTab() {
|
||||
return !!this.viewData.reimburseProject
|
||||
},
|
||||
paymentInfoRows() {
|
||||
return this.viewData.paymentDetails || []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -317,7 +340,8 @@ const unionReimburseInfo = {
|
||||
buildViewData(data) {
|
||||
const viewData = Object.assign({
|
||||
files: [],
|
||||
invoiceDetails: []
|
||||
invoiceDetails: [],
|
||||
paymentDetails: []
|
||||
}, data || {})
|
||||
if (!Array.isArray(viewData.files)) {
|
||||
viewData.files = []
|
||||
@@ -325,8 +349,32 @@ const unionReimburseInfo = {
|
||||
if (!Array.isArray(viewData.invoiceDetails)) {
|
||||
viewData.invoiceDetails = []
|
||||
}
|
||||
const hasLegacyPayment = viewData.paymentWay || viewData.payer || viewData.bankUserName || viewData.bankCardNumber || viewData.bankOfDeposit
|
||||
if (Array.isArray(viewData.paymentDetails) && viewData.paymentDetails.length > 0) {
|
||||
viewData.paymentDetails = viewData.paymentDetails.map(item => this.buildPaymentDetail(item))
|
||||
} else {
|
||||
viewData.paymentDetails = hasLegacyPayment ? [this.buildPaymentDetail({
|
||||
paymentWay: viewData.paymentWay,
|
||||
money: viewData.money,
|
||||
payerName: viewData.payerName,
|
||||
bankUserName: viewData.bankUserName,
|
||||
bankOfDeposit: viewData.bankOfDeposit,
|
||||
bankCardNumber: viewData.bankCardNumber
|
||||
})] : []
|
||||
}
|
||||
return viewData
|
||||
},
|
||||
buildPaymentDetail(detail) {
|
||||
const currentDetail = detail || {}
|
||||
return {
|
||||
paymentWay: currentDetail.paymentWay || "",
|
||||
money: currentDetail.money || "",
|
||||
payerName: currentDetail.payerName || "",
|
||||
bankUserName: currentDetail.bankUserName || "",
|
||||
bankOfDeposit: currentDetail.bankOfDeposit || "",
|
||||
bankCardNumber: currentDetail.bankCardNumber || ""
|
||||
}
|
||||
},
|
||||
// 查看页金额统一保留两位小数,和申请页展示口径保持一致。
|
||||
formatMoney(value) {
|
||||
if (value === null || value === undefined || value === "") {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!--#
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<div id="app" v-cloak>
|
||||
|
||||
@@ -46,6 +46,7 @@ layout("/layouts/platform_h5.html"){
|
||||
<table-column label="校区">{{row.campus}}</table-column>
|
||||
<table-column label="地点">{{row.courseLocation}}</table-column>
|
||||
<table-column label="联系人">{{row.courseInstructor}}</table-column>
|
||||
<table-column v-if="row.courseInstructorMobile" label="联系方式">{{row.courseInstructorMobile}}</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()]
|
||||
|
||||
@@ -17,6 +17,8 @@ new Vue({
|
||||
filterHolidays: false,
|
||||
holidayList: [],
|
||||
notApplyTimeList: [],
|
||||
termStartDate: '',
|
||||
termEndDate: '',
|
||||
},
|
||||
availabilityData: {
|
||||
date: '',
|
||||
@@ -140,7 +142,10 @@ new Vue({
|
||||
return base.startOf('day').toDate()
|
||||
},
|
||||
yearlyReserveMaxDate() {
|
||||
return this.$moment().add(2, 'year').endOf('year').toDate()
|
||||
const base = this.formData.reserveStartTime
|
||||
? this.$moment(this.formData.reserveStartTime)
|
||||
: (this.scheduleDate ? this.$moment(this.scheduleDate, 'YYYY-MM-DD') : this.$moment())
|
||||
return base.endOf('month').toDate()
|
||||
},
|
||||
yearlyReserveDates() {
|
||||
if (!this.yearlyReserve || !this.formData.reserveStartTime || !this.formData.reserveEndTime || !this.formData.yearlyReserveEndDate) {
|
||||
@@ -253,6 +258,10 @@ new Vue({
|
||||
}
|
||||
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate < this.formData.reserveStartTime.slice(0, 10)) {
|
||||
this.$set(this.formData, 'yearlyReserveEndDate', defaultDate)
|
||||
return
|
||||
}
|
||||
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > defaultDate) {
|
||||
this.$set(this.formData, 'yearlyReserveEndDate', defaultDate)
|
||||
}
|
||||
},
|
||||
openReserveTypePicker() {
|
||||
@@ -282,7 +291,6 @@ new Vue({
|
||||
this.formData.applyUnionName = user.union ? user.union.name : ''
|
||||
this.formData.clubId = ''
|
||||
this.formData.clubName = ''
|
||||
return
|
||||
}
|
||||
if (value === 'club') {
|
||||
this.formData.applyUnionId = ''
|
||||
@@ -291,6 +299,9 @@ new Vue({
|
||||
this.formData.clubName = ''
|
||||
await this.loadManagedClubs()
|
||||
}
|
||||
this.scheduleDate = this.getInitialScheduleDate()
|
||||
this.schedulePickerDate = this.$moment(this.scheduleDate, 'YYYY-MM-DD').toDate()
|
||||
await this.queryAvailability(this.scheduleDate)
|
||||
},
|
||||
async loadManagedClubs() {
|
||||
try {
|
||||
@@ -484,6 +495,20 @@ new Vue({
|
||||
result.push('slot-block--closed')
|
||||
return result
|
||||
},
|
||||
formatSlotLabel(block) {
|
||||
const label = block && block.label ? block.label : ''
|
||||
const match = label.match(/^(.+?)\s+(\d{2}:\d{2}(?::\d{2})?\s*-\s*\d{2}:\d{2}(?::\d{2})?)$/)
|
||||
if (match) {
|
||||
return {
|
||||
name: match[1],
|
||||
time: match[2],
|
||||
}
|
||||
}
|
||||
return {
|
||||
name: label,
|
||||
time: '',
|
||||
}
|
||||
},
|
||||
onAvailabilityBlockClick(block) {
|
||||
if (!block || !block.key) {
|
||||
return
|
||||
@@ -710,6 +735,11 @@ new Vue({
|
||||
if (currentDay.day() === 0 || currentDay.day() === 6) {
|
||||
return true
|
||||
}
|
||||
if (this.formData.reserveType === 'union' && this.timeLimitConfig.termStartDate && this.timeLimitConfig.termEndDate) {
|
||||
if (currentDay.isBefore(this.timeLimitConfig.termStartDate) || currentDay.isAfter(this.timeLimitConfig.termEndDate)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return this.timeLimitConfig.filterHolidays && this.timeLimitConfig.holidayList.includes(day)
|
||||
},
|
||||
getDisabledRangesByDay(dayStr) {
|
||||
@@ -838,6 +868,10 @@ new Vue({
|
||||
this.$toast('批量预约截止日期不能早于开始日期')
|
||||
return false
|
||||
}
|
||||
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > this.$moment(this.formData.reserveStartTime).endOf('month').format('YYYY-MM-DD')) {
|
||||
this.$toast('批量预约截止日期不能超过预约开始时间所在月份')
|
||||
return false
|
||||
}
|
||||
if (!this.yearlyReserveDates.length) {
|
||||
this.$toast('当前截止日期内没有可批量预约的同星期时段')
|
||||
return false
|
||||
@@ -924,6 +958,8 @@ new Vue({
|
||||
filterHolidays: !!this.row.filterHolidays,
|
||||
holidayList: [],
|
||||
notApplyTimeList: Array.isArray(this.row.notApplyTimeList) ? this.row.notApplyTimeList : [],
|
||||
termStartDate: this.row.termStartDate || '',
|
||||
termEndDate: this.row.termEndDate || '',
|
||||
}
|
||||
try {
|
||||
const res = await this.$axios.post('/platform/siteCug/apply/timeLimitConfig', {
|
||||
@@ -934,6 +970,8 @@ new Vue({
|
||||
filterHolidays: !!res.data.filterHolidays,
|
||||
holidayList: Array.isArray(res.data.holidayList) ? res.data.holidayList : [],
|
||||
notApplyTimeList: Array.isArray(res.data.notApplyTimeList) ? res.data.notApplyTimeList : [],
|
||||
termStartDate: res.data.termStartDate || '',
|
||||
termEndDate: res.data.termEndDate || '',
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
+33
-7
@@ -165,21 +165,30 @@ layout("/layouts/platform_h5.html"){
|
||||
.availability-popup__tabs {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
padding: 12px 16px 0;
|
||||
padding: 12px 16px 8px;
|
||||
overflow-x: auto;
|
||||
background: #f8fafc;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.availability-popup__tabs::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.availability-tab {
|
||||
flex: 0 0 auto;
|
||||
min-width: 72px;
|
||||
height: 34px;
|
||||
padding: 0 14px;
|
||||
min-height: 34px;
|
||||
padding: 6px 14px;
|
||||
border: 1px solid #cbd5e1;
|
||||
border-radius: 999px;
|
||||
background: #ffffff;
|
||||
color: #475569;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
white-space: nowrap;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -244,12 +253,13 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
.slot-block {
|
||||
min-height: 48px;
|
||||
padding: 0 12px;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #dbe4ee;
|
||||
border-radius: 14px;
|
||||
background: #ffffff;
|
||||
color: #475569;
|
||||
display: inline-flex;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
@@ -259,6 +269,21 @@ layout("/layouts/platform_h5.html"){
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.slot-block__name,
|
||||
.slot-block__time {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.slot-block__time {
|
||||
margin-top: 2px;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.slot-block--available {
|
||||
border-color: #86efac;
|
||||
background: rgba(34, 197, 94, 0.1);
|
||||
@@ -464,7 +489,7 @@ layout("/layouts/platform_h5.html"){
|
||||
</template>
|
||||
</van-cell>
|
||||
<div v-if="yearlyReserve" class="batch-panel">
|
||||
<div class="section-tip">将自动预约截止日期内每周同一时段,默认到本月底。</div>
|
||||
<div class="section-tip">预约本月后续每周同一时段,默认到本月底。</div>
|
||||
<van-field
|
||||
:value="formData.yearlyReserveEndDate"
|
||||
label="截至日期"
|
||||
@@ -548,7 +573,8 @@ layout("/layouts/platform_h5.html"){
|
||||
type="button"
|
||||
:class="getBlockClass(block)"
|
||||
@click="onAvailabilityBlockClick(block)">
|
||||
<span>{{ block.label }}</span>
|
||||
<span class="slot-block__name">{{ formatSlotLabel(block).name }}</span>
|
||||
<span class="slot-block__time">{{ formatSlotLabel(block).time }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,54 @@ layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
|
||||
.site-cug-card-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.site-cug-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 22px;
|
||||
padding: 0 8px;
|
||||
border-radius: 4px;
|
||||
background: #eef6ff;
|
||||
color: #0b75bd;
|
||||
font-size: 12px;
|
||||
}
|
||||
.site-cug-tag.gray {
|
||||
background: #f1f5f9;
|
||||
color: #64748b;
|
||||
}
|
||||
.site-cug-tag.warn {
|
||||
background: #fff3e5;
|
||||
color: #d97706;
|
||||
}
|
||||
.site-cug-tag.info {
|
||||
background: #eef2ff;
|
||||
color: #2563eb;
|
||||
}
|
||||
.site-cug-tag.muted {
|
||||
background: #f8fafc;
|
||||
color: #94a3b8;
|
||||
}
|
||||
.site-cug-batch-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
min-height: 22px;
|
||||
padding: 0 8px;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
font-size: 12px;
|
||||
}
|
||||
.site-cug-batch-child {
|
||||
padding-left: 8px;
|
||||
border-left: 3px solid #dbeafe;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
@@ -18,18 +65,35 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
<table-list api="/platform/siteCug/mine/pageData" :page_form.sync="pageForm" ref="tableListRef" title="siteName" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<div :class="row._isBatchChild ? 'site-cug-batch-child' : ''">
|
||||
<div class="site-cug-card-tags">
|
||||
<span v-if="row.applyLoginName" class="site-cug-tag">{{ row.applyLoginName }}</span>
|
||||
<span class="site-cug-tag gray">{{ row.reserveType === 'club' ? '协会预约' : '分工会预约' }}</span>
|
||||
<span v-if="row.yearlyBatch" class="site-cug-tag warn">预约本月</span>
|
||||
<span v-if="row._isBatchChild" class="site-cug-tag muted">明细</span>
|
||||
<span v-if="row._batchCount > 1 && !row._isBatchChild" class="site-cug-tag info">共 {{ row._batchCount }} 条</span>
|
||||
<button
|
||||
v-if="row._hasFoldChildren && !row._isBatchChild"
|
||||
type="button"
|
||||
class="site-cug-batch-toggle"
|
||||
@click.stop="toggleBatchGroup(row)">
|
||||
<i :class="row._expanded ? 'fa fa-angle-up' : 'fa fa-angle-down'"></i>
|
||||
<span>{{ row._expanded ? '收起' : '展开' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<table-column label="预约人">{{row.applyUserName || '-'}}</table-column>
|
||||
<table-column label="预约类型">{{row.reserveType === 'club' ? '协会预约' : '分工会预约'}}</table-column>
|
||||
<table-column label="开始时间">{{row.reserveStartTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.reserveEndTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.taskName || '-'}}</table-column>
|
||||
</div>
|
||||
</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 delete" @click="onDelete(row)" v-if="row.canCancel">
|
||||
<div class="action-btn delete" @click="onDelete(row)" v-if="!row._isBatchChild && row.canCancel">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span>取消预约</span>
|
||||
</div>
|
||||
@@ -68,14 +132,113 @@ layout("/layouts/platform_h5.html"){
|
||||
value: null,
|
||||
}
|
||||
],
|
||||
expandedBatchKeys: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onReady() {
|
||||
this.installTableListFoldHook()
|
||||
await this.querySiteType()
|
||||
await this.querySites()
|
||||
this.doSearch()
|
||||
},
|
||||
normalizeBatchFlag(row) {
|
||||
return row && (row.yearlyBatch === 1 || row.yearlyBatch === '1' || row.yearlyBatch === true)
|
||||
},
|
||||
getBatchGroupKey(row) {
|
||||
if (!this.normalizeBatchFlag(row)) {
|
||||
return 'single_' + row.id
|
||||
}
|
||||
return 'batch_' + (row.backOption || row.id) + '_' + (row.createdBy || '')
|
||||
},
|
||||
buildFoldedTableData(rows) {
|
||||
const groups = {}
|
||||
;(rows || []).forEach((row) => {
|
||||
const key = this.getBatchGroupKey(row)
|
||||
if (!groups[key]) {
|
||||
groups[key] = []
|
||||
}
|
||||
groups[key].push(Object.assign({}, row))
|
||||
})
|
||||
const displayRows = []
|
||||
Object.keys(groups).forEach((key) => {
|
||||
const sortedRows = groups[key].slice().sort((a, b) => {
|
||||
return (a.reserveStartTime || '').localeCompare(b.reserveStartTime || '')
|
||||
})
|
||||
const parent = Object.assign({}, sortedRows[0])
|
||||
const children = sortedRows.slice(1).map((item) => {
|
||||
return Object.assign({}, item, {
|
||||
_isBatchChild: true,
|
||||
_groupKey: key,
|
||||
_hasFoldChildren: false,
|
||||
})
|
||||
})
|
||||
parent._groupKey = key
|
||||
parent._isBatchChild = false
|
||||
parent._hasFoldChildren = children.length > 0
|
||||
parent._expanded = !!this.expandedBatchKeys[key]
|
||||
parent._batchCount = parent.batchDeleteCount || sortedRows.length
|
||||
parent._foldedRecords = children
|
||||
displayRows.push(parent)
|
||||
if (parent._expanded) {
|
||||
children.forEach((child) => displayRows.push(child))
|
||||
}
|
||||
})
|
||||
return displayRows
|
||||
},
|
||||
refreshFoldedTableData() {
|
||||
const tableList = this.$refs.tableListRef
|
||||
if (!tableList) {
|
||||
return
|
||||
}
|
||||
tableList.tableData = this.buildFoldedTableData(tableList._rawTableData || [])
|
||||
},
|
||||
toggleBatchGroup(row) {
|
||||
if (!row || !row._groupKey || !row._hasFoldChildren) {
|
||||
return
|
||||
}
|
||||
this.$set(this.expandedBatchKeys, row._groupKey, !this.expandedBatchKeys[row._groupKey])
|
||||
this.refreshFoldedTableData()
|
||||
},
|
||||
installTableListFoldHook() {
|
||||
const tableList = this.$refs.tableListRef
|
||||
if (!tableList || tableList._siteCugBatchFoldHooked) {
|
||||
return
|
||||
}
|
||||
tableList._siteCugBatchFoldHooked = true
|
||||
tableList._rawTableData = []
|
||||
tableList.pageData = () => {
|
||||
return this.loadFoldedMinePageData(tableList)
|
||||
}
|
||||
tableList.doSearch = () => {
|
||||
tableList.tableFinished = false
|
||||
tableList.tableData = []
|
||||
tableList._rawTableData = []
|
||||
tableList.localPageForm.pageNumber = 1
|
||||
tableList.$emit('update:page_form', Object.assign({}, tableList.localPageForm))
|
||||
return this.loadFoldedMinePageData(tableList)
|
||||
}
|
||||
},
|
||||
loadFoldedMinePageData(tableList) {
|
||||
tableList.tableLoading = true
|
||||
const loading = createListLoading()
|
||||
return this.$axios.post(tableList.api, tableList.json ? { pageForm: JSON.stringify(tableList.localPageForm) } : tableList.localPageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
const list = res.data && Array.isArray(res.data.list) ? res.data.list : []
|
||||
tableList._rawTableData = (tableList._rawTableData || []).concat(list)
|
||||
tableList.tableData = this.buildFoldedTableData(tableList._rawTableData)
|
||||
tableList.localPageForm.totalCount = res.data ? res.data.totalCount : 0
|
||||
if (tableList._rawTableData.length >= tableList.localPageForm.totalCount) {
|
||||
tableList.tableFinished = true
|
||||
}
|
||||
tableList.$emit('update:page_form', Object.assign({}, tableList.localPageForm))
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.close()
|
||||
tableList.tableLoading = false
|
||||
tableList.tableRefreshing = false
|
||||
})
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
},
|
||||
@@ -83,7 +246,7 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$dialog.confirm({
|
||||
title: '提示',
|
||||
message: row.yearlyBatch
|
||||
? ('该记录属于“预约本年”批量预约,确认后将一并删除同批次的 ' + (row.batchDeleteCount || 0) + ' 条预约记录,是否继续?')
|
||||
? ('该记录属于“预约本月”批量预约,确认后将一并删除同批次的 ' + (row.batchDeleteCount || row._batchCount || 0) + ' 条预约记录,是否继续?')
|
||||
: '您确定要取消该预约吗?',
|
||||
}).then(() => {
|
||||
this.$axios.post('/platform/siteCug/mine/delete', { id: row.id }).then((res) => {
|
||||
@@ -134,6 +297,7 @@ layout("/layouts/platform_h5.html"){
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.expandedBatchKeys = {}
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
@@ -145,4 +309,4 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
#-->
|
||||
|
||||
+141
-5
@@ -52,6 +52,30 @@ layout("/layouts/platform_h5.html"){
|
||||
background: #fff3e5;
|
||||
color: #d97706;
|
||||
}
|
||||
.site-cug-tag.info {
|
||||
background: #eef2ff;
|
||||
color: #2563eb;
|
||||
}
|
||||
.site-cug-tag.muted {
|
||||
background: #f8fafc;
|
||||
color: #94a3b8;
|
||||
}
|
||||
.site-cug-batch-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
min-height: 22px;
|
||||
padding: 0 8px;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
font-size: 12px;
|
||||
}
|
||||
.site-cug-batch-child {
|
||||
padding-left: 8px;
|
||||
border-left: 3px solid #dbeafe;
|
||||
}
|
||||
.action-btn.disabled {
|
||||
opacity: 0.45;
|
||||
pointer-events: none;
|
||||
@@ -94,10 +118,21 @@ layout("/layouts/platform_h5.html"){
|
||||
<div class="site-cug-audit-list-scroll">
|
||||
<table-list api="/platform/siteCug/schoolUnionAudit/pageData" :page_form.sync="pageForm" ref="tableListRef" title="applyUserName" @ready="onReady">
|
||||
<template v-slot="{index,row}">
|
||||
<div :class="row._isBatchChild ? 'site-cug-batch-child' : ''">
|
||||
<div class="site-cug-card-tags">
|
||||
<span v-if="row.applyLoginName" class="site-cug-tag">{{ row.applyLoginName }}</span>
|
||||
<span class="site-cug-tag gray">{{ reserveTypeText(row) }}</span>
|
||||
<span v-if="row.yearlyBatch" class="site-cug-tag warn">预约本年</span>
|
||||
<span v-if="row.yearlyBatch" class="site-cug-tag warn">预约本月</span>
|
||||
<span v-if="row._isBatchChild" class="site-cug-tag muted">明细</span>
|
||||
<span v-if="row._batchCount > 1 && !row._isBatchChild" class="site-cug-tag info">共 {{ row._batchCount }} 条</span>
|
||||
<button
|
||||
v-if="row._hasFoldChildren && !row._isBatchChild"
|
||||
type="button"
|
||||
class="site-cug-batch-toggle"
|
||||
@click.stop="toggleBatchGroup(row)">
|
||||
<i :class="row._expanded ? 'fa fa-angle-up' : 'fa fa-angle-down'"></i>
|
||||
<span>{{ row._expanded ? '收起' : '展开' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<table-column label="场地名称">{{row.siteName}}</table-column>
|
||||
<table-column label="预约主体">{{row.reserveType === 'club' ? (row.clubName || '-') : (row.applyUnionName || '-')}}</table-column>
|
||||
@@ -105,17 +140,18 @@ layout("/layouts/platform_h5.html"){
|
||||
<table-column label="开始时间">{{row.reserveStartTime}}</table-column>
|
||||
<table-column label="结束时间">{{row.reserveEndTime}}</table-column>
|
||||
<table-column label="当前节点">{{row.curTaskName || '-'}}</table-column>
|
||||
</div>
|
||||
</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)">
|
||||
<div class="action-btn" v-if="!row._isBatchChild && row.taskState === 10" @click="onAudit(row)">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span>审核</span>
|
||||
</div>
|
||||
<div class="action-btn delete" v-if="canRevoke(row)" :class="{ loading: revokeLoading }" @click="onRevoke(row)">
|
||||
<div class="action-btn delete" v-if="!row._isBatchChild && canRevoke(row)" :class="{ loading: revokeLoading }" @click="onRevoke(row)">
|
||||
<van-loading v-if="revokeLoading" size="14px" color="#fff"></van-loading>
|
||||
<i v-else class="fa fa-reply"></i>
|
||||
<span>撤回</span>
|
||||
@@ -184,11 +220,13 @@ layout("/layouts/platform_h5.html"){
|
||||
showApprovalForm: false,
|
||||
auditLoading: false,
|
||||
revokeLoading: false,
|
||||
expandedBatchKeys: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
historyBack,
|
||||
async onReady() {
|
||||
this.installTableListFoldHook()
|
||||
await this.querySiteType()
|
||||
await this.querySites()
|
||||
this.doSearch()
|
||||
@@ -203,6 +241,103 @@ layout("/layouts/platform_h5.html"){
|
||||
reserveTypeText(row) {
|
||||
return row && row.reserveType === 'club' ? '协会预约' : '分工会预约'
|
||||
},
|
||||
normalizeBatchFlag(row) {
|
||||
return row && (row.yearlyBatch === 1 || row.yearlyBatch === '1' || row.yearlyBatch === true)
|
||||
},
|
||||
getBatchGroupKey(row) {
|
||||
if (!this.normalizeBatchFlag(row)) {
|
||||
return 'single_' + row.id
|
||||
}
|
||||
return 'batch_' + (row.backOption || row.id) + '_' + (row.createdBy || '')
|
||||
},
|
||||
buildFoldedTableData(rows) {
|
||||
const groups = {}
|
||||
;(rows || []).forEach((row) => {
|
||||
const key = this.getBatchGroupKey(row)
|
||||
if (!groups[key]) {
|
||||
groups[key] = []
|
||||
}
|
||||
groups[key].push(Object.assign({}, row))
|
||||
})
|
||||
const displayRows = []
|
||||
Object.keys(groups).forEach((key) => {
|
||||
const sortedRows = groups[key].slice().sort((a, b) => {
|
||||
return (a.reserveStartTime || '').localeCompare(b.reserveStartTime || '')
|
||||
})
|
||||
const parent = Object.assign({}, sortedRows[0])
|
||||
const children = sortedRows.slice(1).map((item) => {
|
||||
return Object.assign({}, item, {
|
||||
_isBatchChild: true,
|
||||
_groupKey: key,
|
||||
_hasFoldChildren: false,
|
||||
})
|
||||
})
|
||||
parent._groupKey = key
|
||||
parent._isBatchChild = false
|
||||
parent._hasFoldChildren = children.length > 0
|
||||
parent._expanded = !!this.expandedBatchKeys[key]
|
||||
parent._batchCount = parent.batchAuditCount || sortedRows.length
|
||||
parent._foldedRecords = children
|
||||
displayRows.push(parent)
|
||||
if (parent._expanded) {
|
||||
children.forEach((child) => displayRows.push(child))
|
||||
}
|
||||
})
|
||||
return displayRows
|
||||
},
|
||||
refreshFoldedTableData() {
|
||||
const tableList = this.$refs.tableListRef
|
||||
if (!tableList) {
|
||||
return
|
||||
}
|
||||
tableList.tableData = this.buildFoldedTableData(tableList._rawTableData || [])
|
||||
},
|
||||
toggleBatchGroup(row) {
|
||||
if (!row || !row._groupKey || !row._hasFoldChildren) {
|
||||
return
|
||||
}
|
||||
this.$set(this.expandedBatchKeys, row._groupKey, !this.expandedBatchKeys[row._groupKey])
|
||||
this.refreshFoldedTableData()
|
||||
},
|
||||
installTableListFoldHook() {
|
||||
const tableList = this.$refs.tableListRef
|
||||
if (!tableList || tableList._siteCugBatchFoldHooked) {
|
||||
return
|
||||
}
|
||||
tableList._siteCugBatchFoldHooked = true
|
||||
tableList._rawTableData = []
|
||||
tableList.pageData = () => {
|
||||
return this.loadFoldedAuditPageData(tableList)
|
||||
}
|
||||
tableList.doSearch = () => {
|
||||
tableList.tableFinished = false
|
||||
tableList.tableData = []
|
||||
tableList._rawTableData = []
|
||||
tableList.localPageForm.pageNumber = 1
|
||||
tableList.$emit('update:page_form', Object.assign({}, tableList.localPageForm))
|
||||
return this.loadFoldedAuditPageData(tableList)
|
||||
}
|
||||
},
|
||||
loadFoldedAuditPageData(tableList) {
|
||||
tableList.tableLoading = true
|
||||
const loading = createListLoading()
|
||||
return this.$axios.post(tableList.api, tableList.json ? { pageForm: JSON.stringify(tableList.localPageForm) } : tableList.localPageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
const list = res.data && Array.isArray(res.data.list) ? res.data.list : []
|
||||
tableList._rawTableData = (tableList._rawTableData || []).concat(list)
|
||||
tableList.tableData = this.buildFoldedTableData(tableList._rawTableData)
|
||||
tableList.localPageForm.totalCount = res.data ? res.data.totalCount : 0
|
||||
if (tableList._rawTableData.length >= tableList.localPageForm.totalCount) {
|
||||
tableList.tableFinished = true
|
||||
}
|
||||
tableList.$emit('update:page_form', Object.assign({}, tableList.localPageForm))
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.close()
|
||||
tableList.tableLoading = false
|
||||
tableList.tableRefreshing = false
|
||||
})
|
||||
},
|
||||
onView(row) {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
@@ -228,7 +363,7 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$dialog.confirm({
|
||||
title: '提示',
|
||||
message: this.formData.yearlyBatch
|
||||
? ('该记录属于“预约本年”批量预约,提交后将一并审核同批次的 ' + (this.formData.batchAuditCount || 0) + ' 条预约记录,是否继续?')
|
||||
? ('该记录属于“预约本月”批量预约,提交后将一并审核同批次的 ' + (this.formData.batchAuditCount || 0) + ' 条预约记录,是否继续?')
|
||||
: '您确定要提交吗?',
|
||||
}).then(() => {
|
||||
this.auditLoading = true
|
||||
@@ -267,7 +402,7 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$dialog.confirm({
|
||||
title: '提示',
|
||||
message: row.yearlyBatch
|
||||
? ('该记录属于“预约本年”批量预约,撤回后将一并撤回同批次的 ' + (row.batchAuditCount || 0) + ' 条审核任务,是否继续?')
|
||||
? ('该记录属于“预约本月”批量预约,撤回后将一并撤回同批次的 ' + (row.batchAuditCount || 0) + ' 条审核任务,是否继续?')
|
||||
: '您确定要撤回吗?',
|
||||
}).then(() => {
|
||||
this.revokeLoading = true
|
||||
@@ -321,6 +456,7 @@ layout("/layouts/platform_h5.html"){
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.expandedBatchKeys = {}
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
|
||||
+734
-115
File diff suppressed because it is too large
Load Diff
@@ -2,118 +2,263 @@ const UNION_REIMBURSE_INFO = {
|
||||
template:
|
||||
/*language=HTML*/
|
||||
`
|
||||
<van-action-sheet v-model="visible" title="查看详情">
|
||||
<van-action-sheet v-model="visible" class="union-reimburse-info-sheet">
|
||||
<div class="union-info-header">
|
||||
<div class="union-info-header-title">查看详情</div>
|
||||
<div class="union-info-close" @click="onClose">
|
||||
<van-icon name="cross"></van-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-container">
|
||||
<van-cell-group title="报销申请">
|
||||
<van-cell title="工号">{{ viewData.loginName }}</van-cell>
|
||||
<van-cell title="经办人">{{ viewData.userName }}</van-cell>
|
||||
<van-cell title="联系方式">{{ viewData.mobile }}</van-cell>
|
||||
<van-cell title="经费来源">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_FUND_SOURCE"
|
||||
:value="viewData.reimburseFundSource">
|
||||
</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_PAYMENT_WAY"
|
||||
:value="viewData.paymentWay">
|
||||
</dict-tag>
|
||||
</van-cell>
|
||||
<van-cell title="所属协会" v-if="viewData.reimburseFundSource === 'UNION_REIMBURSE_FUND_SOURCE_3'">
|
||||
{{ viewData.clubName }}
|
||||
</van-cell>
|
||||
<van-cell title="余额" v-if="viewData.reimburseFundSource">{{ formatMoney(viewData.fundBalance) }}</van-cell>
|
||||
<div class="union-info-scroll">
|
||||
<div class="union-info-section">
|
||||
<div class="union-info-section-title">报销申请</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">工号</div>
|
||||
<div class="union-info-value">{{ viewData.loginName }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">经办人</div>
|
||||
<div class="union-info-value union-info-link">{{ viewData.userName }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">联系方式</div>
|
||||
<div class="union-info-value">{{ viewData.mobile }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">经费来源</div>
|
||||
<div class="union-info-value">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_FUND_SOURCE" :value="viewData.reimburseFundSource"></dict-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">报销项目</div>
|
||||
<div class="union-info-value">
|
||||
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT" :value="viewData.reimburseProject"></dict-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="union-info-row" v-if="viewData.reimburseFundSource === 'UNION_REIMBURSE_FUND_SOURCE_3'">
|
||||
<div class="union-info-label">所属协会</div>
|
||||
<div class="union-info-value">{{ viewData.clubName }}</div>
|
||||
</div>
|
||||
<div class="union-info-row" v-if="viewData.reimburseFundSource">
|
||||
<div class="union-info-label">余额</div>
|
||||
<div class="union-info-value">{{ formatMoney(viewData.fundBalance) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
|
||||
<van-cell title="付款人">{{ viewData.payerName }}</van-cell>
|
||||
<van-cell title="户名">{{ viewData.bankUserName }}</van-cell>
|
||||
<van-cell title="开户行">{{ viewData.bankOfDeposit }}</van-cell>
|
||||
<van-cell title="银行卡号">{{ viewData.bankCardNumber }}</van-cell>
|
||||
</template>
|
||||
<div class="union-info-section">
|
||||
<div class="union-info-section-title">支付信息</div>
|
||||
<template v-if="paymentInfoRows.length">
|
||||
<div class="union-payment-tabs">
|
||||
<div class="union-payment-tab"
|
||||
:class="{active: index === currentPaymentIndex}"
|
||||
v-for="(item, index) in paymentInfoRows"
|
||||
:key="index"
|
||||
@click="swipeToPayment(index)">支付信息{{ index + 1 }}</div>
|
||||
</div>
|
||||
<van-swipe ref="paymentInfoSwipe" :loop="false" :show-indicators="false" @change="handlePaymentSwipeChange">
|
||||
<van-swipe-item v-for="(item, index) in paymentInfoRows" :key="index">
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">支付方式</div>
|
||||
<div class="union-info-value">{{ getPaymentWayText(item.paymentWay) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">金额</div>
|
||||
<div class="union-info-value">{{ formatMoney(item.money) }}</div>
|
||||
</div>
|
||||
<template v-if="item.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">付款人</div>
|
||||
<div class="union-info-value">{{ item.payerName }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">户名</div>
|
||||
<div class="union-info-value">{{ item.bankUserName }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">开户行</div>
|
||||
<div class="union-info-value">{{ item.bankOfDeposit }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">银行卡号</div>
|
||||
<div class="union-info-value">{{ item.bankCardNumber }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</van-swipe-item>
|
||||
</van-swipe>
|
||||
</template>
|
||||
<div class="union-empty-text" v-else>暂无支付信息</div>
|
||||
</div>
|
||||
|
||||
<template v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
|
||||
<van-cell title="慰问对象">{{ viewData.condolenceUserName }}</van-cell>
|
||||
<van-cell title="性别">{{ viewData.condolenceSex }}</van-cell>
|
||||
<van-cell title="生日">{{ formatDateText(viewData.condolenceBirthday) }}</van-cell>
|
||||
<van-cell title="身份证号">{{ viewData.condolenceIdCard }}</van-cell>
|
||||
<van-cell title="联系方式">{{ viewData.condolenceMobile }}</van-cell>
|
||||
<van-cell title="慰问类型">{{ viewData.typeName || viewData.condolenceTypeName }}</van-cell>
|
||||
<van-cell title="慰问方式">{{ viewData.way }}</van-cell>
|
||||
<van-cell title="慰问金额">{{ formatMoney(viewData.condolenceMoney) }}</van-cell>
|
||||
<van-cell title="慰问时间">{{ formatDateText(viewData.condolenceTime) }}</van-cell>
|
||||
<van-cell title="结婚时间" v-if="isCondolenceType('cf4ce7af322d464f8f86d818fcc00203')">
|
||||
{{ formatDateText(viewData.marryTime) }}
|
||||
</van-cell>
|
||||
<van-cell title="生育时间" v-if="isCondolenceType('c90cb10dce6542e99ae271bee6fe8cc0')">
|
||||
{{ formatDateText(viewData.fertilityTime) }}
|
||||
</van-cell>
|
||||
<div class="union-info-section" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
|
||||
<div class="union-info-section-title">慰问信息</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">慰问对象</div>
|
||||
<div class="union-info-value">{{ viewData.condolenceUserName }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">性别</div>
|
||||
<div class="union-info-value">{{ viewData.condolenceSex }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">生日</div>
|
||||
<div class="union-info-value">{{ formatDateText(viewData.condolenceBirthday) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">身份证号</div>
|
||||
<div class="union-info-value">{{ viewData.condolenceIdCard }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">联系方式</div>
|
||||
<div class="union-info-value">{{ viewData.condolenceMobile }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">慰问类型</div>
|
||||
<div class="union-info-value">{{ viewData.typeName || viewData.condolenceTypeName }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">慰问方式</div>
|
||||
<div class="union-info-value">{{ viewData.way }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">慰问金额</div>
|
||||
<div class="union-info-value">{{ formatMoney(viewData.condolenceMoney) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">慰问时间</div>
|
||||
<div class="union-info-value">{{ formatDateText(viewData.condolenceTime) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row" v-if="isCondolenceType('cf4ce7af322d464f8f86d818fcc00203')">
|
||||
<div class="union-info-label">结婚时间</div>
|
||||
<div class="union-info-value">{{ formatDateText(viewData.marryTime) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row" v-if="isCondolenceType('c90cb10dce6542e99ae271bee6fe8cc0')">
|
||||
<div class="union-info-label">生育时间</div>
|
||||
<div class="union-info-value">{{ formatDateText(viewData.fertilityTime) }}</div>
|
||||
</div>
|
||||
<template v-if="isCondolenceType('4e316737e71047e0b01aea78524c1416')">
|
||||
<van-cell title="住院病由">{{ viewData.hospitalCausation }}</van-cell>
|
||||
<van-cell title="住院开始时间">{{ formatDateText(viewData.hospitalizationStartTime) }}</van-cell>
|
||||
<van-cell title="住院结束时间">{{ formatDateText(viewData.hospitalizationEndTime) }}</van-cell>
|
||||
<van-cell title="入住医院">{{ viewData.hospital }}</van-cell>
|
||||
<van-cell title="当年次数">{{ viewData.hospitalCount }}</van-cell>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">住院病由</div>
|
||||
<div class="union-info-value">{{ viewData.hospitalCausation }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">住院开始时间</div>
|
||||
<div class="union-info-value">{{ formatDateText(viewData.hospitalizationStartTime) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">住院结束时间</div>
|
||||
<div class="union-info-value">{{ formatDateText(viewData.hospitalizationEndTime) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">入住医院</div>
|
||||
<div class="union-info-value">{{ viewData.hospital }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">当年次数</div>
|
||||
<div class="union-info-value">{{ viewData.hospitalCount }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="isCondolenceType('60f03a87b62b4823855814afdbf5672a')">
|
||||
<van-cell title="去逝时间">{{ formatDateText(viewData.deathTime) }}</van-cell>
|
||||
<van-cell title="与被慰问人关系">{{ viewData.condolenceRelationship }}</van-cell>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">去逝时间</div>
|
||||
<div class="union-info-value">{{ formatDateText(viewData.deathTime) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">与被慰问人关系</div>
|
||||
<div class="union-info-value">{{ viewData.condolenceRelationship }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<van-cell title="参加随行人员">
|
||||
<div style="white-space: pre-line">{{ viewData.participants }}</div>
|
||||
</van-cell>
|
||||
<van-cell title="报销事由">
|
||||
<div style="white-space: pre-line">{{ viewData.paymentNotes }}</div>
|
||||
</van-cell>
|
||||
<van-cell title="备注">
|
||||
<div style="white-space: pre-line">{{ viewData.notes }}</div>
|
||||
</van-cell>
|
||||
</template>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">参加随行人员</div>
|
||||
<div class="union-info-value">{{ viewData.participants }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">报销事由</div>
|
||||
<div class="union-info-value">{{ viewData.paymentNotes }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">备注</div>
|
||||
<div class="union-info-value">{{ viewData.notes }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-if="viewData.reimburseProject && viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
|
||||
<van-cell title="活动名称">{{ viewData.activityName }}</van-cell>
|
||||
<van-cell title="活动人数">{{ viewData.activityNumber }}</van-cell>
|
||||
<van-cell title="活动地点">{{ viewData.activityPlace }}</van-cell>
|
||||
<van-cell title="活动时间">{{ formatDateText(viewData.activityTime) }}</van-cell>
|
||||
<van-cell title="支付内容">
|
||||
<div style="white-space: pre-line">{{ viewData.paymentNotes }}</div>
|
||||
</van-cell>
|
||||
</template>
|
||||
<div class="union-info-section" v-if="viewData.reimburseProject && viewData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
|
||||
<div class="union-info-section-title">活动信息</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">活动名称</div>
|
||||
<div class="union-info-value union-info-link">{{ viewData.activityName }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">活动人数</div>
|
||||
<div class="union-info-value">{{ viewData.activityNumber }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">活动地点</div>
|
||||
<div class="union-info-value">{{ viewData.activityPlace }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">活动时间</div>
|
||||
<div class="union-info-value">{{ formatDateText(viewData.activityTime) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">支付内容</div>
|
||||
<div class="union-info-value">{{ viewData.paymentNotes }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<van-cell title="附件">
|
||||
<template #label>
|
||||
<file-preview :files="viewData.files" complete_result
|
||||
v-if="viewData.files && viewData.files.length > 0"></file-preview>
|
||||
<span v-else>暂无附件</span>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<div class="union-info-section">
|
||||
<div class="union-info-section-title">附件</div>
|
||||
<div class="union-file-preview" v-if="viewData.files && viewData.files.length > 0">
|
||||
<file-preview :files="viewData.files" complete_result></file-preview>
|
||||
</div>
|
||||
<div class="union-empty-text" v-else>暂无附件</div>
|
||||
</div>
|
||||
|
||||
<van-cell-group title="电子发票" v-if="viewData.reimburseProject">
|
||||
<van-cell title="报销金额">{{ formatMoney(viewData.money) }}</van-cell>
|
||||
<van-cell title="发票张数">{{ viewData.invoiceNumber }}</van-cell>
|
||||
<van-cell title="发票明细列表">
|
||||
<template #label>
|
||||
<template v-if="viewData.invoiceDetails && viewData.invoiceDetails.length > 0">
|
||||
<div style="margin-top: 8px; padding: 10px 12px; border: 1px solid #ebedf0; border-radius: 6px; background: #fafafa;" v-for="(item, index) in viewData.invoiceDetails" :key="index">
|
||||
<div style="margin-top: 4px; color: #323233;">第{{ index + 1 }}张发票</div>
|
||||
<div style="margin-top: 4px;">发票号码:{{ item.invoiceNo || '未填写' }}</div>
|
||||
<div style="margin-top: 4px;">发票金额:{{ formatMoney(item.invoiceAmount) }}</div>
|
||||
<div style="margin-top: 4px;">销售方信息名称:{{ item.sellerName || '未填写' }}</div>
|
||||
<div style="margin-top: 4px;">项目名称:{{ item.itemName || '未填写' }}</div>
|
||||
<div style="margin-top: 4px;" v-if="item.remark">备注:{{ item.remark }}</div>
|
||||
<file-preview :files="item.invoiceFiles" complete_result
|
||||
v-if="item.invoiceFiles && item.invoiceFiles.length > 0"></file-preview>
|
||||
<div style="margin-top: 4px;" v-else>文件:未上传</div>
|
||||
<div class="union-info-section" v-if="viewData.reimburseProject">
|
||||
<div class="union-info-section-title">电子发票</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">报销金额</div>
|
||||
<div class="union-info-value">{{ formatMoney(viewData.money) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">发票张数</div>
|
||||
<div class="union-info-value">{{ viewData.invoiceNumber }}</div>
|
||||
</div>
|
||||
<div class="union-invoice-subtitle">发票明细表</div>
|
||||
<div class="union-invoice-card-list" v-if="viewData.invoiceDetails && viewData.invoiceDetails.length > 0">
|
||||
<div class="union-invoice-card" v-for="(item, index) in viewData.invoiceDetails" :key="index">
|
||||
<div class="union-invoice-card-title">第{{ index + 1 }}张发票</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">发票号码</div>
|
||||
<div class="union-info-value">{{ item.invoiceNo || '未填写' }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<van-empty description="暂无发票明细" v-else></van-empty>
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">发票金额</div>
|
||||
<div class="union-info-value">{{ formatMoney(item.invoiceAmount) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">销售方名称</div>
|
||||
<div class="union-info-value">{{ item.sellerName || '未填写' }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">项目名称</div>
|
||||
<div class="union-info-value">{{ item.itemName || '未填写' }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">备注</div>
|
||||
<div class="union-info-value">{{ item.remark || '未填写' }}</div>
|
||||
</div>
|
||||
<template v-if="item.invoiceFiles && item.invoiceFiles.length > 0">
|
||||
<div class="union-file-preview union-invoice-file-preview">
|
||||
<file-preview :files="item.invoiceFiles" complete_result></file-preview>
|
||||
</div>
|
||||
</template>
|
||||
<div class="union-empty-text" v-else>文件:未上传</div>
|
||||
</div>
|
||||
</div>
|
||||
<van-empty description="暂无发票明细" v-else></van-empty>
|
||||
</div>
|
||||
|
||||
<!-- <van-cell-group title="电子签名">-->
|
||||
<!-- <van-cell title="签字">-->
|
||||
@@ -126,47 +271,54 @@ const UNION_REIMBURSE_INFO = {
|
||||
<!-- </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="申请时间">
|
||||
{{ formatCreateTime(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="办理时间">
|
||||
{{ formatCreateTime(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 v-for="(task,index) in doneTasks">
|
||||
<div class="union-info-section">
|
||||
<div class="process-title">{{ task.displayName }}</div>
|
||||
<template v-if="task.ext.isFirstTaskNode">
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">申请用户</div>
|
||||
<div class="union-info-value">{{ task.ext.initiatorName}}({{task.ext.initiatorAccount}})</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">申请时间</div>
|
||||
<div class="union-info-value">{{ formatCreateTime(task.finishTime) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">办理结果</div>
|
||||
<div class="union-info-value">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
<template v-else>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">办理用户</div>
|
||||
<div class="union-info-value">{{ task.taskFormData.userName}}({{task.taskFormData.loginName}})</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">办理时间</div>
|
||||
<div class="union-info-value">{{ formatCreateTime(task.finishTime) }}</div>
|
||||
</div>
|
||||
<div class="union-info-row">
|
||||
<div class="union-info-label">办理结果</div>
|
||||
<div class="union-info-value">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="union-info-row" v-if="!task.ext.isFirstTaskNode">
|
||||
<div class="union-info-label">办理意见</div>
|
||||
<div class="union-info-value">{{ task.taskFormData.opinion }}</div>
|
||||
</div>
|
||||
<div class="union-info-row" v-if="!task.ext.isFirstTaskNode && task.ext.tf_userSign">
|
||||
<div class="union-info-label">签字</div>
|
||||
<div class="union-info-value">
|
||||
<van-image :src="task.ext.tf_userSign" class="signature-image"></van-image>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<slot></slot>
|
||||
@@ -178,13 +330,35 @@ const UNION_REIMBURSE_INFO = {
|
||||
visible: false,
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null
|
||||
row: null,
|
||||
currentPaymentIndex: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
paymentInfoRows() {
|
||||
return this.viewData.paymentDetails || []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.injectInfoStyle()
|
||||
},
|
||||
methods: {
|
||||
injectInfoStyle() {
|
||||
// 当前组件是普通 JS 对象注册,Vue 不会自动注入 style 字段,这里只为本详情弹窗注入一次样式。
|
||||
const styleId = "union-reimburse-info-style"
|
||||
if (document.getElementById(styleId) || !this.$options.style) {
|
||||
return
|
||||
}
|
||||
const styleNode = document.createElement("style")
|
||||
styleNode.id = styleId
|
||||
styleNode.type = "text/css"
|
||||
styleNode.appendChild(document.createTextNode(this.$options.style))
|
||||
document.head.appendChild(styleNode)
|
||||
},
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
this.currentPaymentIndex = 0
|
||||
this.getInfo()
|
||||
this.getDoneTasks()
|
||||
},
|
||||
@@ -208,11 +382,82 @@ const UNION_REIMBURSE_INFO = {
|
||||
isCondolenceType(typeId) {
|
||||
return this.viewData.condolenceTypeId === typeId || this.viewData.condolenceType === typeId
|
||||
},
|
||||
getPaymentWayText(paymentWay) {
|
||||
const matchedPaymentWay = this.dict.type.UNION_REIMBURSE_PAYMENT_WAY.find(item => item.code === paymentWay)
|
||||
return matchedPaymentWay ? matchedPaymentWay.name : ""
|
||||
},
|
||||
buildViewData(data) {
|
||||
const viewData = Object.assign({
|
||||
files: [],
|
||||
invoiceDetails: [],
|
||||
paymentDetails: []
|
||||
}, data || {})
|
||||
if (!Array.isArray(viewData.files)) {
|
||||
viewData.files = []
|
||||
}
|
||||
if (!Array.isArray(viewData.invoiceDetails)) {
|
||||
viewData.invoiceDetails = []
|
||||
}
|
||||
const hasLegacyPayment = viewData.paymentWay || viewData.payer || viewData.bankUserName || viewData.bankCardNumber || viewData.bankOfDeposit
|
||||
if (Array.isArray(viewData.paymentDetails) && viewData.paymentDetails.length > 0) {
|
||||
viewData.paymentDetails = viewData.paymentDetails.map(item => this.buildPaymentDetail(item))
|
||||
} else {
|
||||
viewData.paymentDetails = hasLegacyPayment ? [this.buildPaymentDetail({
|
||||
paymentWay: viewData.paymentWay,
|
||||
money: viewData.money,
|
||||
payerName: viewData.payerName,
|
||||
bankUserName: viewData.bankUserName,
|
||||
bankOfDeposit: viewData.bankOfDeposit,
|
||||
bankCardNumber: viewData.bankCardNumber
|
||||
})] : []
|
||||
}
|
||||
return viewData
|
||||
},
|
||||
buildPaymentDetail(detail) {
|
||||
const currentDetail = detail || {}
|
||||
return {
|
||||
paymentWay: currentDetail.paymentWay || "",
|
||||
money: currentDetail.money || "",
|
||||
payerName: currentDetail.payerName || "",
|
||||
bankUserName: currentDetail.bankUserName || "",
|
||||
bankOfDeposit: currentDetail.bankOfDeposit || "",
|
||||
bankCardNumber: currentDetail.bankCardNumber || ""
|
||||
}
|
||||
},
|
||||
handlePaymentSwipeChange(index) {
|
||||
this.currentPaymentIndex = index
|
||||
},
|
||||
swipeToPayment(index) {
|
||||
if (!this.paymentInfoRows.length) {
|
||||
this.currentPaymentIndex = 0
|
||||
return
|
||||
}
|
||||
const targetIndex = Math.max(0, Math.min(index, this.paymentInfoRows.length - 1))
|
||||
this.currentPaymentIndex = targetIndex
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.paymentInfoSwipe && this.$refs.paymentInfoSwipe.swipeTo) {
|
||||
this.$refs.paymentInfoSwipe.swipeTo(targetIndex)
|
||||
}
|
||||
})
|
||||
},
|
||||
showPrevPayment() {
|
||||
if (this.currentPaymentIndex <= 0) {
|
||||
return
|
||||
}
|
||||
this.swipeToPayment(this.currentPaymentIndex - 1)
|
||||
},
|
||||
showNextPayment() {
|
||||
if (this.currentPaymentIndex >= this.paymentInfoRows.length - 1) {
|
||||
return
|
||||
}
|
||||
this.swipeToPayment(this.currentPaymentIndex + 1)
|
||||
},
|
||||
// 获取申请信息
|
||||
getInfo() {
|
||||
this.$axios.post("/platform/unionReimburse/apply/info", { id: this.row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
this.viewData = this.buildViewData(res.data)
|
||||
this.currentPaymentIndex = 0
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -230,6 +475,209 @@ const UNION_REIMBURSE_INFO = {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.union-reimburse-info-sheet {
|
||||
height: 92vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.union-reimburse-info-sheet .van-action-sheet__content {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.union-info-header {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 56px;
|
||||
padding: 0 20px;
|
||||
background: #fff;
|
||||
border-top: 4px solid #1677ff;
|
||||
border-bottom: 1px solid #e7ebf0;
|
||||
}
|
||||
|
||||
.union-info-header-title {
|
||||
color: #111827;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.union-info-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
color: #8b95a3;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.detail-container {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
background: #f2f4f7;
|
||||
}
|
||||
|
||||
.union-info-scroll {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.union-info-section {
|
||||
background: #fff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.union-info-section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 44px;
|
||||
padding: 0 16px;
|
||||
color: #1f2937;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
background: #f5f7fa;
|
||||
border-bottom: 1px solid #e7ebf0;
|
||||
}
|
||||
|
||||
.union-info-section-title::before {
|
||||
content: "";
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
margin-right: 8px;
|
||||
border-radius: 2px;
|
||||
background: #1677ff;
|
||||
}
|
||||
|
||||
.union-info-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
min-height: 44px;
|
||||
padding: 12px 20px;
|
||||
border-bottom: 1px solid #edf0f4;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.union-info-row:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.union-info-label {
|
||||
flex: 0 0 96px;
|
||||
color: #8a94a6;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.union-info-value {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
color: #1f2937;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
text-align: right;
|
||||
word-break: break-all;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.union-info-link {
|
||||
color: #1677ff;
|
||||
}
|
||||
|
||||
.union-payment-tabs {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
padding: 12px 20px 4px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.union-payment-tab {
|
||||
height: 30px;
|
||||
padding: 0 13px;
|
||||
border-radius: 999px;
|
||||
color: #8a94a6;
|
||||
background: #f0f2f5;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.union-payment-tab.active {
|
||||
color: #fff;
|
||||
background: #1677ff;
|
||||
}
|
||||
|
||||
.union-empty-text {
|
||||
padding: 14px 20px;
|
||||
color: #9aa3af;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.union-file-preview {
|
||||
padding: 12px 20px 16px;
|
||||
}
|
||||
|
||||
.union-invoice-subtitle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
padding: 0 20px;
|
||||
color: #6b7280;
|
||||
font-size: 13px;
|
||||
background: #f5f7fa;
|
||||
border-top: 1px solid #edf0f4;
|
||||
border-bottom: 1px solid #edf0f4;
|
||||
}
|
||||
|
||||
.union-invoice-card-list {
|
||||
padding: 12px 16px 4px;
|
||||
}
|
||||
|
||||
.union-invoice-card {
|
||||
margin-bottom: 12px;
|
||||
padding: 14px 14px 12px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #e6ebf2;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 3px rgba(31, 35, 41, 0.05);
|
||||
}
|
||||
|
||||
.union-invoice-card-title {
|
||||
margin-bottom: 8px;
|
||||
color: #1677ff;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.union-invoice-file-preview {
|
||||
padding: 12px 0 0;
|
||||
}
|
||||
|
||||
.process-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
padding: 0 20px;
|
||||
color: #1f2937;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.signature-image {
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
object-fit: contain;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user