436 lines
12 KiB
Vue
436 lines
12 KiB
Vue
<template>
|
||
<BasicLayout>
|
||
<view class="page-container">
|
||
<view class="notice-box">
|
||
<text class="notice-text"
|
||
>特别提示:家中家庭成员可多人关联,可接收孩子在校情况、学业情况等。</text
|
||
>
|
||
</view>
|
||
<view
|
||
v-for="(student, index) in students"
|
||
:key="index"
|
||
class="form-section mb-15"
|
||
>
|
||
<view v-if="index > 0" class="remove-btn" @click="removeStudent(index)">
|
||
<u-icon name="minus-circle" color="#ff4d4f" size="18"></u-icon>
|
||
</view>
|
||
|
||
<view class="avatar-section">
|
||
<view class="avatar-uploader-container-rect">
|
||
<CustomUpload
|
||
@select="(event:any) => afterRead(event, index)"
|
||
@close="handleAvatarClose(index)"
|
||
:sourceType="['camera', 'album']"
|
||
:value="imagUrl(student.xstx)"
|
||
>
|
||
<view class="avatar-placeholder">
|
||
<view class="wh-full flex-col-center">
|
||
<svg
|
||
t="1729656215869"
|
||
class="icon"
|
||
viewBox="0 0 1024 1024"
|
||
version="1.1"
|
||
xmlns="http://www.w3.org/2000/svg"
|
||
p-id="5302"
|
||
width="32"
|
||
height="32"
|
||
>
|
||
<path
|
||
d="M851.552 890.88 172.448 890.88c-74.592 0-135.296-60.672-135.296-135.296L37.152 370.752c0-74.624 60.672-135.328 135.296-135.328l132.16 0L302.912 195.904c0-34.624 28.192-62.816 62.816-62.816l302.016 0c29.408 0 53.312 23.904 53.312 53.312l0 49.024 130.464 0c74.592 0 135.296 60.672 135.296 135.328l0 384.832C986.816 830.208 926.144 890.88 851.552 890.88zM172.448 283.456c-48.128 0-87.296 39.168-87.296 87.328l0 384.832c0 48.128 39.168 87.296 87.296 87.296l679.104 0c48.128 0 87.296-39.168 87.296-87.296L938.848 370.752c0-48.16-39.168-87.328-87.296-87.328L716.8 283.424c-24.096 0-43.712-19.616-43.712-43.712L673.088 186.4c0-2.944-2.368-5.312-5.312-5.312l-302.016 0c-8.16 0-14.816 6.656-14.816 14.816L350.944 237.12c0 25.536-20.768 46.304-46.304 46.304L172.448 283.424zM512 755.84c-107.04 0-194.08-87.072-194.08-194.08S404.992 367.68 512 367.68s194.08 87.072 194.08 194.08S619.04 755.84 512 755.84zM512 415.68c-80.576 0-146.08 65.536-146.08 146.08S431.456 707.84 512 707.84s146.08-65.536 146.08-146.08S592.576 415.68 512 415.68zM816.8 438.016c-25.568 0-46.336-20.768-46.336-46.336s20.768-46.336 46.336-46.336 46.336 20.768 46.336 46.336S842.368 438.016 816.8 438.016zM816.8 390.016l-1.664 1.664c0 0.896 0.736 1.664 1.664 1.664L816.8 390.016z"
|
||
fill="#cdcdcd"
|
||
p-id="5303"
|
||
></path>
|
||
</svg>
|
||
</view>
|
||
</view>
|
||
</CustomUpload>
|
||
</view>
|
||
<text class="avatar-upload-note">上传学生人像用于校园进出</text>
|
||
</view>
|
||
|
||
<view class="student-info-form">
|
||
<u--form label-width="auto">
|
||
<u-form-item
|
||
label="姓名"
|
||
:prop="`students[${index}].xsxm`"
|
||
required
|
||
borderBottom
|
||
>
|
||
<u--input
|
||
v-model="student.xsxm"
|
||
placeholder="请输入学生姓名"
|
||
border="none"
|
||
inputAlign="right"
|
||
></u--input>
|
||
</u-form-item>
|
||
<!-- <u-form-item
|
||
label="与学生关系"
|
||
:prop="`students[${index}].jzxsgxId`"
|
||
required
|
||
borderBottom
|
||
>
|
||
<view @click="openDicPicker(student)" class="flex-row flex-1 justify-end">
|
||
<view v-if="!student.jzxsgxId" style="color: rgb(192, 196, 204);">请选择与学生关系</view>
|
||
<view v-else>{{ student.jzxsgxmc }}</view>
|
||
</view>
|
||
|
||
</u-form-item> -->
|
||
<u-form-item
|
||
label="身份证号"
|
||
:prop="`students[${index}].xssfzh`"
|
||
required
|
||
borderBottom
|
||
>
|
||
<u--input
|
||
v-model="student.xssfzh"
|
||
placeholder="请输入学生身份证号"
|
||
border="none"
|
||
inputAlign="right"
|
||
></u--input>
|
||
</u-form-item>
|
||
</u--form>
|
||
</view>
|
||
</view>
|
||
<view class="add-child-btn mb-15" @click="addMoreChildren">
|
||
<u-icon name="plus" color="#416AF2" size="20"></u-icon>
|
||
<text class="add-child-btn-text">新增多孩</text>
|
||
</view>
|
||
|
||
</view>
|
||
|
||
<template #bottom>
|
||
<view class="white-bg-color py-5">
|
||
<view class="flex-row items-center pb-10 pt-5">
|
||
<u-button text="提交" class="mx-15" type="primary" @click="submit" />
|
||
</view>
|
||
</view>
|
||
</template>
|
||
</BasicLayout>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { hideLoading, showLoading, showToast } from "@/utils/uniapp";
|
||
import { ref } from "vue";
|
||
import { attachmentUpload } from "@/api/system/upload";
|
||
import CustomUpload from "/src/components/BasicUpload/CustomUpload.vue";
|
||
|
||
import { useForm } from "@/components/BasicForm/hooks/useForm";
|
||
import { glxsApi } from "@/api/base/server";
|
||
import { useUserStore } from "@/store/modules/user";
|
||
import { useDataStore } from "@/store/modules/data";
|
||
import {imagUrl} from "@/utils";
|
||
|
||
const { getGlobal, getAppCode } = useDataStore();
|
||
const { getUser, setUser, setCurXs } = useUserStore();
|
||
|
||
const dicOptions = ref<any>([[[]]]);
|
||
const dicPickerRef = ref();
|
||
const dicVal = ref<number[]>([]);
|
||
|
||
const students = ref([
|
||
{
|
||
xsxm: "",
|
||
xssfzh: "",
|
||
xstx: "",
|
||
jzxsgxId: "",
|
||
jzxsgxmc: ""
|
||
},
|
||
]);
|
||
|
||
const curXs = ref(students.value[0]);
|
||
|
||
const openDicPicker = (xs: any) => {
|
||
curXs.value = xs;
|
||
dicVal.value = [0];
|
||
for (let i = 0; i < dicOptions.value[0].length; i++) {
|
||
if (xs.jzxsgxId == dicOptions.value[0][i].dictionaryValue) {
|
||
dicVal.value = [i];
|
||
break;
|
||
}
|
||
}
|
||
dicPickerRef.value.open();
|
||
};
|
||
|
||
const dicChanged = (dicArr: any) => {
|
||
console.log(dicArr);
|
||
const dic = dicOptions.value[0][dicArr[0]];
|
||
curXs.value.jzxsgxId = dic.dictionaryValue;
|
||
curXs.value.jzxsgxmc = dic.dictionaryCode;
|
||
}
|
||
|
||
async function afterRead(event: any, index: number) {
|
||
if (!event.tempFilePaths || event.tempFilePaths.length === 0) {
|
||
showToast({ title: "图片选择失败", icon: "none" });
|
||
return;
|
||
}
|
||
const tempFilePath = event.tempFilePaths[0];
|
||
showLoading({ title: "上传中" });
|
||
try {
|
||
const res = await attachmentUpload(tempFilePath);
|
||
const result = res.result;
|
||
if (result && result.length > 0 && result[0].filePath) {
|
||
students.value[index].xstx = result[0].filePath;
|
||
console.log(`Student ${index} avatar uploaded:`, result[0].filePath);
|
||
showToast({ title: "上传成功" });
|
||
} else {
|
||
showToast({ title: "上传失败,请重试", icon: "none" });
|
||
console.error("Upload result format error:", result);
|
||
}
|
||
} catch (error) {
|
||
showToast({ title: "上传出错", icon: "none" });
|
||
console.error("Upload error:", error);
|
||
} finally {
|
||
hideLoading();
|
||
}
|
||
}
|
||
|
||
function handleAvatarClose(index: number) {
|
||
students.value[index].xstx = "";
|
||
}
|
||
|
||
function addMoreChildren() {
|
||
students.value.push({
|
||
xsxm: "",
|
||
xssfzh: "",
|
||
xstx: "",
|
||
jzxsgxId: "",
|
||
jzxsgxmc: ""
|
||
});
|
||
}
|
||
|
||
function removeStudent(index: number) {
|
||
if (students.value.length > 1) {
|
||
students.value.splice(index, 1);
|
||
} else {
|
||
showToast({ title: "至少需要一个子女信息", icon: "none" });
|
||
}
|
||
}
|
||
|
||
async function submit() {
|
||
for (const student of students.value) {
|
||
if (!student.xstx) {
|
||
showToast({ title: "请上传子女照片", icon: "none" });
|
||
return;
|
||
}
|
||
if (!student.xsxm) {
|
||
showToast({ title: "请输入子女姓名", icon: "none" });
|
||
return;
|
||
}
|
||
if (!student.xssfzh) {
|
||
showToast({ title: "请输入子女身份证号", icon: "none" });
|
||
return;
|
||
}
|
||
}
|
||
showLoading({ title: "提交中" });
|
||
try {
|
||
for (let i = 0; i < students.value.length; i++) {
|
||
students.value[i].jzxsgxId = getUser.jzxsgxId;
|
||
}
|
||
const res = await glxsApi({
|
||
xsList: students.value,
|
||
jzId: getUser.jzId,
|
||
openId: getGlobal.openId,
|
||
appCode: getAppCode,
|
||
});
|
||
hideLoading();
|
||
setUser(res.result);
|
||
for (let i = 0; i < res.result.xsList.length; i++) {
|
||
if (res.result.xsList[i].sfzh == students.value[0].xssfzh) {
|
||
setCurXs(res.result.xsList[i]);
|
||
break;
|
||
}
|
||
}
|
||
|
||
uni.reLaunch({
|
||
url: "/pages/base/home/index",
|
||
});
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
}
|
||
|
||
onMounted(async () => {
|
||
console.log("glxs");
|
||
// const resDic = await dicApi({ pid: 1622287061 });
|
||
// dicOptions.value = [resDic.result];
|
||
// formSchema[1].componentProps.options = resDic.result;
|
||
// setSchema(formSchema);
|
||
});
|
||
|
||
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page-container {
|
||
padding: 15px; /* Consistent padding */
|
||
}
|
||
|
||
.notice-box {
|
||
background-color: #fff1f0; /* Slightly lighter red */
|
||
padding: 12px 18px;
|
||
border-radius: 8px;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.notice-text {
|
||
color: #fa541c; /* Adjusted red color */
|
||
font-size: 13px;
|
||
}
|
||
|
||
.form-section {
|
||
background-color: #ffffff;
|
||
border-radius: 10px;
|
||
padding: 20px 20px 0 20px;
|
||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.06);
|
||
/* Added margin-bottom directly here for spacing between sections */
|
||
margin-bottom: 5px;
|
||
position: relative;
|
||
}
|
||
|
||
.avatar-section {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-bottom: 25px; /* Increased margin */
|
||
}
|
||
|
||
/* Keep avatar uploader styles relevant to CustomUpload */
|
||
/* Replace with rectangular styles */
|
||
.avatar-uploader-container-rect {
|
||
/* Assuming uni.rpx units based on class names like wi-180, he-240 */
|
||
width: 180rpx;
|
||
height: 240rpx;
|
||
margin: 0 auto 10px auto; /* mx-auto mb-10 */
|
||
border-radius: 6px; /* r-md approximation */
|
||
border: 1px solid #cccccc;
|
||
overflow: hidden;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background-color: #fafafa;
|
||
}
|
||
|
||
/* Remove old circular styles */
|
||
/* .avatar-uploader-container { ... } */
|
||
|
||
.avatar-placeholder {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 100%;
|
||
height: 100%;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* Keep inner placeholder for centering SVG */
|
||
.avatar-placeholder-inner {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.avatar-image {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
/* Remove old hint style */
|
||
/* .avatar-upload-hint { ... } */
|
||
|
||
.avatar-upload-note {
|
||
color: #999;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.student-info-form {
|
||
margin-bottom: 20px; /* Restore original margin */
|
||
}
|
||
|
||
.form-title {
|
||
display: block;
|
||
font-size: 16px; /* Slightly larger title */
|
||
font-weight: 600; /* Bolder */
|
||
margin-bottom: 15px; /* Space below title */
|
||
}
|
||
|
||
/* Restore remove button style if needed, or adapt */
|
||
/* Updated remove button style */
|
||
.remove-btn {
|
||
position: absolute;
|
||
top: 10px; /* Closer to top edge */
|
||
right: 10px; /* Closer to right edge */
|
||
cursor: pointer;
|
||
z-index: 10;
|
||
/* Optional: add padding for easier clicking */
|
||
// padding: 5px;
|
||
}
|
||
|
||
.add-child-btn {
|
||
background-color: #ffffff;
|
||
border-radius: 10px;
|
||
padding: 15px; /* Increased padding */
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-top: 10px; /* Increased margin */
|
||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.06);
|
||
cursor: pointer;
|
||
}
|
||
|
||
.add-child-btn-text {
|
||
color: #416af2;
|
||
margin-left: 8px;
|
||
font-size: 15px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* Adjust uview form item styles */
|
||
::v-deep .u-form-item {
|
||
margin-bottom: 0; /* Remove default margin if any */
|
||
}
|
||
|
||
::v-deep .u-form-item__body {
|
||
padding: 15px 0 !important; /* Adjusted padding */
|
||
/* Align items vertically if label wraps */
|
||
// align-items: flex-start;
|
||
}
|
||
|
||
::v-deep .u-form-item__body__left {
|
||
/* Allow label to take necessary width, adjust as needed */
|
||
// flex: 0 0 80px;
|
||
}
|
||
|
||
::v-deep .u-form-item__body__left__text {
|
||
font-size: 15px;
|
||
color: #333;
|
||
line-height: 1.5; /* Improve line spacing if label wraps */
|
||
/* Ensure required asterisk is red and BEFORE the text */
|
||
display: flex; /* Use flex to control order */
|
||
align-items: center; /* Vertically center asterisk and text */
|
||
|
||
span {
|
||
color: #f56c6c;
|
||
/* Order asterisk first */
|
||
order: -1;
|
||
margin-right: 4px;
|
||
/* Adjust vertical alignment if needed */
|
||
// line-height: 1;
|
||
// display: inline-block;
|
||
// vertical-align: middle;
|
||
}
|
||
}
|
||
|
||
::v-deep .u-input {
|
||
text-align: right; /* Align input text to the right */
|
||
}
|
||
|
||
::v-deep .u-border-bottom {
|
||
/* Ensure border spans full width if needed, or adjust */
|
||
// left: 0 !important;
|
||
// right: 0 !important;
|
||
}
|
||
</style>
|