This commit is contained in:
2026-10-21 14:19:01 +08:00
22 changed files with 970 additions and 644 deletions
+197 -159
View File
@@ -110,7 +110,7 @@ layout("/mobile/platform.html"){
left-arrow
placeholder
fixed
@click-left="pjaxReplace('/mobile/index')"
@click-left="leavePage"
safe-area-inset-top
></van-nav-bar>
@@ -207,13 +207,13 @@ layout("/mobile/platform.html"){
></van-empty>
</div>
<van-popup v-model="infoShow" get-container="#app" position="right" :style="{ height: '100%', width: '100%' }">
<van-popup v-model="infoShow" :close-on-click-overlay="false" get-container="#app" position="right" :style="{ height: '100%', width: '100%' }">
<van-nav-bar
title="社团详细信息"
left-arrow
placeholder
fixed
@click-left="infoShow = false"
@click-left="closePopup"
safe-area-inset-top></van-nav-bar>
<van-tabs v-model="infoActive">
<van-tab title="社团信息">
@@ -233,94 +233,29 @@ layout("/mobile/platform.html"){
<span style="cursor: pointer; color: #236eb4">点击查看</span>
</van-cell>
</van-cell-group>
<div class="footer" v-if="canJoin">
<van-button class="join" @click="startJoin">我要加入</van-button>
</div>
<van-cell v-else title="申请状态" :value="joinStatus"></van-cell>
</van-tab>
<van-tab v-if="viewType === 'join'" title="个人信息">
<van-form @submit="needJoin" ref="form" :show-error-message="false">
<van-cell-group inset class="mt10">
<van-field readonly v-model="formData.username" name="username"
label="姓名" :rules="[{ required: true }]"></van-field>
<van-field readonly v-model="formData.sex" name="sex"
label="性别" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.birthday" name="birthday" required
@click="showPicker = true"
placeholder="请填写出生年月" label="出生年月" :rules="[{ required: true }]">
</van-field>
<van-popup v-model="showPicker" position="bottom">
<van-datetime-picker
type="date"
title="选择年月日"
@confirm="(val) => {formData.birthday = moment(val).format('YYYY-MM-DD'); showPicker = false}"
@cancel="showPicker = false"
></van-datetime-picker>
<van-field v-model="formData.username" name="username" label="姓名" placeholder="请填写姓名" readonly required :rules="[{ required: true, message: '请填写姓名' }]"></van-field>
<van-field v-model="formData.sex" name="sex" label="性别" placeholder="请填写性别" readonly required :rules="[{ required: true, message: '请填写性别' }]"></van-field>
<van-field v-model="formData.loginname" name="loginname" label="工号" placeholder="请填写工号" readonly required :rules="[{ required: true, message: '请填写工号' }]"></van-field>
<van-field v-model="formData.birthday" name="birthday" label="出生年月" placeholder="请填写出生年月" readonly @click="openBirthday" required :rules="[{ required: true, message: '请填写出生年月' }]"></van-field>
<van-popup v-model="showPicker" position="bottom" :close-on-click-overlay="false">
<van-datetime-picker v-model="birthdayPickerValue" type="date" :min-date="birthdayMinDate" :max-date="birthdayMaxDate" title="选择出生日期" @confirm="confirmBirthday" @cancel="closePopup"></van-datetime-picker>
</van-popup>
<van-field v-model="formData.birthPlace" name="birthPlace" required
placeholder="请填写出生地" label="出生地" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.education" name="education" required
placeholder="请填写文化程度" label="文化程度" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.hobby" name="hobby" required
placeholder="请填写爱好" label="爱好" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.unitName" name="unitName" required
readonly label="工作部门" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.position" name="position" required
placeholder="请填写职务" label="职务" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.mobile" name="mobile" required
placeholder="请填写电话" label="电话" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.email" name="email" required
placeholder="请填写电子邮箱" label="电子邮箱" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.homeAddress" name="homeAddress" required
placeholder="请填写家庭住址" label="家庭住址" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.QQNumber" name="QQNumber" required
placeholder="请填写QQ" label="QQ" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.bodyHeight" name="bodyHeight" required
placeholder="请填写身高" label="身高" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.bodyWeight" name="bodyWeight" required
placeholder="请填写体重" label="体重" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.health" name="health" required
placeholder="请填写身体状况" label="身体状况" :rules="[{ required: true }]"></van-field>
<van-field v-model="formData.sport" name="sport" required
placeholder="请填写经常从事的运动" label="经常从事的运动" :rules="[{ required: true }]"></van-field>
<van-field name="medicalHistory" required
placeholder="是否有过特殊病史" label="是否有过特殊病史">
<template #input>
<van-radio-group v-model="formData.medicalHistory" direction="horizontal">
<van-radio :name="true">是</van-radio>
<van-radio :name="false">否</van-radio>
</van-radio-group>
</template>
</van-field>
<van-field name="joinActivity" required
placeholder="是否愿意参加本协会的活动" label="是否愿意参加本协会的活动">
<template #input>
<van-radio-group v-model="formData.joinActivity" direction="horizontal">
<van-radio :name="true">是</van-radio>
<van-radio :name="false">否</van-radio>
</van-radio-group>
</template>
</van-field>
<van-field v-model="formData.otherThing" name="otherThing"
rows="1"
autosize
type="textarea"
placeholder="是否有特别需要说明的问题(身体或心理)" label="是否有特别需要说明的问题"></van-field>
<van-field v-model="formData.remark" name="remark"
rows="1"
autosize
type="textarea"
placeholder="备注" label="备注"></van-field>
<van-field name="photo" label="两寸登记照" required
style="flex-flow: column" input-align="left">
<template #label>
<div class="mb10">两寸登记照</div>
</template>
<template #input>
<vant-file-upload
:max="1"
:files.sync="formData.photo"></vant-file-upload>
</template>
</van-field>
<van-field v-model="formData.mobile" name="mobile" label="联系电话" placeholder="请填写联系电话" maxlength="20" required :rules="[{ required: true, message: '请填写联系电话' }]"></van-field>
<van-field name="medicalHistory" label="是否有特殊病史" required><template #input><van-radio-group v-model="formData.medicalHistory" direction="horizontal"><van-radio :name="true">是</van-radio><van-radio :name="false">否</van-radio></van-radio-group></template></van-field>
<van-field v-model="formData.otherThing" name="otherThing" label="是否有特别需要说明的问题" placeholder="如有,请填写特别需要说明的问题" maxlength="100" type="textarea" autosize></van-field>
<van-field v-model="formData.emergencyContact" name="emergencyContact" label="紧急联系人" placeholder="请填写紧急联系人" maxlength="50" required :rules="[{ required: true, message: '请填写紧急联系人' }]"></van-field>
<van-field v-model="formData.emergencyMobile" name="emergencyMobile" label="紧急联系电话" placeholder="请填写紧急联系电话" maxlength="20" required :rules="[{ required: true, message: '请填写紧急联系电话' }]"></van-field>
</van-cell-group>
<div class="footer">
<van-button class="join join_submit" native-type="submit">申请加入</van-button>
<van-button class="join join_submit" :loading="formLoading" native-type="submit">申请加入</van-button>
</div>
</van-form>
</van-tab>
@@ -336,6 +271,9 @@ layout("/mobile/platform.html"){
data() {
return {
showPicker: false,
birthdayPickerValue: new Date(),
birthdayMinDate: new Date(1900, 0, 1),
birthdayMaxDate: new Date(),
infoActive: 0,
clickRow: {},
typeOptions: [],
@@ -343,17 +281,77 @@ layout("/mobile/platform.html"){
infoShow: false,
detailData: {},
viewType: '',
formLoading: false,
// 服务端保留本次页面请求的社团 ID,避免依赖页面切换时的地址栏状态。
scanClubId: decodeURIComponent('${scanClubId!}'.replace(/\+/g, '%20')),
}
},
computed: {
canJoin() {
return !!this.detailData.id && ![1, 3, 5].includes(Number(this.detailData.status))
},
joinStatus() {
return {1: '待社团审核', 3: '待校工会审核', 5: '已加入'}[this.detailData.status] || ''
}
},
methods: {
showCode(type) {
if(type === 'QQ' && this.clickRow.qqgroupcode) {
const ids = JSON.parse(this.clickRow.qqgroupcode).map(o => FILE_DOMAIN + '/fileStreamPreview?id=' + o.id)
vant.ImagePreview({images: ids})
} else if(type === 'weChat' && this.clickRow.wechatgroupcode) {
const ids = JSON.parse(this.clickRow.wechatgroupcode).map(o => FILE_DOMAIN + '/fileStreamPreview?id=' + o.id)
vant.ImagePreview({images: ids})
// 所有弹层由统一历史栈同步;页面不单独监听 popstate。
syncPopup(key, visible) {
if (key === 'info') this.$set(this, 'infoShow', visible)
if (key === 'birthday') this.$set(this, 'showPicker', visible)
if (key === 'confirm' && !visible) vant.Dialog.close()
if (key === 'preview' && !visible && this.clubPreview) this.clubPreview.close()
},
closePopup() {
return mobilePopupHistory.close()
},
leavePage() {
if (mobilePopupHistory.stack.length) {
this.closePopup()
return
}
this.disposePopup()
pjaxReplace('/mobile/index')
},
disposePopup() {
mobilePopupHistory.unregister(this.syncPopup)
$(document).off('pjax:beforeSend.clubScan')
},
openBirthday() {
// 选择器定位到系统出生日期;档案为空时允许用户补填。
const date = moment(this.formData.birthday, 'YYYY-MM-DD', true)
this.$set(this, 'birthdayPickerValue', date.isValid() ? date.toDate() : new Date())
mobilePopupHistory.open('birthday')
},
confirmBirthday(value) {
this.$set(this.formData, 'birthday', moment(value).format('YYYY-MM-DD'))
this.closePopup()
},
// 确认/取消先回退本层历史,系统返回由同步回调关闭确认框。
confirmAction(message) {
mobilePopupHistory.open('confirm')
return vant.Dialog.confirm({title: '提示', message, closeOnPopstate: false})
.then(() => this.closePopup())
.catch(() => {
if (mobilePopupHistory.stack.includes('confirm')) {
return this.closePopup().then(() => Promise.reject())
}
return Promise.reject()
})
},
showCode(type) {
const files = type === 'QQ' ? this.detailData.qqgroupcode : this.detailData.wechatgroupcode
if (!files) return
const images = (typeof files === 'string' ? JSON.parse(files) : files)
.map(o => FILE_DOMAIN + '/fileStreamPreview?id=' + o.id)
if (!images.length) return
mobilePopupHistory.open('preview')
this.clubPreview = vant.ImagePreview({
images, closeOnPopstate: false,
onClose: () => {
if (mobilePopupHistory.stack.includes('preview')) this.closePopup()
}
})
},
doSearch() {
this.pageForm.pageNumber = 1
@@ -361,7 +359,7 @@ layout("/mobile/platform.html"){
this.finished = false
this.onLoad()
},
async onLoad() {
onLoad() {
this.loading = true
$.post('/platform/sys/club/sq/pageData', this.pageForm).then(res => {
if (res.code === 0) {
@@ -372,99 +370,139 @@ layout("/mobile/platform.html"){
this.pageForm.pageNumber++
}
}
this.loading = false
})
}).always(() => { this.loading = false })
},
openInfo(row, type) {
this.viewType = type
this.infoActive = type === 'view' ? 0 : 1
if(type === 'join') {
this.formData = {
if (this.mLoading) return
this.mLoading = true
// clubId 是社团主键;data 返回详情及登录用户状态,不受列表页码、筛选影响。
$.post('/platform/sys/club/sq/scanDetail', {clubId: row.id}).then(res => {
if (res.code !== 0) {
vant.Toast(res.msg || '社团信息加载失败')
return
}
this.detailData = res.data
this.clickRow = res.data
this.viewType = 'view'
this.infoActive = 0
if (this.canJoin && (type === 'join' || type === 'scan')) {
this.prepareJoin()
}
// 等待条件页签及弹框渲染后再打开;扫码先展示社团信息,列表申请展示个人信息。
this.$nextTick(() => {
this.infoActive = type === 'join' && this.canJoin ? 1 : 0
mobilePopupHistory.open('info')
})
}).fail(() => vant.Toast('社团信息加载失败,请重试'))
.always(() => { this.mLoading = false })
},
startJoin() {
if (!this.canJoin) return
// 已进入加入模式时保留用户填写的数据,不因切换页签再次清空。
if (this.viewType !== 'join') this.prepareJoin()
this.$nextTick(() => { this.infoActive = 1 })
},
// 初始化当前社团的加入表单;扫码展示两个页签时也复用此方法。
prepareJoin() {
this.viewType = 'join'
this.$set(this, 'formData', {
username: "${@shiro.getPrincipalProperty('username')}",
sex: "${@shiro.getPrincipalProperty('sex')}",
loginname: "${@shiro.getPrincipalProperty('loginname')}",
birthday: "${@shiro.getPrincipalProperty('birthday')}",
birthPlace: "${@shiro.getPrincipalProperty('birthPlace')}",
education: "${@shiro.getPrincipalProperty('education')}",
hobby: "${@shiro.getPrincipalProperty('hobby')}",
unitName: "${@shiro.getPrincipalProperty('unit').getName()}",
position: "${@shiro.getPrincipalProperty('position')}",
mobile: "${@shiro.getPrincipalProperty('mobile')}",
email: "${@shiro.getPrincipalProperty('email')}",
homeAddress: "${@shiro.getPrincipalProperty('homeAddress')}",
}
}
this.clickRow = row
$.get("/platform/sys/club/mange/findOne", {id: row.id}, (data) => {
if (data.code === 0) {
this.detailData = data.data
this.infoShow = true
}
}, "json");
medicalHistory: null, otherThing: '', emergencyContact: '', emergencyMobile: ''
})
},
async needJoin() {
needJoin() {
if (this.formLoading || !this.canJoin) return
const row = this.clickRow
if(this.formData.medicalHistory === '' || this.formData.medicalHistory === undefined || this.formData.medicalHistory === null) {
vant.Toast('请选择是否有过特殊病史')
vant.Toast('请选择是否有特殊病史')
return
}
if(this.formData.joinActivity === '' || this.formData.joinActivity === undefined || this.formData.joinActivity === null) {
vant.Toast('请选择是否愿意参加本协会的活动')
return
}
if(this.formData.photo === '' || this.formData.photo === undefined || this.formData.photo === null) {
vant.Toast('请上传两寸登记照')
return
}
const {code, data} = await $.post('/platform/sys/club/sq/getInClubByCurUser')
let str = ''
if (data && data.length > 0) {
str = '您已经加入了'
data.forEach((item) => {
str += '【' + item.name + '】'
})
str += ','
}
str += '请确认是否申请加入【' + row.name + '】?'
vant.Dialog.confirm({title: '提示', message: str,}).then(() => {
this.formData.clubid = row.id
this.formData.photo = this.formData.photo[0].filepath
$.post("/platform/sys/club/sq/submit", this.formData, (data) => {
if (data.code === 0) {
vant.Toast(data.msg)
this.doSearch()
this.infoShow = false
} else {
vant.Toast(data.msg)
}
}, "json");
}).catch(() => {
});
this.$set(this, 'formLoading', true)
$.post('/platform/sys/club/sq/getInClubByCurUser').then(res => {
if (res.code !== 0) {
vant.Toast(res.msg)
return
}
const data = res.data
let str = ''
if (data && data.length > 0) {
str = '您已经加入了'
data.forEach((item) => {
str += '【' + item.name + '】'
})
str += ','
}
str += '请确认是否申请加入【' + row.name + '】?'
this.confirmAction(str).then(() => {
this.$set(this, 'formLoading', true)
// 仅提交精简后的入会资料,出生年月和电话不回写用户档案。
const params = Object.assign({}, this.formData, {
clubid: row.id
})
$.post("/platform/sys/club/sq/submit", params).then(data => {
if (data.code === 0) {
vant.Toast(data.msg)
mobilePopupHistory.clear().then(() => this.doSearch())
} else {
vant.Toast(data.msg)
}
}).always(() => { this.$set(this, 'formLoading', false) })
}).catch(() => {
});
}).always(() => { this.$set(this, 'formLoading', false) })
},
rollback(o) {
vant.Dialog.confirm({title: '提示', message: '请确定是否撤销申请?',}).then(() => {
this.confirmAction('请确定是否撤销申请?').then(() => {
const id = o.id
$.post("/platform/sys/club/sq/revocation", {id}, (data) => {
this.$set(this, 'formLoading', true)
$.post("/platform/sys/club/sq/revocation", {id}).then(data => {
if (data.code === 0) {
vant.Toast('撤销申请成功');
this.doSearch();
} else {
vant.Toast(data.msg);
}
}, "json");
}).always(() => { this.$set(this, 'formLoading', false) })
}).catch(() => {
});
}
},
async created() {
const data = await getClubType()
data.forEach(item => {
this.typeOptions.push({text: item.name, value: item.code})
created() {
mobilePopupHistory.register(this.syncPopup)
// PJAX 离开前先清理弹框历史,重新发起原页面跳转,并注销本页回调。
$(document).on('pjax:beforeSend.clubScan', (event, xhr, options) => {
if (mobilePopupHistory.stack.length) {
event.preventDefault()
mobilePopupHistory.clear().then(() => {
this.disposePopup()
pjaxReplace(options.url)
})
return false
}
this.disposePopup()
})
this.typeOptions.unshift({text: '全部类型'})
this.$set(this.pageForm, "clubType", this.typeOptions[0].value)
this.$set(this.pageForm, "isjr", this.clubType[0].value)
this.pageForm.searchName = 'club.name'
this.$set(this.pageForm, 'isjr', false)
this.$set(this.pageForm, 'searchName', 'club.name')
this.onLoad()
getClubType().then(data => {
data.forEach(item => {
this.typeOptions.push({text: item.name, value: item.code})
})
this.typeOptions.unshift({text: '全部类型'})
this.$set(this.pageForm, "clubType", this.typeOptions[0].value)
})
},
mounted() {
// 兼容已有二维码;无 clubId 的普通入口仍显示列表,不猜测目标社团。
const clubId = this.scanClubId || new URLSearchParams(window.location.search).get('clubId')
if (clubId) this.openInfo({id: clubId}, 'scan')
},
beforeDestroy() {
mobilePopupHistory.clear().then(() => this.disposePopup())
}
})
</script>
@@ -560,7 +560,12 @@ layout("/layouts/platform.html"){
},
async created() {
this.pageData();
if ("${@shiro.hasRole('sysadmin')||@shiro.hasRole('A06')||@shiro.hasRole('H03')}" === 'true') {
// 分工会主席可能兼具 H03 角色,需优先按当前分工会加载查询选项。
if ("${@shiro.hasRole('H04')&&!(@shiro.hasRole('sysadmin')||@shiro.hasRole('A06'))}" === 'true') {
this.unions = await getUnions(null, true)
this.$set(this.pageForm, 'unionId', this.unions ? this.unions[0].id : null)
this.flushUnits()
} else if ("${@shiro.hasRole('sysadmin')||@shiro.hasRole('A06')||@shiro.hasRole('H03')}" === 'true') {
this.unions = await getUnions(null, false)
} else {
this.unions = await getUnions(null, true)
@@ -574,4 +579,4 @@ layout("/layouts/platform.html"){
</script>
<!--#
}
#-->
#-->
@@ -58,6 +58,38 @@ layout("/layouts/platform.html"){
margin: 0 0 18px;
}
/* 仅调整入会表单,避免影响公共表格组件及其他业务页面。 */
#app .club-apply-form th,
#app .club-apply-form .el-form-item__label {
text-align: center;
}
#app .club-apply-form .el-form-item__label {
width: 100%;
}
#app .club-apply-form th.club-required::before {
content: "*";
color: #f56c6c;
margin-right: 4px;
}
/* 校验信息占据字段下方的正常文档流,长提示也不会遮挡下一行。 */
#app .club-apply-form .el-form-item__error {
position: relative;
top: auto;
left: auto;
z-index: auto;
background: transparent;
color: #f56c6c;
border-radius: 0;
padding: 4px 0 0;
min-width: 0;
font-size: 12px;
line-height: 1.4;
text-align: left;
}
</style>
<div id="app" v-cloak>
@@ -142,10 +174,11 @@ layout("/layouts/platform.html"){
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作" width="350px">
<el-table-column align="center" header-align="center" label="操作" width="430px">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="openDetail(scope.row, 'view')">查看
</el-button>
<el-button size="mini" type="primary" @click="openClubCode(scope.row)">二维码</el-button>
<el-button type="primary" size="mini" v-if="activeName=='true'" @click="doExportApply(scope.row)">导出申请表</el-button>
<!-- <el-button size="mini" v-if="activeName=='false'" type="primary"-->
<!-- @click="openDetail(scope.row, 'join')">-->
@@ -254,157 +287,57 @@ layout("/layouts/platform.html"){
</el-descriptions>
</el-tab-pane>
<el-tab-pane v-if="viewType === 'join'" name="second" label="个人信息">
<el-form :model="formData" ref="form" :rules="formRules" label-position="top"
label-width="120px">
<el-form class="club-apply-form" :model="formData" ref="form" :rules="formRules" label-position="top" label-width="160px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="username" label="姓名">
<el-input v-model="formData.username" disabled></el-input>
<el-input v-model="formData.username" readonly></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="sex" label="性别">
<el-input v-model="formData.sex" disabled></el-input>
<el-input v-model="formData.sex" readonly></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="birthday" label="出生年月">
<el-date-picker
v-model="formData.birthday"
type="date"
value-format="yyyy-MM-dd"
style="width: 100%"
placeholder="请选择出生年月">
</el-date-picker>
<el-form-item prop="loginname" label="工号">
<el-input v-model="formData.loginname" readonly></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="birthPlace" label="出生地">
<el-input v-model="formData.birthPlace"
placeholder="请填写出生地"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="education" label="文化程度">
<el-input v-model="formData.education" placeholder="请填写文化程度"></el-input>
<el-form-item prop="birthday" label="出生年月">
<el-date-picker v-model="formData.birthday" type="date" value-format="yyyy-MM-dd" style="width: 100%" placeholder="请选择出生年月"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="hobby" label="爱好">
<el-input v-model="formData.hobby" placeholder="请填写爱好"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="unitName" label="工作部门">
<el-input v-model="formData.unitName" disabled></el-input>
<el-form-item prop="mobile" label="联系电话">
<el-input v-model="formData.mobile" maxlength="20" placeholder="请填写联系电话"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="position" label="职务">
<el-input v-model="formData.position" placeholder="请填写职务"></el-input>
<el-form-item prop="medicalHistory" label="是否有特殊病史">
<el-radio-group v-model="formData.medicalHistory"><el-radio :label="true">是</el-radio><el-radio :label="false">否</el-radio></el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="mobile" label="电话">
<el-input v-model="formData.mobile" placeholder="请填写电话"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="email" label="电子邮箱">
<el-input v-model="formData.email" placeholder="请填写电子邮箱"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="homeAddress" label="家庭住址">
<el-input v-model="formData.homeAddress" placeholder="请填写家庭住址"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="QQNumber" label="QQ">
<el-input v-model="formData.QQNumber" placeholder="请填写QQ"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="bodyHeight" label="身高">
<el-input v-model="formData.bodyHeight" placeholder="请填写身高"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="bodyWeight" label="体重">
<el-input v-model="formData.bodyWeight" placeholder="请填写体重"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="health" label="身体状况">
<el-input v-model="formData.health" placeholder="请填写身体状况"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="sport" label="经常从事的运动">
<el-input v-model="formData.sport" placeholder="请填写经常从事的运动"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item prop="medicalHistory" label="是否有过特殊病史">
<el-radio-group v-model="formData.medicalHistory">
<el-radio :label="true" border>是</el-radio>
<el-radio :label="false" border>否</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="joinActivity" label="是否愿意参加本协会的活动">
<el-radio-group v-model="formData.joinActivity">
<el-radio :label="true" border>是</el-radio>
<el-radio :label="false" border>否</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item prop="otherThing" label="是否有特别需要说明的问题(身体或心理)">
<el-input maxlength="500" v-model="formData.otherThing"
placeholder="如有,请填写特别需要说明的问题"
type="textarea" :autosize="{ minRows: 4, maxRows: 8}"></el-input>
<el-form-item prop="otherThing" label="是否有特别需要说明的问题">
<el-input v-model="formData.otherThing" maxlength="100" type="textarea" placeholder="如有,请填写特别需要说明的问题"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item prop="remark" label="备注">
<el-input maxlength="100" v-model="formData.remark" placeholder="请填写备注"
type="textarea" :autosize="{ minRows: 4, maxRows: 8}"></el-input>
<el-col :span="12">
<el-form-item prop="emergencyContact" label="紧急联系人">
<el-input v-model="formData.emergencyContact" maxlength="50" placeholder="请填写紧急联系人"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item prop="photo" label="两寸登记照">
<image-Upload :height="50" :limit="1" :file-type="['png', 'jpg']" :file-size="1"
v-model="formData.photo"></image-Upload>
<el-col :span="12">
<el-form-item prop="emergencyMobile" label="紧急联系电话">
<el-input v-model="formData.emergencyMobile" maxlength="20" placeholder="请填写紧急联系电话"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div style="float: right;margin: 20px 0">
<el-button @click="doSubmit()" type="primary">申请加入</el-button>
<el-button @click="doSubmit()" :loading="formLoading" type="primary">申请加入</el-button>
</div>
</el-tab-pane>
</el-tabs>
@@ -417,190 +350,98 @@ layout("/layouts/platform.html"){
<div>填表时间:{{moment().format('YYYY年MM月DD日')}}</div>
<div>编号:NO._____(自动生成)</div>
</div>
<el-form :model="formData"
ref="form"
:rules="formRules"
label-position="top"
class="applyForm"
label-width="0">
<el-form class="club-apply-form" :model="formData" ref="form" :rules="formRules" label-position="top" label-width="160px">
<border-table>
<table>
<tr>
<th>姓名</th>
<td>{{formData.username}}</td>
<th>性别</th>
<th>{{formData.sex}}</th>
<th rowspan="4">
<el-form-item prop="photo">
<image-Upload :limit="1"
:file-type="['png', 'jpg','jpeg']"
:file-size="5"
width="150"
height="200"
:file-size="1"
v-model="formData.photo"></image-Upload>
<th class="club-required">姓名</th>
<td>
<el-form-item prop="username">
<el-input v-model="formData.username" readonly></el-input>
</el-form-item>
</th>
</td>
</tr>
<tr>
<th>出生年月</th>
<th class="club-required">性别</th>
<td>
<el-form-item prop="sex">
<el-input v-model="formData.sex" readonly></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th class="club-required">工号</th>
<td>
<el-form-item prop="loginname">
<el-input v-model="formData.loginname" readonly></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th class="club-required">出生年月</th>
<td>
<el-form-item prop="birthday">
<el-date-picker
v-model="formData.birthday"
type="date"
style="width: 100%"
value-format="yyyy-MM-dd"
placeholder="请选择出生年月">
</el-date-picker>
</el-form-item>
</td>
<th>出生地</th>
<td>
<el-form-item prop="birthPlace">
<el-input v-model="formData.birthPlace"
maxlength="50"
placeholder="请填写出生地"></el-input>
<el-date-picker v-model="formData.birthday" type="date" value-format="yyyy-MM-dd" style="width: 100%" placeholder="请选择出生年月"></el-date-picker>
</el-form-item>
</td>
</tr>
<tr>
<th>文化程度</th>
<td>
<el-form-item prop="education">
<el-input v-model="formData.education" placeholder="请填写文化程度"
maxlength="20"
></el-input>
</el-form-item>
</td>
<th>爱好</th>
<td>
<el-form-item prop="hobby">
<el-input v-model="formData.hobby" placeholder="请填写爱好" maxlength="100"></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th>工作部门</th>
<td>
<el-form-item prop="unitName">
<el-input v-model="formData.unitName" disabled maxlength="100"></el-input>
</el-form-item>
</td>
<th>职务</th>
<td>
<el-form-item prop="position">
<el-input v-model="formData.position" placeholder="请填写职务" maxlength="100"></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th>电话</th>
<th class="club-required">联系电话</th>
<td>
<el-form-item prop="mobile">
<el-input v-model="formData.mobile" placeholder="请填写电话" maxlength="20"></el-input>
</el-form-item>
</td>
<th>电子邮箱</th>
<td colspan="2">
<el-form-item prop="email">
<el-input v-model="formData.email" placeholder="请填写电子邮箱" maxlength="100"></el-input>
<el-input v-model="formData.mobile" maxlength="20" placeholder="请填写联系电话"></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th>家庭住址</th>
<th class="club-required">是否有特殊病史</th>
<td>
<el-form-item prop="homeAddress">
<el-input v-model="formData.homeAddress" placeholder="请填写家庭住址" maxlength="100"></el-input>
</el-form-item>
</td>
<th>QQ</th>
<td colspan="2">
<el-form-item prop="QQNumber">
<el-input v-model="formData.QQNumber" placeholder="请填写QQ" maxlength="12"></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th>身高</th>
<td>
<el-form-item prop="bodyHeight">
<el-input v-model="formData.bodyHeight" placeholder="请填写身高" maxlength="10"></el-input>
</el-form-item>
</td>
<th>体重</th>
<td colspan="2">
<el-form-item prop="bodyWeight">
<el-input v-model="formData.bodyWeight" placeholder="请填写体重" maxlength="10"></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th>身体状况</th>
<td>
<el-form-item prop="health">
<el-input v-model="formData.health" placeholder="请填写身体状况" maxlength="10"></el-input>
</el-form-item>
</td>
<th>经常从事的运动</th>
<td colspan="2">
<el-form-item prop="sport">
<el-input v-model="formData.sport" placeholder="请填写经常从事的运动" maxlength="100"></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th>是否有过特殊病史</th>
<td colspan="4">
<el-form-item prop="medicalHistory">
<el-radio-group v-model="formData.medicalHistory">
<el-radio :label="true" border>是</el-radio>
<el-radio :label="false" border>否</el-radio>
</el-radio-group>
<el-radio-group v-model="formData.medicalHistory"><el-radio :label="true">是</el-radio><el-radio :label="false">否</el-radio></el-radio-group>
</el-form-item>
</td>
</tr>
<tr>
<th>是否愿意参加本协会的活动</th>
<td colspan="4">
<el-form-item prop="joinActivity">
<el-radio-group v-model="formData.joinActivity">
<el-radio :label="true" border>是</el-radio>
<el-radio :label="false" border>否</el-radio>
</el-radio-group>
</el-form-item>
</td>
</tr>
<tr>
<th>是否有特别需要说明的问题(身体或心理)</th>
<td colspan="4">
<th>是否有特别需要说明的问题</th>
<td>
<el-form-item prop="otherThing">
<el-input maxlength="100" v-model="formData.otherThing"
placeholder="如有,请填写特别需要说明的问题"
type="textarea" :autosize="{ minRows: 4, maxRows: 8}"></el-input>
<el-input v-model="formData.otherThing" maxlength="100" type="textarea" placeholder="如有,请填写特别需要说明的问题"></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th class="club-required">紧急联系人</th>
<td>
<el-form-item prop="emergencyContact">
<el-input v-model="formData.emergencyContact" maxlength="50" placeholder="请填写紧急联系人"></el-input>
</el-form-item>
</td>
</tr>
<tr>
<th class="club-required">紧急联系电话</th>
<td>
<el-form-item prop="emergencyMobile">
<el-input v-model="formData.emergencyMobile" maxlength="20" placeholder="请填写紧急联系电话"></el-input>
</el-form-item>
</td>
</tr>
</table>
</border-table>
<!-- <el-row :gutter="20">-->
<!-- <el-col :span="24">-->
<!-- <el-form-item prop="remark" label="备注">-->
<!-- <el-input maxlength="100" v-model="formData.remark" placeholder="请填写备注"-->
<!-- type="textarea" :autosize="{ minRows: 4, maxRows: 8}"></el-input>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<!-- </el-row>-->
</el-form>
<div style="text-align: center;margin: 20px 0">
<el-button @click="doSubmit()" type="primary">申请加入</el-button>
<el-button @click="doSubmit()" :loading="formLoading" type="primary">申请加入</el-button>
</div>
</div>
</template>
</guava>
<el-dialog title="社团二维码" :visible.sync="clubCodeShow" width="360px" :close-on-click-modal="false">
<div style="text-align: center">
<p>{{clubCodeName}}</p>
<img :src="clubCodeImage" alt="扫码查看社团并申请加入" style="width: 260px; height: 260px">
<p>手机扫码查看社团并申请加入</p>
</div>
</el-dialog>
</div>
<script>
const vue = new Vue({
@@ -608,26 +449,19 @@ layout("/layouts/platform.html"){
data() {
return {
formData: {},
formLoading: false,
clubCodeShow: false,
clubCodeName: '',
clubCodeImage: '',
formRules: {
username: [{required: true, message: '必填', trigger: ['blur', 'change']}],
sex: [{required: true, message: '必填', trigger: ['blur', 'change']}],
birthday: [{required: true, message: '必填', trigger: ['blur', 'change']}],
birthPlace: [{required: true, message: '必填', trigger: ['blur', 'change']}],
education: [{required: true, message: '必填', trigger: ['blur', 'change']}],
hobby: [{required: true, message: '必填', trigger: ['blur', 'change']}],
unitName: [{required: true, message: '必填', trigger: ['blur', 'change']}],
position: [{required: true, message: '必填', trigger: ['blur', 'change']}],
mobile: [{required: true, message: '必填', trigger: ['blur', 'change']}],
email: [{required: true, message: '必填', trigger: ['blur', 'change']}],
homeAddress: [{required: true, message: '必填', trigger: ['blur', 'change']}],
QQNumber: [{required: true, message: '必填', trigger: ['blur', 'change']}],
bodyHeight: [{required: true, message: '必填', trigger: ['blur', 'change']}],
bodyWeight: [{required: true, message: '必填', trigger: ['blur', 'change']}],
health: [{required: true, message: '必填', trigger: ['blur', 'change']}],
sport: [{required: true, message: '必填', trigger: ['blur', 'change']}],
medicalHistory: [{required: true, message: '必填', trigger: ['blur', 'change']}],
joinActivity: [{required: true, message: '必填', trigger: ['blur', 'change']}],
photo: [{required: true, message: '必填', trigger: ['blur', 'change']}],
username: [{required: true, message: '请填写姓名', trigger: ['blur', 'change']}],
sex: [{required: true, message: '请填写性别', trigger: ['blur', 'change']}],
loginname: [{required: true, message: '请填写工号', trigger: ['blur', 'change']}],
birthday: [{required: true, message: '请填写出生年月', trigger: ['blur', 'change']}],
mobile: [{required: true, message: '请填写联系电话', trigger: ['blur', 'change']}],
medicalHistory: [{required: true, message: '请选择是否有特殊病史', trigger: ['blur', 'change']}],
emergencyContact: [{required: true, message: '请填写紧急联系人', trigger: ['blur', 'change']}],
emergencyMobile: [{required: true, message: '请填写紧急联系电话', trigger: ['blur', 'change']}],
},
infoActive: 'first',
detailData: {},
@@ -650,6 +484,13 @@ layout("/layouts/platform.html"){
}
},
methods: {
// 二维码携带当前行社团主键,使用系统配置域名供手机访问。
openClubCode(row) {
this.clubCodeName = row.name
this.clubCodeImage = jrQrcode.getQrBase64(APP_DOMAIN.replace(/\/$/, '') +
'/platform/sys/club/sq/mobile?clubId=' + encodeURIComponent(row.id))
this.clubCodeShow = true
},
doExportApply(row){
location.href = '/platform/sys/club/clubInfoManage/exportInfo?clubId=' + row.id
},
@@ -672,56 +513,50 @@ layout("/layouts/platform.html"){
}
});
},
async doSubmit() {
const row = this.clickRow
const valid = await this.$refs.form.validate()
if (!valid) return
const {code, data} = await $.post('/platform/sys/club/sq/getInClubByCurUser')
let str = '您还没有参加协会'
if (data && data.length > 0) {
str = '您已经加入了'
data.forEach((item) => {
str += '【' + item.name + '】'
})
}
str += ',请确认是否申请加入【' + row.name + '】?'
this.$confirm(str, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
callback: async (a, b) => {
if ("confirm" === a) {//确认后再执行
this.formData.clubid = row.id
const resp = await $.post("/platform/sys/club/sq/submit", this.formData);
if (resp.code === 0) {
this.$message.success(resp.msg)
await this.getCount()
this.pageData()
this.$refs.guava.index()
} else {
this.$message.warning(resp.msg)
}
// 两处 PC 申请入口共用校验与提交,仅保存本次入会资料。
doSubmit() {
if (this.formLoading) return
this.$refs.form.validate(valid => {
if (!valid) return
this.$set(this, 'formLoading', true)
$.post('/platform/sys/club/sq/getInClubByCurUser').then(res => {
if (res.code !== 0) {
this.$message.warning(res.msg)
return
}
}
});
const clubs = res.data || []
const prefix = clubs.length ? '您已经加入了' + clubs.map(item => '【' + item.name + '】').join('') : '您还没有参加协会'
this.$confirm(prefix + ',请确认是否申请加入【' + this.clickRow.name + '】?', '提示', {
confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'
}).then(() => {
this.$set(this, 'formLoading', true)
const params = Object.assign({}, this.formData, {clubid: this.clickRow.id})
$.post('/platform/sys/club/sq/submit', params).then(resp => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.getCount()
this.pageData()
this.$refs.guava.index()
} else {
this.$message.warning(resp.msg)
}
}).always(() => { this.$set(this, 'formLoading', false) })
}).catch(() => {})
}).always(() => { this.$set(this, 'formLoading', false) })
})
},
openDetail(row, type) {
this.viewType = type
this.infoActive = type === 'view' ? 'first' : 'second'
if (type === 'join') {
this.formData = {
this.$set(this, 'formData', {
username: "${@shiro.getPrincipalProperty('username')}",
sex: "${@shiro.getPrincipalProperty('sex')}",
loginname: "${@shiro.getPrincipalProperty('loginname')}",
birthday: "${@shiro.getPrincipalProperty('birthday')}",
birthPlace: "${@shiro.getPrincipalProperty('birthPlace')}",
education: "${@shiro.getPrincipalProperty('education')}",
hobby: "${@shiro.getPrincipalProperty('hobby')}",
unitName: "${@shiro.getPrincipalProperty('unit').getName()}",
position: "${@shiro.getPrincipalProperty('position')}",
mobile: "${@shiro.getPrincipalProperty('mobile')}",
email: "${@shiro.getPrincipalProperty('email')}",
homeAddress: "${@shiro.getPrincipalProperty('homeAddress')}",
}
medicalHistory: null, otherThing: '', emergencyContact: '', emergencyMobile: ''
})
this.$nextTick(() => {
this.$refs.form.clearValidate()
})
@@ -743,19 +578,14 @@ layout("/layouts/platform.html"){
openApply(row) {
this.$refs.guava.edit()
this.clickRow = row
this.formData = {
username: "${@shiro.getPrincipalProperty('username')}",
sex: "${@shiro.getPrincipalProperty('sex')}",
birthday: "${@shiro.getPrincipalProperty('birthday')}",
birthPlace: "${@shiro.getPrincipalProperty('birthPlace')}",
education: "${@shiro.getPrincipalProperty('education')}",
hobby: "${@shiro.getPrincipalProperty('hobby')}",
unitName: "${@shiro.getPrincipalProperty('unit').getName()}",
position: "${@shiro.getPrincipalProperty('position')}",
mobile: "${@shiro.getPrincipalProperty('mobile')}",
email: "${@shiro.getPrincipalProperty('email')}",
homeAddress: "${@shiro.getPrincipalProperty('homeAddress')}",
}
this.$set(this, 'formData', {
username: "${@shiro.getPrincipalProperty('username')}",
sex: "${@shiro.getPrincipalProperty('sex')}",
loginname: "${@shiro.getPrincipalProperty('loginname')}",
birthday: "${@shiro.getPrincipalProperty('birthday')}",
mobile: "${@shiro.getPrincipalProperty('mobile')}",
medicalHistory: null, otherThing: '', emergencyContact: '', emergencyMobile: ''
})
this.$nextTick(() => {
this.$refs.form.clearValidate()
})
@@ -800,15 +630,17 @@ layout("/layouts/platform.html"){
}
}, "json");
},
async getCount() {
const resp = await $.post('/platform/sys/club/sq/getCount')
this.hasJoinCount = resp.data.hasJoinCount
this.noJoinCount = resp.data.noJoinCount
getCount() {
return $.post('/platform/sys/club/sq/getCount').then(resp => {
if (resp.code === 0) {
this.$set(this, 'hasJoinCount', resp.data.hasJoinCount)
this.$set(this, 'noJoinCount', resp.data.noJoinCount)
}
})
}
},
async created() {
await this.getCount()
this.pageData()
created() {
this.getCount().always(() => this.pageData())
}
})
</script>
@@ -58,7 +58,9 @@ layout("/layouts/platform.html"){
<template #func>
<el-button @click="exportData" type="primary" size="medium">导出全部统计数据</el-button>
<el-button @click="exportUserData(null)" v-if="${@shiro.hasAnyRoles('sysadmin', 'A06', 'xxhgly')}"
type="primary" size="medium">导出全部人员明细</el-button>
type="primary" size="medium">导出全部人员明细(Zip)</el-button>
<el-button @click="exportAllUserExcel" v-if="${@shiro.hasAnyRoles('sysadmin', 'A06', 'xxhgly')}"
type="primary" size="medium">导出全部人员明细(Excel)</el-button>
<el-button @click="exportFiles(null)" v-if="${@shiro.hasAnyRoles('sysadmin', 'A06', 'xxhgly')}"
type="primary" size="medium">导出全部上传资料</el-button>
</template>
@@ -225,6 +227,10 @@ layout("/layouts/platform.html"){
'dict-select': httpVueLoader('/components/plugins/DictSelect.vue?v=1.0.0'),
},
methods: {
exportAllUserExcel() {
// 导出权限范围内全部有效成员,不携带页面筛选或分页参数。
window.open('/platform/sys/club/clubUserCount/exportAllUserExcel')
},
exportUserData(row) {
const id = row === null ? '' : row.id
let url = '/platform/sys/club/clubUserCount/exportUserData?clubId=' + id +
@@ -1129,8 +1129,8 @@ layout("/layouts/platform.html"){
'tree-layout': httpVueLoader('/components/plugins/TreeLayout.vue'),
'dict-select': httpVueLoader('/components/plugins/DictSelect.vue'),
'union-cadre': httpVueLoader('/components/sys/union/UnionCadreMange.vue?v=1.0.89'),
'union-cadre-mange': httpVueLoader('/components/sys/union/cadre/Mange.vue?v=1.0.5'),
'union-cadre-audit': httpVueLoader('/components/sys/union/cadre/Audit.vue?v=1.0.5'),
'union-cadre-mange': httpVueLoader('/components/sys/union/cadre/Mange.vue?v=1.0.9'),
'union-cadre-audit': httpVueLoader('/components/sys/union/cadre/Audit.vue?v=1.0.7'),
},
watch: {
filterText(val) {