fix:save_to_json

This commit is contained in:
dichgrem
2025-12-26 11:00:57 +08:00
parent d076ee1d3a
commit 61655580fd
9 changed files with 550 additions and 303 deletions

View File

@@ -1,60 +1,58 @@
<template>
<div class="container">
<div class="inner">
<h1>个人信息</h1>
<ul>
<li>
<p class="label"><span>*</span>姓名</p>
<span class="txt">{{ name }}</span>
</li>
<li>
<p class="label"><span>*</span>编号</p>
<span class="txt">{{ code }}</span>
</li>
<li>
<p class="label"><span>*</span>性别</p>
<input type="radio" value="0" v-model="gender" />
<input type="radio" value="1" v-model="gender" />
</li>
<li>
<p class="label"><span>*</span>手机号</p>
<input placeholder="请输入手机号" v-model.trim="phoneNum" />
</li>
<li>
<p class="label"><span>*</span>学校</p>
<input placeholder="请输入学校名称" v-model.trim="school" />
</li>
<li>
<p class="label"><span>*</span>专业</p>
<input
placeholder="请输入专业名称"
v-model.trim="profession"
/>
</li>
<li>
<p class="label"><span>*</span>人员属性</p>
<div class="userTypeList">
<span
:class="{ active: userType === 0 }"
@click="changeUserType(0)"
>群众</span
>
<span
:class="{ active: userType === 1 }"
@click="changeUserType(1)"
>团员</span
>
<span
:class="{ active: userType === 2 }"
@click="changeUserType(2)"
>党员</span
>
</div>
</li>
</ul>
<button class="subBtn" @click="submitClick">提交</button>
</div>
<div class="container">
<div class="inner">
<h1>个人信息</h1>
<ul>
<li>
<p class="label"><span>*</span>姓名</p>
<input placeholder="请输入姓名" v-model.trim="name" />
</li>
<li>
<p class="label"><span>*</span>编号</p>
<input placeholder="请输入编号" v-model.trim="codeStr" />
</li>
<li>
<p class="label"><span>*</span>性别</p>
<input type="radio" value="0" v-model="gender" />
<input type="radio" value="1" v-model="gender" />
</li>
<li>
<p class="label"><span>*</span>手机号</p>
<input placeholder="请输入手机号" v-model.trim="phoneNum" />
</li>
<li>
<p class="label"><span>*</span>学校</p>
<input placeholder="请输入学校名称" v-model.trim="school" />
</li>
<li>
<p class="label"><span>*</span>专业</p>
<input placeholder="请输入专业名称" v-model.trim="profession" />
</li>
<li>
<p class="label"><span>*</span>人员属性</p>
<div class="userTypeList">
<span :class="{ active: userType === 0 }" @click="changeUserType(0)">群众</span>
<span :class="{ active: userType === 1 }" @click="changeUserType(1)">团员</span>
<span :class="{ active: userType === 2 }" @click="changeUserType(2)">党员</span>
</div>
</li>
</ul>
<button class="subBtn" :disabled="saving" @click="submitClick">
{{ saving ? "保存中..." : "保存" }}
</button>
<button class="subBtn subBtn-ghost" :disabled="saving" @click="resetClick">
取消修改
</button>
</div>
</div>
</template>
<script>
@@ -62,181 +60,252 @@ import axios from "axios";
import { showToast, showSuccessToast, showFailToast } from "vant";
export default {
data() {
return {
name: "",
code: null,
gender: 0,
phoneNum: "",
school: "",
profession: "",
userType: 0,
};
},
methods: {
changeUserType(value) {
this.userType = value;
},
fetchUsrInfo() {
const that = this;
axios.get("/api/userInfo").then(function (response) {
const { error, data = {} } = response.data;
if (error === 0) {
that.name = data.name;
that.code = data.code;
that.gender = data.gender;
that.phoneNum = data.phoneNum;
that.school = data.school;
that.profession = data.profession;
that.userType = data.userType;
}
});
},
check() {
var phoneNum = this.phoneNum;
var school = this.school;
var profession = this.profession;
data() {
return {
name: "",
code: null,
codeStr: "",
if (phoneNum === "") {
showToast("手机号不可为空");
return;
}
if (school === "") {
showToast("学校不可为空");
return;
}
if (profession === "") {
showToast("专业不可为空");
return;
}
gender: "0",
phoneNum: "",
school: "",
profession: "",
userType: 0,
const payload = {
name: this.name,
code: this.code,
gender: this.gender,
phoneNum,
school,
profession,
userType: this.userType,
};
return payload;
},
submitClick() {
var payload = this.check();
if (!payload) {
return;
}
saving: false,
original: null,
};
},
methods: {
changeUserType(value) {
this.userType = value;
},
axios
.post("/api/userInfo/submit", payload)
.then(function (response) {
const { error, msg } = response.data;
if (error === 0) {
showSuccessToast("操作成功");
} else {
showFailToast(msg || "网络错误,请稍后重试");
}
});
},
snapshot() {
return {
name: this.name,
code: this.code,
codeStr: this.codeStr,
gender: this.gender,
phoneNum: this.phoneNum,
school: this.school,
profession: this.profession,
userType: this.userType,
};
},
mounted() {
this.fetchUsrInfo();
applyData(data = {}) {
this.name = data.name ?? "";
this.code = data.code ?? null;
this.codeStr = data.code != null ? String(data.code) : "";
this.gender = data.gender != null ? String(data.gender) : "0";
this.phoneNum = data.phoneNum ?? "";
this.school = data.school ?? "";
this.profession = data.profession ?? "";
this.userType = data.userType ?? 0;
},
fetchUsrInfo() {
axios
.get("/api/userInfo")
.then((response) => {
const { error, data = {}, msg } = response.data || {};
if (error === 0) {
this.applyData(data);
this.original = this.snapshot();
} else {
showFailToast(msg || "获取用户信息失败");
}
})
.catch(() => showFailToast("网络错误,请稍后重试"));
},
check() {
const name = this.name.trim();
const codeStr = this.codeStr.trim();
const phoneNum = this.phoneNum.trim();
const school = this.school.trim();
const profession = this.profession.trim();
if (!name) {
showToast("姓名不可为空");
return;
}
if (!codeStr) {
showToast("编号不可为空");
return;
}
if (!phoneNum) {
showToast("手机号不可为空");
return;
}
if (!school) {
showToast("学校不可为空");
return;
}
if (!profession) {
showToast("专业不可为空");
return;
}
const codeNum = Number(codeStr);
const code = Number.isFinite(codeNum) ? codeNum : codeStr;
const payload = {
name,
code,
gender: Number(this.gender),
phoneNum,
school,
profession,
userType: this.userType,
};
return payload;
},
submitClick() {
const payload = this.check();
if (!payload) return;
if (this.saving) return;
this.saving = true;
axios
.post("/api/userInfo/submit", payload)
.then((response) => {
const { error, msg } = response.data || {};
if (error === 0) {
showSuccessToast("保存成功");
this.original = this.snapshot();
} else {
showFailToast(msg || "网络错误,请稍后重试");
}
})
.catch(() => showFailToast("网络错误,请稍后重试"))
.finally(() => {
this.saving = false;
});
},
resetClick() {
if (!this.original) return;
this.name = this.original.name;
this.code = this.original.code;
this.codeStr = this.original.codeStr;
this.gender = this.original.gender;
this.phoneNum = this.original.phoneNum;
this.school = this.original.school;
this.profession = this.original.profession;
this.userType = this.original.userType;
showToast("已还原");
},
},
mounted() {
this.fetchUsrInfo();
},
};
</script>
<style scoped>
.inner {
padding: 20px;
background: white;
color: #333;
padding: 20px;
background: white;
color: #333;
}
h1 {
text-align: center;
margin-bottom: 20px;
color: #333;
text-align: center;
margin-bottom: 20px;
color: #333;
}
ul {
list-style: none;
padding: 0;
margin: 0;
list-style: none;
padding: 0;
margin: 0;
}
li {
padding: 15px 0;
border-bottom: 1px solid #eee;
color: #333;
padding: 15px 0;
border-bottom: 1px solid #eee;
color: #333;
}
.label {
font-weight: bold;
margin-bottom: 10px;
color: #333;
font-weight: bold;
margin-bottom: 10px;
color: #333;
}
.label span {
color: red;
}
.txt {
color: #666;
color: red;
}
li input:not([type="radio"]) {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
margin-top: 5px;
box-sizing: border-box;
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
margin-top: 5px;
box-sizing: border-box;
color: #333;
background-color: #fff;
color: #333;
background-color: #fff;
}
li input:not([type="radio"])::placeholder {
color: #999;
color: #999;
}
input[type="radio"] {
margin-right: 6px;
margin-left: 10px;
margin-right: 6px;
margin-left: 10px;
}
input[type="radio"]:first-of-type {
margin-left: 0;
margin-left: 0;
}
.userTypeList {
display: flex;
gap: 10px;
margin-top: 10px;
display: flex;
gap: 10px;
margin-top: 10px;
}
.userTypeList span {
padding: 8px 20px;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
color: #333;
padding: 8px 20px;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
color: #333;
}
.userTypeList span.active {
background: #ff5d23;
color: white;
border-color: #ff5d23;
background: #ff5d23;
color: white;
border-color: #ff5d23;
}
.subBtn {
width: 100%;
padding: 15px;
background: #ff5d23;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
margin-top: 20px;
cursor: pointer;
width: 100%;
padding: 15px;
background: #ff5d23;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
margin-top: 20px;
cursor: pointer;
}
.subBtn:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.subBtn-ghost {
background: transparent;
color: #333;
border: 1px solid #ddd;
}
</style>