323 lines
9.6 KiB
Vue
323 lines
9.6 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">
|
|
<!-- 课题标题 -->
|
|
<view class="ciy-form">
|
|
<label class="imp">课题标题</label>
|
|
<view>
|
|
<ciy-input name="name" v-model="form.name" placeholder="请输入课题标题" required></ciy-input>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 备案编号 -->
|
|
<view class="ciy-form">
|
|
<label>备案编号</label>
|
|
<view>
|
|
<ciy-input name="recordno" v-model="form.recordno" placeholder="请输入备案编号"></ciy-input>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 摘要 -->
|
|
<view class="ciy-form">
|
|
<label>摘要</label>
|
|
<view>
|
|
<ciy-input type="textarea" name="descs" v-model="form.descs" placeholder="请输入摘要"></ciy-input>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 预算金额 -->
|
|
<view class="ciy-form">
|
|
<label>预算金额</label>
|
|
<view>
|
|
<ciy-inputbet bet="1000000" unit="万元" name="budgetmoney" v-model="form.budgetmoney"></ciy-inputbet>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 服务机构 -->
|
|
<view class="ciy-form">
|
|
<label>服务机构</label>
|
|
<view>
|
|
<ciy-input name="serviceorg" v-model="form.serviceorg" placeholder="请输入服务机构"></ciy-input>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 负责人 -->
|
|
<view class="ciy-form">
|
|
<label>负责人</label>
|
|
<view>
|
|
<ciy-select :range="page_users" name="principal_id" v-model="form.principal_id"></ciy-select>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 所属机构 -->
|
|
<view class="ciy-form">
|
|
<label>所属机构</label>
|
|
<view>
|
|
<ciy-select :range="page_orgs" name="laborgid" v-model="form.laborgid"></ciy-select>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 科研类目 -->
|
|
<view class="ciy-form">
|
|
<label>科研类目</label>
|
|
<view>
|
|
<ciy-select :range="g.rcate" name="rcate" v-model="form.rcate"></ciy-select>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 课题状态 -->
|
|
<view class="ciy-form">
|
|
<label>课题状态</label>
|
|
<view>
|
|
<ciy-select :range="g.rprojectstatus" name="rprojectstatus" v-model="form.rprojectstatus"></ciy-select>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 是否公开 -->
|
|
<view class="ciy-form">
|
|
<label>是否公开</label>
|
|
<view>
|
|
<ciy-radio :range="g.isweb" name="isweb" v-model="form.isweb"></ciy-radio>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 备案方向 -->
|
|
<view class="ciy-form">
|
|
<label>备案方向</label>
|
|
<ciy-selcas
|
|
v-model="form.direction"
|
|
name="direction"
|
|
:range="g.direction"
|
|
placeholder="请选择备案方向"
|
|
></ciy-selcas>
|
|
</view>
|
|
|
|
<!-- 主管部门 -->
|
|
<view class="ciy-form">
|
|
<label>主管部门</label>
|
|
<view>
|
|
<ciy-input name="mdeptname" v-model="form.mdeptname" placeholder="请输入主管部门"></ciy-input>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 层次 -->
|
|
<view class="ciy-form">
|
|
<label>层次</label>
|
|
<view>
|
|
<ciy-select :range="g.mdeptlevel" name="mdeptlevel" v-model="form.mdeptlevel"></ciy-select>
|
|
</view>
|
|
</view>
|
|
<view class="ciy-form">
|
|
<label>进度</label>
|
|
<view>
|
|
<ciy-input name="progress" v-model="form.progress"></ciy-input>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 最新进展日期 -->
|
|
<view class="ciy-form">
|
|
<label>最新进展日期</label>
|
|
<view>
|
|
<ciy-inputdatetime name="lasttimes" v-model="form.lasttimes"></ciy-inputdatetime>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 备案时间 -->
|
|
<view class="ciy-form">
|
|
<label>备案时间</label>
|
|
<view>
|
|
<ciy-inputdatetime name="recordtime" v-model="form.recordtime"></ciy-inputdatetime>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 最新附件 -->
|
|
<view class="ciy-form">
|
|
<label>最新附件</label>
|
|
<view>
|
|
<ciy-upload path="demo" name="latestattachment" v-model="form.latestattachment"></ciy-upload>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 项目成员 -->
|
|
<view class="ciy-form">
|
|
<label>项目成员</label>
|
|
<view>
|
|
<view v-for="(member, index) in form.members" :key="index" class="member-row">
|
|
<ciy-select :range="page_users" v-model="member.uid" placeholder="选择成员"></ciy-select>
|
|
<ciy-select :range="g.prole" v-model="member.prole" placeholder="选择角色"></ciy-select>
|
|
<button type="button" @click="removeMember(index)">-</button>
|
|
</view>
|
|
<button type="button" @click="addMember()">+ 添加成员</button>
|
|
</view>
|
|
</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: {
|
|
id: 0,
|
|
recordno: '',
|
|
laborgid: 0,
|
|
isweb: 0,
|
|
rcate: 0,
|
|
name: '',
|
|
descs: '',
|
|
mdeptname: '',
|
|
mdeptlevel: 0,
|
|
budgetmoney: 0,
|
|
serviceorg: '',
|
|
principal_id: 0,
|
|
rprojectstatus: 0,
|
|
progress: 0,
|
|
lasttimes: 0,
|
|
recordtime: 0,
|
|
latestcontent: '',
|
|
latestattachment: '',
|
|
direction: 0,
|
|
members: []
|
|
},
|
|
page_users: [],
|
|
page_orgs: [],
|
|
};
|
|
},
|
|
async onLoad() {
|
|
await this.loadInitialData();
|
|
},
|
|
methods: {
|
|
goBack() {
|
|
uni.navigateBack({ delta: 1 });
|
|
},
|
|
async loadInitialData(){
|
|
|
|
const retjson = await this.callfunc({
|
|
func: 'project.addinit',
|
|
data: { act: 'edit' }
|
|
});
|
|
console.log('--- project.addinit 返回的数据 ---', retjson);
|
|
if (retjson.code === 1) {
|
|
const rawUsers = retjson.users || [];
|
|
this.page_users = rawUsers.map(user => ({
|
|
id: user.id,
|
|
name: user.name
|
|
}));
|
|
|
|
|
|
const rawOrgs = retjson.orgs || [];
|
|
console.log('--- rawOrgs from backend ---', rawOrgs);
|
|
this.page_orgs = rawOrgs.map(org => ({
|
|
id: org.id,
|
|
name: org.name
|
|
}));
|
|
console.log('--- this.page_orgs after mapping ---', this.page_orgs); // 调试日志
|
|
if (retjson.rcate) this.$set(this.g, 'rcate', retjson.rcate);
|
|
if (retjson.rprojectstatus) this.$set(this.g, 'rprojectstatus', retjson.rprojectstatus);
|
|
if (retjson.direction) this.$set(this.g, 'direction', retjson.direction);
|
|
if (retjson.isweb) this.$set(this.g, 'isweb', retjson.isweb);
|
|
if (retjson.mdeptlevel) this.$set(this.g, 'mdeptlevel', retjson.mdeptlevel);
|
|
if (retjson.prole) this.$set(this.g, 'prole', retjson.prole);
|
|
if (retjson.principal_id) this.$set(this.g, 'principal_id', retjson.principal_id);
|
|
|
|
} else {
|
|
this.toast(retjson.msg || '获取基础数据失败');
|
|
}
|
|
},
|
|
addMember() {
|
|
const allRoleIds = Object.keys(this.g.prole);
|
|
const firstRoleId = allRoleIds.length > 0 ? allRoleIds[0] : "10";
|
|
this.form.members.push({
|
|
mid: 0,
|
|
uid: 0,
|
|
prole: firstRoleId,
|
|
isNew: true,
|
|
isDeleted: false
|
|
});
|
|
},
|
|
removeMember(index) {
|
|
this.form.members.splice(index, 1);
|
|
},
|
|
async submitForm() {
|
|
if (!this.form.name) {
|
|
return this.toast('请输入课题标题');
|
|
}
|
|
if (!this.form.recordno) {
|
|
return this.toast('请输入备案编号');
|
|
}
|
|
|
|
this.isSubmitting = true;
|
|
try {
|
|
const submitData = { ...this.form };
|
|
// 转换时间戳
|
|
if (submitData.lasttimes) submitData.lasttimes = Math.floor(submitData.lasttimes / 1000);
|
|
if (submitData.recordtime) submitData.recordtime = Math.floor(submitData.recordtime / 1000);
|
|
|
|
console.log("准备提交的完整数据:", JSON.stringify(submitData, null, 2));
|
|
const retjson = await this.callfunc({
|
|
func: 'project.add',
|
|
data: submitData
|
|
});
|
|
|
|
if (retjson.err && retjson.err.length) {
|
|
const errorMsg = retjson.err[0]?.msg || retjson.err[0]?.type || '网络请求异常';
|
|
throw new Error(`请求失败: ${errorMsg}`);
|
|
}
|
|
if (retjson.code !== 1) {
|
|
throw new Error(retjson.msg || '添加课题失败');
|
|
}
|
|
|
|
this.toast('添加课题信息成功');
|
|
uni.$emit('project-added');
|
|
setTimeout(() => this.goBack(), 1500);
|
|
} catch (err) {
|
|
this.toast(err.message);
|
|
console.error('提交编辑异常:', err);
|
|
} finally {
|
|
this.isSubmitting = false;
|
|
}
|
|
}
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.ciy-edit {
|
|
width: 100%;
|
|
height: 2rem;
|
|
border: 1px solid var(--bg6);
|
|
border-radius: 0.3rem;
|
|
}
|
|
.text-xs {
|
|
font-size: 0.75rem;
|
|
}
|
|
.text-gray-500 {
|
|
color: #9ca3af;
|
|
}
|
|
.mt1 {
|
|
margin-top: 0.25rem;
|
|
}
|
|
.member-row {
|
|
display: flex;
|
|
gap: 0.5em;
|
|
align-items: center;
|
|
margin-bottom: 0.5em;
|
|
}
|
|
</style> |