commit
This commit is contained in:
@@ -233,6 +233,11 @@ public class MemberApplyRecord extends BaseModel {
|
|||||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
private String sign;
|
private String sign;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("照片")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||||
|
private String photo;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("来源,高校编码")
|
@Comment("来源,高校编码")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
|||||||
+118
-8
@@ -40,6 +40,15 @@ import com.deepoove.poi.XWPFTemplate;
|
|||||||
import com.deepoove.poi.config.Configure;
|
import com.deepoove.poi.config.Configure;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.ddr.poi.html.HtmlRenderPolicy;
|
import org.ddr.poi.html.HtmlRenderPolicy;
|
||||||
|
import org.apache.poi.xwpf.usermodel.LineSpacingRule;
|
||||||
|
import org.apache.poi.util.Units;
|
||||||
|
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFRun;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFTable;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
|
||||||
|
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
|
||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.*;
|
import org.nutz.dao.*;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
@@ -52,10 +61,10 @@ import org.nutz.ioc.loader.annotation.IocBean;
|
|||||||
import org.nutz.lang.Lang;
|
import org.nutz.lang.Lang;
|
||||||
import org.nutz.lang.random.R;
|
import org.nutz.lang.random.R;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
|
||||||
|
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -77,6 +86,13 @@ import java.util.zip.ZipOutputStream;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implements MemberCommonService {
|
public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implements MemberCommonService {
|
||||||
|
|
||||||
|
private static final int MEMBER_APPLY_PHOTO_WIDTH_PIXEL = 100;
|
||||||
|
private static final int MEMBER_APPLY_PHOTO_HEIGHT_PIXEL = 140;
|
||||||
|
private static final int MEMBER_APPLY_PHOTO_WIDTH_EMU = Units.pixelToEMU(MEMBER_APPLY_PHOTO_WIDTH_PIXEL);
|
||||||
|
private static final int MEMBER_APPLY_PHOTO_HEIGHT_EMU = Units.pixelToEMU(MEMBER_APPLY_PHOTO_HEIGHT_PIXEL);
|
||||||
|
private static final int MEMBER_APPLY_PHOTO_SIZE_TOLERANCE_EMU = Units.pixelToEMU(2);
|
||||||
|
private static final double MEMBER_APPLY_PHOTO_PARAGRAPH_LINE_POINT = MEMBER_APPLY_PHOTO_HEIGHT_PIXEL * 0.75D;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SysDictService sysDictService;
|
private SysDictService sysDictService;
|
||||||
@Inject
|
@Inject
|
||||||
@@ -624,7 +640,7 @@ public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implement
|
|||||||
|
|
||||||
docData.put("nativePlace", member.getNativePlace());
|
docData.put("nativePlace", member.getNativePlace());
|
||||||
docData.put("marriage", member.getMarriage());
|
docData.put("marriage", member.getMarriage());
|
||||||
docData.put("specialty", StrUtil.isNotBlank(member.getSpecialty()) ? HtmlUtil.cleanHtmlTag(member.getSpecialty()) : "");
|
docData.put("specialty", buildMemberApplyDocHtml(member.getSpecialty()));
|
||||||
|
|
||||||
docData.put("jobCategory", member.getJobCategory());
|
docData.put("jobCategory", member.getJobCategory());
|
||||||
docData.put("idCard", member.getIdCard());
|
docData.put("idCard", member.getIdCard());
|
||||||
@@ -633,7 +649,8 @@ public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implement
|
|||||||
docData.put("arrivalAtSchoolDate", StrUtil.isNotBlank(member.getArrivalAtSchoolDate()) ? DateUtil.parse(member.getArrivalAtSchoolDate()).toString("yyyy-MM-dd") : "");
|
docData.put("arrivalAtSchoolDate", StrUtil.isNotBlank(member.getArrivalAtSchoolDate()) ? DateUtil.parse(member.getArrivalAtSchoolDate()).toString("yyyy-MM-dd") : "");
|
||||||
docData.put("homeAddress", member.getHomeAddress());
|
docData.put("homeAddress", member.getHomeAddress());
|
||||||
|
|
||||||
docData.put("personalData", sysOfficeTemplateUtil.convertRichTextToDocText(member.getPersonalData()));
|
docData.put("personalData", buildMemberApplyDocHtml(member.getPersonalData()));
|
||||||
|
docData.put("photo", sysOfficeTemplateUtil.createPictureRenderData(MEMBER_APPLY_PHOTO_WIDTH_PIXEL, MEMBER_APPLY_PHOTO_HEIGHT_PIXEL, member.getPhoto()));
|
||||||
docData.put("sign", sysOfficeTemplateUtil.createPictureRenderData(member.getSign()));
|
docData.put("sign", sysOfficeTemplateUtil.createPictureRenderData(member.getSign()));
|
||||||
docData.put("applyDateTime", member.getApplyDateTime() != null ? DateUtil.format(member.getApplyDateTime(), "yyyy年MM月dd日") : "");
|
docData.put("applyDateTime", member.getApplyDateTime() != null ? DateUtil.format(member.getApplyDateTime(), "yyyy年MM月dd日") : "");
|
||||||
|
|
||||||
@@ -702,16 +719,109 @@ public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implement
|
|||||||
|
|
||||||
Configure config = Configure.builder()
|
Configure config = Configure.builder()
|
||||||
.bind("personalData", htmlRenderPolicy)
|
.bind("personalData", htmlRenderPolicy)
|
||||||
|
.bind("specialty", htmlRenderPolicy)
|
||||||
.build();
|
.build();
|
||||||
try {
|
try {
|
||||||
XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("member_apply_form"), config)
|
XWPFTemplate template = XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("member_apply_form"), config)
|
||||||
.render(docData)
|
.render(docData);
|
||||||
.write(response.getOutputStream());
|
resizeMemberApplyPhotoRow(template.getXWPFDocument());
|
||||||
} catch (IOException e) {
|
template.write(response.getOutputStream());
|
||||||
|
} catch (Exception e) {
|
||||||
log.error("导出会员入会申请表失败,ID: {}, 错误信息: {}", id, e.getMessage());
|
log.error("导出会员入会申请表失败,ID: {}, 错误信息: {}", id, e.getMessage());
|
||||||
throw new RuntimeException("导出文件失败", e);
|
throw new RuntimeException("导出文件失败", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入会申请导出时统一转为 HTML 片段,历史富文本保留样式,普通文本保留换行。
|
||||||
|
*/
|
||||||
|
private String buildMemberApplyDocHtml(String text) {
|
||||||
|
if (StrUtil.isBlank(text)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String docText = sysOfficeTemplateUtil.convertRichTextToDocText(text);
|
||||||
|
if (containsHtmlTag(docText)) {
|
||||||
|
return docText;
|
||||||
|
}
|
||||||
|
String escapeText = HtmlUtil.escape(docText)
|
||||||
|
.replace("\r\n", "\n")
|
||||||
|
.replace("\r", "\n")
|
||||||
|
.replace("\n", "<br/>");
|
||||||
|
return "<p>" + escapeText + "</p>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断内容是否包含 HTML 标签,避免把历史富文本当普通文本转义。
|
||||||
|
*/
|
||||||
|
private boolean containsHtmlTag(String text) {
|
||||||
|
return StrUtil.isNotBlank(text) && text.matches("(?s).*<\\s*[a-zA-Z][^>]*>.*");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep the member photo row tall enough so Word does not clip the default inline picture.
|
||||||
|
*/
|
||||||
|
private void resizeMemberApplyPhotoRow(XWPFDocument document) {
|
||||||
|
if (document == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (XWPFTable table : document.getTables()) {
|
||||||
|
for (XWPFTableRow row : table.getRows()) {
|
||||||
|
adjustMemberApplyPhotoParagraph(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match only the two-inch member photo by rendered picture size, avoiding signature pictures.
|
||||||
|
*/
|
||||||
|
private boolean adjustMemberApplyPhotoParagraph(XWPFTableRow row) {
|
||||||
|
if (row == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
boolean found = false;
|
||||||
|
for (XWPFTableCell cell : row.getTableCells()) {
|
||||||
|
for (XWPFParagraph paragraph : cell.getParagraphs()) {
|
||||||
|
for (XWPFRun run : paragraph.getRuns()) {
|
||||||
|
if (runContainsMemberApplyPhoto(run)) {
|
||||||
|
adjustMemberApplyPhotoParagraphStyle(paragraph);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep the inline photo visible without changing the merged cell vertical anchor.
|
||||||
|
*/
|
||||||
|
private void adjustMemberApplyPhotoParagraphStyle(XWPFParagraph paragraph) {
|
||||||
|
paragraph.setAlignment(ParagraphAlignment.CENTER);
|
||||||
|
paragraph.setSpacingBefore(0);
|
||||||
|
paragraph.setSpacingAfter(0);
|
||||||
|
paragraph.setSpacingBeforeLines(0);
|
||||||
|
paragraph.setSpacingAfterLines(0);
|
||||||
|
paragraph.setSpacingBetween(MEMBER_APPLY_PHOTO_PARAGRAPH_LINE_POINT, LineSpacingRule.AT_LEAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean runContainsMemberApplyPhoto(XWPFRun run) {
|
||||||
|
if (run == null || run.getCTR() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (CTDrawing drawing : run.getCTR().getDrawingArray()) {
|
||||||
|
for (CTInline inline : drawing.getInlineArray()) {
|
||||||
|
if (inline.getExtent() != null && isMemberApplyPhotoSize(inline.getExtent().getCx(), inline.getExtent().getCy())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMemberApplyPhotoSize(long widthEmu, long heightEmu) {
|
||||||
|
return Math.abs(widthEmu - MEMBER_APPLY_PHOTO_WIDTH_EMU) <= MEMBER_APPLY_PHOTO_SIZE_TOLERANCE_EMU
|
||||||
|
&& Math.abs(heightEmu - MEMBER_APPLY_PHOTO_HEIGHT_EMU) <= MEMBER_APPLY_PHOTO_SIZE_TOLERANCE_EMU;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,14 +54,19 @@ const INFO = {
|
|||||||
<el-empty v-else :image-size="50" description="暂无家庭成员信息"></el-empty>
|
<el-empty v-else :image-size="50" description="暂无家庭成员信息"></el-empty>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="个人学习及工作经历" :span="3">
|
<el-descriptions-item label="个人学习及工作经历" :span="3">
|
||||||
<div v-if="viewData.personalData" class="text-left w-e-text member-apply-rich-text" v-html="viewData.personalData"></div>
|
<div v-if="viewData.personalData" class="text-left w-e-text member-apply-rich-text" style="white-space: pre-wrap; word-break: break-all;" v-html="viewData.personalData"></div>
|
||||||
<el-tag type="warning" v-else>暂无</el-tag>
|
<el-tag type="warning" v-else>暂无</el-tag>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="特长及获奖情况" :span="3">
|
<el-descriptions-item label="特长及获奖情况" :span="3">
|
||||||
<div v-if="viewData.specialty" class="text-left w-e-text member-apply-rich-text" v-html="viewData.specialty"></div>
|
<div v-if="viewData.specialty" class="text-left w-e-text member-apply-rich-text" style="white-space: pre-wrap; word-break: break-all;" v-html="viewData.specialty"></div>
|
||||||
<el-tag type="warning" v-else>暂无</el-tag>
|
<el-tag type="warning" v-else>暂无</el-tag>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item label="照片" :span="3" v-if="viewData.photo">
|
||||||
|
<el-image :src="viewData.photo"
|
||||||
|
style="width: 120px;height: 150px"
|
||||||
|
fit="cover"></el-image>
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
<el-descriptions-item label="签字信息" :span="3" v-if="viewData.sign">
|
<el-descriptions-item label="签字信息" :span="3" v-if="viewData.sign">
|
||||||
<el-image :src="viewData.sign"
|
<el-image :src="viewData.sign"
|
||||||
|
|||||||
@@ -193,13 +193,28 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<el-descriptions-item label="个人学习及工作经历" :span="3">
|
<el-descriptions-item label="个人学习及工作经历" :span="3">
|
||||||
<el-form-item prop="personalData" label="个人学习及工作经历">
|
<el-form-item prop="personalData" label="个人学习及工作经历">
|
||||||
<text-editor v-model="formData.personalData"></text-editor>
|
<el-input type="textarea" :rows="4" v-model="formData.personalData"
|
||||||
|
placeholder="请输入个人学习及工作经历"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
<el-descriptions-item label="特长及获奖情况" :span="3">
|
<el-descriptions-item label="特长及获奖情况" :span="3">
|
||||||
<el-form-item prop="specialty" label="特长及获奖情况">
|
<el-form-item prop="specialty" label="特长及获奖情况">
|
||||||
<text-editor v-model="formData.specialty"></text-editor>
|
<el-input type="textarea" :rows="4" v-model="formData.specialty"
|
||||||
|
maxlength="100" show-word-limit
|
||||||
|
placeholder="请输入特长及获奖情况"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item label="照片" :span="3">
|
||||||
|
<el-form-item prop="photo" label="照片">
|
||||||
|
<file-upload
|
||||||
|
:value.sync="formData.photo"
|
||||||
|
:upload_number="1"
|
||||||
|
upload_mode="image"
|
||||||
|
upload_result_category="interval"
|
||||||
|
upload_result_type="url"
|
||||||
|
></file-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
@@ -259,7 +274,29 @@ layout("/layouts/platform.html"){
|
|||||||
sex: [{ required: false, message: "必填", trigger: ["change", "blur"] }],
|
sex: [{ required: false, message: "必填", trigger: ["change", "blur"] }],
|
||||||
isVoluntary: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
isVoluntary: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
sign: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
sign: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
|
photo: [{ required: true, message: "请上传照片", trigger: ["change", "blur"] }],
|
||||||
homeAddress: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
homeAddress: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
|
families: [{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
// 提交时家庭主要成员至少填写一条,并校验核心成员信息。
|
||||||
|
if (!value || value.length === 0) {
|
||||||
|
callback(new Error("请添加家庭主要成员"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const hasIncomplete = value.some(item => {
|
||||||
|
item = item || {}
|
||||||
|
return !String(item.relation || "").trim()
|
||||||
|
|| !String(item.name || "").trim()
|
||||||
|
|| !String(item.unit || "").trim()
|
||||||
|
})
|
||||||
|
if (hasIncomplete) {
|
||||||
|
callback(new Error("请完善家庭主要成员的关系、姓名、工作单位"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
},
|
||||||
|
trigger: ["change", "blur"]
|
||||||
|
}],
|
||||||
personalData: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
personalData: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
specialty: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
specialty: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
marriage: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
marriage: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
@@ -388,23 +425,27 @@ layout("/layouts/platform.html"){
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
onFinishTask() {
|
onFinishTask() {
|
||||||
this.$confirm("您确定要提交吗?", "提示", {
|
this.$refs.formRef.validate((valid) => {
|
||||||
confirmButtonText: "确定",
|
if (valid) {
|
||||||
cancelButtonText: "取消",
|
this.$confirm("您确定要提交吗?", "提示", {
|
||||||
type: "warning"
|
confirmButtonText: "确定",
|
||||||
}).then(() => {
|
cancelButtonText: "取消",
|
||||||
const loading = createLoading()
|
type: "warning"
|
||||||
this.$axios.post("/platform/member/apply/submit/submitAgain", {
|
}).then(() => {
|
||||||
data: JSON.stringify(this.formData),
|
const loading = createLoading()
|
||||||
taskId: this.taskId
|
this.$axios.post("/platform/member/apply/submit/submitAgain", {
|
||||||
}).then(res => {
|
data: JSON.stringify(this.formData),
|
||||||
if (res.code === 0) {
|
taskId: this.taskId
|
||||||
this.$message.success(res.msg)
|
}).then(res => {
|
||||||
commonUtil.pjaxPush("/platform/member/apply/mine")
|
if (res.code === 0) {
|
||||||
}
|
this.$message.success(res.msg)
|
||||||
}).finally(() => {
|
commonUtil.pjaxPush("/platform/member/apply/mine")
|
||||||
loading.close()
|
}
|
||||||
})
|
}).finally(() => {
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
async init() {
|
async init() {
|
||||||
|
|||||||
@@ -40,8 +40,19 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
<el-empty v-else :image-size="50" description="暂无家庭成员信息"></el-empty>
|
<el-empty v-else :image-size="50" description="暂无家庭成员信息"></el-empty>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="个人简况" :span="3">
|
<el-descriptions-item label="个人学习及工作经历" :span="3">
|
||||||
<div v-if="viewData.personalData" class="text-left" v-html="viewData.personalData"></div>
|
<div v-if="viewData.personalData" class="text-left w-e-text member-apply-rich-text" style="white-space: pre-wrap; word-break: break-all;" v-html="viewData.personalData"></div>
|
||||||
|
<el-tag type="warning" v-else>暂无</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="特长及获奖情况" :span="3">
|
||||||
|
<div v-if="viewData.specialty" class="text-left w-e-text member-apply-rich-text" style="white-space: pre-wrap; word-break: break-all;" v-html="viewData.specialty"></div>
|
||||||
|
<el-tag type="warning" v-else>暂无</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item label="照片" :span="3">
|
||||||
|
<el-image v-if="viewData.photo" :src="viewData.photo"
|
||||||
|
style="width: 120px;height: 150px"
|
||||||
|
fit="cover"></el-image>
|
||||||
<el-tag type="warning" v-else>暂无</el-tag>
|
<el-tag type="warning" v-else>暂无</el-tag>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
|||||||
@@ -63,18 +63,24 @@ const INFO = {
|
|||||||
|
|
||||||
<van-cell title="个人学习及工作经历">
|
<van-cell title="个人学习及工作经历">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div v-if="viewData.personalData" class="text-left" v-html="viewData.personalData"></div>
|
<div v-if="viewData.personalData" class="text-left w-e-text member-apply-rich-text" style="white-space: pre-wrap; word-break: break-all;" v-html="viewData.personalData"></div>
|
||||||
<span style="font-size: 14px" v-else>无数据</span>
|
<span style="font-size: 14px" v-else>无数据</span>
|
||||||
</template>
|
</template>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
|
|
||||||
<van-cell title="特长及获奖情况">
|
<van-cell title="特长及获奖情况">
|
||||||
<template #label>
|
<template #label>
|
||||||
<div v-if="viewData.specialty" class="text-left" v-html="viewData.specialty"></div>
|
<div v-if="viewData.specialty" class="text-left w-e-text member-apply-rich-text" style="white-space: pre-wrap; word-break: break-all;" v-html="viewData.specialty"></div>
|
||||||
<span style="font-size: 14px" v-else>无数据</span>
|
<span style="font-size: 14px" v-else>无数据</span>
|
||||||
</template>
|
</template>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
|
|
||||||
|
<van-cell title="照片" v-if="viewData.photo">
|
||||||
|
<van-image :src="viewData.photo"
|
||||||
|
style="width: 120px;height: 150px"
|
||||||
|
fit="cover"></van-image>
|
||||||
|
</van-cell>
|
||||||
|
|
||||||
<van-cell title="签字" >
|
<van-cell title="签字" >
|
||||||
<van-image :src="viewData.sign"
|
<van-image :src="viewData.sign"
|
||||||
v-if="viewData.sign"
|
v-if="viewData.sign"
|
||||||
|
|||||||
+65
-2
@@ -288,11 +288,48 @@ layout("/layouts/platform_h5.html"){
|
|||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
|
|
||||||
<van-cell-group title="个人学习及工作经历" class="form-section">
|
<van-cell-group title="个人学习及工作经历" class="form-section">
|
||||||
<text-editor v-model="formData.personalData"></text-editor>
|
<van-field
|
||||||
|
v-model="formData.personalData"
|
||||||
|
name="personalData"
|
||||||
|
rows="4"
|
||||||
|
label=""
|
||||||
|
type="textarea"
|
||||||
|
placeholder="请输入个人学习及工作经历"
|
||||||
|
required
|
||||||
|
:rules="[{ required: true, message: '请填写个人学习及工作经历' }]"
|
||||||
|
></van-field>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
|
|
||||||
<van-cell-group title="特长及获奖情况" class="form-section">
|
<van-cell-group title="特长及获奖情况" class="form-section">
|
||||||
<text-editor v-model="formData.specialty"></text-editor>
|
<van-field
|
||||||
|
v-model="formData.specialty"
|
||||||
|
name="specialty"
|
||||||
|
rows="4"
|
||||||
|
label=""
|
||||||
|
type="textarea"
|
||||||
|
maxlength="100"
|
||||||
|
show-word-limit
|
||||||
|
placeholder="请输入特长及获奖情况"
|
||||||
|
required
|
||||||
|
:rules="[{ required: true, message: '请填写特长及获奖情况' }]"
|
||||||
|
></van-field>
|
||||||
|
</van-cell-group>
|
||||||
|
|
||||||
|
<van-cell-group title="照片" class="form-section">
|
||||||
|
<van-field class="direction-column-field" name="photo" label=""
|
||||||
|
required :rules="[{ required: true, message: '请上传照片' }]">
|
||||||
|
<template #input>
|
||||||
|
<h5-file-upload
|
||||||
|
slot="input"
|
||||||
|
:value.sync="formData.photo"
|
||||||
|
:upload_number="1"
|
||||||
|
upload_mode="image"
|
||||||
|
upload_result_category="interval"
|
||||||
|
upload_result_type="url"
|
||||||
|
complete_result
|
||||||
|
></h5-file-upload>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
|
|
||||||
<van-cell-group title="签字" class="form-section">
|
<van-cell-group title="签字" class="form-section">
|
||||||
@@ -401,6 +438,9 @@ layout("/layouts/platform_h5.html"){
|
|||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.$refs.formRef.validate().then(() => {
|
this.$refs.formRef.validate().then(() => {
|
||||||
|
if (!this.validateFamilies()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!this.formData.personalData) {
|
if (!this.formData.personalData) {
|
||||||
this.$toast.fail("请填写个人学习及工作经历")
|
this.$toast.fail("请填写个人学习及工作经历")
|
||||||
return
|
return
|
||||||
@@ -442,6 +482,9 @@ layout("/layouts/platform_h5.html"){
|
|||||||
|
|
||||||
onFinishTask() {
|
onFinishTask() {
|
||||||
this.$refs.formRef.validate().then(() => {
|
this.$refs.formRef.validate().then(() => {
|
||||||
|
if (!this.validateFamilies()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!this.formData.personalData) {
|
if (!this.formData.personalData) {
|
||||||
this.$toast.fail("请填写个人学习及工作经历")
|
this.$toast.fail("请填写个人学习及工作经历")
|
||||||
return
|
return
|
||||||
@@ -482,6 +525,26 @@ layout("/layouts/platform_h5.html"){
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
validateFamilies() {
|
||||||
|
// 提交时家庭主要成员至少填写一条,并校验核心成员信息。
|
||||||
|
const families = this.formData.families || []
|
||||||
|
if (families.length === 0) {
|
||||||
|
this.$toast.fail("请添加家庭主要成员")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const hasIncomplete = families.some(item => {
|
||||||
|
item = item || {}
|
||||||
|
return !String(item.relation || "").trim()
|
||||||
|
|| !String(item.name || "").trim()
|
||||||
|
|| !String(item.unit || "").trim()
|
||||||
|
})
|
||||||
|
if (hasIncomplete) {
|
||||||
|
this.$toast.fail("请完善家庭主要成员的关系、姓名、工作单位")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
|
||||||
onDateConfirm(value) {
|
onDateConfirm(value) {
|
||||||
this.formData.birthday = value
|
this.formData.birthday = value
|
||||||
this.showDatePicker = false
|
this.showDatePicker = false
|
||||||
|
|||||||
Reference in New Issue
Block a user