305 lines
9.1 KiB
Vue
305 lines
9.1 KiB
Vue
<template>
|
||
<view class="ciy-page">
|
||
<!-- 页面标题 -->
|
||
<view class="ciy-title mk bg2">
|
||
<view class="title">新增实验室成员</view>
|
||
<button class="btn def sm" @click="goBack">返回</button>
|
||
</view>
|
||
|
||
<!-- 表单容器 -->
|
||
<view class="main bg4 flex1 overflow-auto px4 py3">
|
||
<form class="ciy-form-group">
|
||
<!-- 1. 姓名(必填) -->
|
||
<view class="ciy-form">
|
||
<label class="imp char4">姓名</label>
|
||
<input
|
||
type="text"
|
||
v-model="form.name"
|
||
placeholder="请输入成员姓名"
|
||
class="ciy-edit px2 py1 bg1 rounded"
|
||
required
|
||
/>
|
||
</view>
|
||
|
||
<!-- 2. 头像上传 -->
|
||
<view class="ciy-form">
|
||
<label class="char4">头像</label>
|
||
<view class="flex flex-center">
|
||
<image
|
||
:src="form.icon || '/lab/default-avatar.png'"
|
||
mode="aspectFill"
|
||
class="w-12 h-12 rounded-full mr3"
|
||
></image>
|
||
<button class="btn def sm" @click="chooseAvatar">选择图片</button>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 3. 头衔 -->
|
||
<view class="ciy-form">
|
||
<label class="char4">头衔</label>
|
||
<picker
|
||
mode="selector"
|
||
:range="titleOptions"
|
||
:range-key="'label'"
|
||
v-model="form.usertitle"
|
||
class="px2 py1 bg1 rounded w-full"
|
||
>
|
||
<view class="txt-left px2 py1">{{ getTitleText(form.usertitle) }}</view>
|
||
</picker>
|
||
</view>
|
||
|
||
<!-- 4. 成员状态(必填) -->
|
||
<view class="ciy-form">
|
||
<label class="imp char4">状态</label>
|
||
<picker
|
||
mode="selector"
|
||
:range="statusOptions"
|
||
:range-key="'label'"
|
||
v-model="form.role"
|
||
class="px2 py1 bg1 rounded w-full"
|
||
required
|
||
>
|
||
<view class="txt-left px2 py1">{{ statusMap[form.role] }}</view>
|
||
</picker>
|
||
</view>
|
||
|
||
<!-- 5. 学历 -->
|
||
<view class="ciy-form">
|
||
<label class="char4">学历</label>
|
||
<picker
|
||
mode="selector"
|
||
:range="educationOptions"
|
||
:range-key="'label'"
|
||
v-model="form.education"
|
||
class="px2 py1 bg1 rounded w-full"
|
||
>
|
||
<view class="txt-left px2 py1">{{ educationMap[form.education] }}</view>
|
||
</picker>
|
||
</view>
|
||
|
||
<!-- 6. 编号 -->
|
||
<view class="ciy-form">
|
||
<label class="char4">编号</label>
|
||
<input
|
||
type="text"
|
||
v-model="form.sn"
|
||
placeholder="如 LAB-2024-001"
|
||
class="ciy-edit px2 py1 bg1 rounded"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 7. 性别 -->
|
||
<view class="ciy-form">
|
||
<label class="char4">性别</label>
|
||
<picker
|
||
mode="selector"
|
||
:range="sexOptions"
|
||
:range-key="'label'"
|
||
v-model="form.sex"
|
||
class="px2 py1 bg1 rounded w-full"
|
||
>
|
||
<view class="txt-left px2 py1">{{ sexMap[form.sex] }}</view>
|
||
</picker>
|
||
</view>
|
||
|
||
<!-- 8. 加入日期 -->
|
||
<view class="ciy-form">
|
||
<label class="char4">加入日期</label>
|
||
<picker
|
||
mode="date"
|
||
v-model="form.addtimesText"
|
||
start="2000-01-01"
|
||
end="2100-12-31"
|
||
class="px2 py1 bg1 rounded w-full"
|
||
>
|
||
<view class="txt-left px2 py1">{{ form.addtimesText || '请选择日期' }}</view>
|
||
</picker>
|
||
</view>
|
||
|
||
<!-- 9. 手机号 -->
|
||
<view class="ciy-form">
|
||
<label class="char4">手机号</label>
|
||
<input
|
||
type="number"
|
||
v-model="form.mobile"
|
||
placeholder="请输入11位手机号"
|
||
class="ciy-edit px2 py1 bg1 rounded"
|
||
maxlength="11"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 10. 邮箱 -->
|
||
<view class="ciy-form">
|
||
<label class="char4">邮箱</label>
|
||
<input
|
||
type="email"
|
||
v-model="form.email"
|
||
placeholder="请输入邮箱地址"
|
||
class="ciy-edit px2 py1 bg1 rounded"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 11. 密码(默认初始密码) -->
|
||
<view class="ciy-form">
|
||
<label class="char4">初始密码</label>
|
||
<input
|
||
type="password"
|
||
v-model="form.password"
|
||
placeholder="默认:123456"
|
||
class="ciy-edit px2 py1 bg1 rounded"
|
||
:value="form.password || '123456'"
|
||
/>
|
||
</view>
|
||
</form>
|
||
|
||
<!-- 表单提交按钮 -->
|
||
<view class="ciy-form-bottom mt4">
|
||
<button
|
||
class="btn man lgg long"
|
||
@click="submitForm"
|
||
:disabled="isSubmitting"
|
||
>
|
||
{{ isSubmitting ? '提交中...' : '提交成员信息' }}
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
isSubmitting: false, // 提交状态锁
|
||
form: {
|
||
name: '', // 姓名(必填)
|
||
icon: '', // 头像
|
||
usertitle: 0, // 头衔(默认无)
|
||
role: 30, // 成员状态(默认在册成员)
|
||
education: 50, // 学历(默认本科)
|
||
sn: '', // 编号
|
||
sex: 90, // 性别(默认其他)
|
||
addtimesText: '', // 加入日期(文本格式)
|
||
addtimes: 0, // 加入日期(时间戳,提交用)
|
||
mobile: '', // 手机号
|
||
email: '', // 邮箱
|
||
password: '123456' // 初始密码
|
||
},
|
||
|
||
// 下拉选择项:与lab_user.sql字段对应
|
||
titleOptions: [
|
||
{ value: 0, label: '无头衔' },
|
||
{ value: 10, label: '主任' },
|
||
{ value: 20, label: '副主任' },
|
||
{ value: 30, label: '顾问' },
|
||
{ value: 40, label: '名誉主任' },
|
||
{ value: 50, label: '教授' },
|
||
{ value: 60, label: '副教授' },
|
||
{ value: 70, label: '讲师' },
|
||
{ value: 80, label: '研究员' }
|
||
],
|
||
statusOptions: [
|
||
{ value: 10, label: '负责人' },
|
||
{ value: 20, label: '科研秘书' },
|
||
{ value: 30, label: '在册成员' },
|
||
{ value: 40, label: '历史成员' },
|
||
{ value: 50, label: '外部成员' }
|
||
],
|
||
educationOptions: [
|
||
{ value: 50, label: '本科' },
|
||
{ value: 60, label: '硕士' },
|
||
{ value: 70, label: '博士' }
|
||
],
|
||
sexOptions: [
|
||
{ value: 10, label: '男' },
|
||
{ value: 20, label: '女' },
|
||
{ value: 90, label: '其他' }
|
||
],
|
||
|
||
// 映射表:用于文本显示
|
||
statusMap: { 10: '负责人', 20: '科研秘书', 30: '在册成员', 40: '历史成员', 50: '外部成员' },
|
||
educationMap: { 50: '本科', 60: '硕士', 70: '博士' },
|
||
sexMap: { 10: '男', 20: '女', 90: '其他' },
|
||
titleMap: { 0: '无头衔', 10: '主任', 20: '副主任', 30: '顾问', 40: '名誉主任', 50: '教授', 60: '副教授', 70: '讲师', 80: '研究员' }
|
||
};
|
||
},
|
||
watch: {
|
||
// 监听日期选择,转换为时间戳
|
||
'form.addtimesText'(val) {
|
||
if (val) {
|
||
this.form.addtimes = new Date(val).getTime();
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
// 返回列表页
|
||
goBack() {
|
||
uni.navigateBack({ delta: 1 });
|
||
},
|
||
|
||
// 选择头像(调用相册/相机)
|
||
chooseAvatar() {
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sizeType: ['original', 'compressed'],
|
||
sourceType: ['album', 'camera'],
|
||
success: (res) => {
|
||
const tempFilePath = res.tempFilePaths[0];
|
||
// 此处可添加图片上传逻辑,暂用临时路径
|
||
this.form.icon = tempFilePath;
|
||
}
|
||
});
|
||
},
|
||
|
||
// 转换头衔文本
|
||
getTitleText(usertitle) {
|
||
return this.titleMap[usertitle] || '无头衔';
|
||
},
|
||
|
||
// 表单提交(后续对接后端接口)
|
||
async submitForm() {
|
||
// 1. 必填项校验
|
||
if (!this.form.name) {
|
||
return uni.showToast({ title: '请输入成员姓名', icon: 'none' });
|
||
}
|
||
if (!this.form.addtimes) {
|
||
return uni.showToast({ title: '请选择加入日期', icon: 'none' });
|
||
}
|
||
|
||
// 2. 锁定提交状态
|
||
this.isSubmitting = true;
|
||
|
||
try {
|
||
// 3. 模拟提交(后续替换为后端接口请求)
|
||
console.log('提交的成员信息:', this.form);
|
||
|
||
// 4. 提交成功提示
|
||
uni.showToast({ title: '新增成员成功', icon: 'success' });
|
||
|
||
// 5. 延迟返回列表页
|
||
setTimeout(() => {
|
||
this.goBack();
|
||
}, 1500);
|
||
} catch (err) {
|
||
uni.showToast({ title: '提交失败,请重试', icon: 'none' });
|
||
console.error('新增成员失败:', err);
|
||
} finally {
|
||
// 6. 解锁提交状态
|
||
this.isSubmitting = false;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 补充样式:适配表单布局 */
|
||
.ciy-edit {
|
||
width: 100%;
|
||
height: 2rem;
|
||
border: 1px solid var(--bg6);
|
||
border-radius: 0.3rem;
|
||
}
|
||
.w-12 { width: 3rem; }
|
||
.h-12 { height: 3rem; }
|
||
</style> |