You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

472 lines
14 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="container">
<image class="cbg" :src="base.imgHost('common_bg.png')"></image>
<!-- <u-divider>个人信息</u-divider> -->
<view class="wrap">
<applyForm ref="applyForm" @backForm="backForm" :course_forms="course_forms"></applyForm>
</view>
<!-- 差异展示弹窗 -->
<difference-modal
:show="showDifferenceModal"
:differenceList="differenceList"
@choice="handleDifferenceChoice"
></difference-modal>
</view>
</template>
<script>
import applyForm from "@/components/applyForm/index.vue"
import differenceModal from "@/components/difference-modal/index.vue"
export default {
components: {
applyForm,
differenceModal
},
data() {
return {
course_id: '',
is_fee: 0, //需不需要缴费这个课程
form: {},
apply_form: [],
course_forms: [],
sign_id: '', // 报名的id
opType: 'add', // edit 修改
isLocked: false,
change_data:[], // 记录报名表中填写的字段和 form学员信息中不同的
is_change:0,
differenceList: [], // 存储详细的差异信息(字段名、原值、新值、字段映射)
showDifferenceModal: false // 控制差异弹窗显示
}
},
onReady() {
// this.$refs.uForm.setRules(this.rules);
},
async onLoad(options) {
this.course_id = options.id
// 先获取最新的用户信息
await this.getUserInfo()
if (options.type === 'edit') {
this.opType = 'edit'
this.getCourseDetail(options.id)
// this.getSignDetail(options.id)
} else {
this.getCourseDetail(options.id)
}
},
methods: {
// 获取最新的用户信息
async getUserInfo() {
try {
const res = await this.$u.api.user()
if (res && res.user) {
this.form = res.user
// 更新 vuex 和本地存储
this.$u.vuex('vuex_user', res.user)
}
} catch (err) {
console.log("获取用户信息失败", err)
// 如果获取失败,使用缓存中的用户信息作为备选
let user = uni.getStorageSync("stbc1_lifeData") ? uni.getStorageSync("stbc1_lifeData").vuex_user : {}
this.form = user || {}
}
},
async getCourseDetail(id) {
const res = await this.$u.api.courseDetail({
course_id: id
})
if (res.course_forms && res.course_forms.length > 0) {
res.course_forms.map(item => {
if (item.belong_user === 1) {
// 使用用户表字段名获取用户信息,如果没有则使用表单字段名
const userTableField = item.belong_user_table || item.field
item.value = this.form[userTableField]
}
if (item.value === null) {
item.value = ''
}
})
this.course_forms = res.course_forms.sort((a, b) => (a.sort - b.sort))
}
this.is_fee = res.is_fee
if(this.opType == 'edit'){
this.getSignDetail(id)
}
},
// 修改
async getSignDetail(id) {
const res = await this.$u.api.courseGetSign({
course_id: id
})
this.sign_id = res.detail.id
if (res.detail.data && res.detail.data.length > 0) {
res.detail.data.map(item => {
this.course_forms.map((forms,index)=>{
if(item.field==forms.field){
forms.value = item.value?item.value:''
if(forms.edit_input==='files'){
this.$set(forms,'fileListArr',item.fileListArr?item.fileListArr:[])
this.$set(forms,'fileList',item.fileList?item.fileList:[])
}
}
})
// if (item.value === null) {
// item.value = ''
// }
})
console.log("this.course_forms",this.course_forms)
// this.course_forms = res.detail.data.sort((a, b) => (a.sort - b.sort))
}
},
async backForm(e) {
let _arr = []
let that = this
let change_data_arr = []
let difference_list = []
e.map(item => {
item.value = item.value ? item.value : ''
// 确保文件类型字段的 fileList 和 fileListArr 被正确保存
if (item.edit_input === 'files') {
// 确保 fileList 和 fileListArr 存在
if (!item.hasOwnProperty('fileList')) {
item.fileList = []
}
if (!item.hasOwnProperty('fileListArr')) {
item.fileListArr = []
}
}
_arr.push(item)
// 更新学员user表中的字段 学员字段有值
if (item.belong_user === 1 && !this.base.isNull(item.value)) {
// 获取用户表字段名,如果没有则使用表单字段名
const userTableField = item.belong_user_table || item.field
// 获取原值(从用户表中获取)
const oldValue = this.form[userTableField] || ''
const newValue = item.value
if(oldValue != newValue){
console.log('item.field',item.field, 'userTableField', userTableField)
// 使用用户表字段名构建 change_data
change_data_arr.push({[userTableField]:item.value})
// 收集详细的差异信息
difference_list.push({
name: item.name || item.field, // 字段显示名
field: item.field, // 表单字段名
belong_user_table: userTableField, // 用户表字段名
oldValue: oldValue || '无', // 原值
newValue: newValue || '无' // 新值
})
}
}
})
this.apply_form = _arr
this.change_data = change_data_arr
this.differenceList = difference_list
console.log("this.apply_form", this.apply_form, this.form, this.change_data, this.differenceList)
this.is_change = 0
if(this.change_data.length > 0){
this.is_change = 1
if (that.isLocked) {
return
}
that.isLocked = true
// 显示差异弹窗
that.showDifferenceModal = true
}else{
that.is_change = 0
if (that.isLocked) {
return
}
that.isLocked = true
// 没有差异,直接显示确认报名弹窗
that.confirmSubmit()
}
},
async saveUser() {
let that = this
this.form.name = this.form.username
await this.$u.api.saveUser(this.form).then(res => {
console.log("user")
// this.$u.api.user().then(res => {
// this.$u.vuex('vuex_user', res.user)
// })
}).catch(err => {
console.log("err", err)
that.isLocked = false
})
},
// 更新用户信息
async updateUserInfo() {
const updateData = {}
const fieldValueMap = {} // 存储字段名 -> 实际值的映射
this.differenceList.forEach(diff => {
// 使用 belong_user_table 作为用户表字段名,如果没有则使用 field
const fieldName = diff.belong_user_table || diff.field
// 直接使用新值,不做特殊处理("无"就是一个普通的值,应该原样提交)
const actualValue = diff.newValue != null ? diff.newValue : ''
updateData[fieldName] = actualValue
fieldValueMap[fieldName] = actualValue
})
try {
await this.$u.api.saveUser(updateData)
// 更新成功后,重新获取最新的用户信息,确保数据一致性
await this.getUserInfo()
// 同步更新 apply_form 中的对应字段值,确保提交时使用最新的值
this.apply_form.forEach(item => {
// 获取用户表字段名
const userTableField = item.belong_user_table || item.field
// 如果字段在更新列表中,更新其值为实际值
if (fieldValueMap.hasOwnProperty(userTableField)) {
item.value = fieldValueMap[userTableField]
}
})
// 更新用户信息后,清空 change_data 和 is_change
// 因为用户信息已经更新,不再需要更新用户信息了
this.change_data = []
this.is_change = 0
return true
} catch (err) {
console.log("更新用户信息失败", err)
this.isLocked = false
uni.showToast({
title: '更新用户信息失败',
icon: 'none'
})
return false
}
},
// 处理用户选择(按本次信息更新/维持原信息/返回修改)
async handleDifferenceChoice(update) {
this.showDifferenceModal = false
if (update === 'cancel') {
// 选择"返回修改",关闭弹窗,解锁,让用户重新修改表单
this.isLocked = false
return
}
if (update) {
// 选择"按本次信息更新"
const success = await this.updateUserInfo()
if (!success) {
return // 更新失败,已处理错误
}
// 更新成功后change_data 已经被清空is_change 也已经在 updateUserInfo 中处理
} else {
// 选择"维持原信息",不更新用户信息
// 但保留 change_data 和 is_change因为报名表中的数据和用户表中的数据确实不同
// 后端需要知道这些差异,所以不能清空
// change_data 和 is_change 已经在 backForm 中正确设置,这里不需要修改
}
// 继续显示确认报名弹窗
this.confirmSubmit()
},
// 最终确认报名弹窗
confirmSubmit() {
let that = this
uni.showModal({
title: '确认报名',
content: '是否确认报名?',
confirmText: '确认提交',
cancelText: '返回修改',
success: function(res) {
if (res.confirm) {
// 确认提交
if (that.opType == 'edit') {
that.updateApplyCourse()
} else {
that.applyCourse()
}
} else {
// 返回修改
that.isLocked = false
}
}
})
},
async applyCourse() {
let that = this
await this.$u.api.courseSign({
course_id: this.course_id,
data: this.apply_form,
change_data:this.change_data,
is_change:this.is_change
}).then(res => {
if (this.is_fee) {
this.newsSubscription()
} else {
that.base.toast("报名已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mycourse/index'
})
}, 1500)
})
}
}).catch(err => {
console.log("err", err)
that.isLocked = false
})
},
// 更新报名信息
async updateApplyCourse() {
// console.log("this.apply_form",this.apply_form)
// return
let that = this
this.$u.api.courseUpdateSign({
id: this.sign_id,
data: this.apply_form,
change_data:this.change_data,
is_change:this.is_change
}).then(res => {
that.base.toast("修改成功", 1500, function() {
setTimeout(function() {
uni.navigateBack({
delta:1
})
}, 1500)
})
}).catch(err => {
console.log("err", err)
that.isLocked = false
})
},
// 订阅缴费
newsSubscription() {
let that = this
uni.getSetting({
withSubscriptions: true, //是否获取用户订阅消息的订阅状态默认false不返回
success(res) {
console.log("resdfg", res)
if (res.subscriptionsSetting.mainSwitch) {
if (res.subscriptionsSetting.itemSettings && res.subscriptionsSetting.itemSettings[
'6bkRNahvR88pG4Tpk0c2aY81kszvFpdaIV-CdC_ENTM'] === 'accept' &&
res.subscriptionsSetting.itemSettings[
'XsR1BJRdE8JtFUC1o3w7DDcscXkCEGu62J8_smMofZI'] === 'accept'
) {
console.log("accept")
// 用户已经订阅该消息模板,执行相应操作
that.base.toast("报名已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mycourse/index'
})
}, 1500)
})
} else {
// 用户没有订阅该消息模板,显示订阅弹窗
uni.showModal({
title: '订阅消息',
content: '是否需要订阅预约结果消息',
success(res1) {
if (res1.confirm) {
uni.requestSubscribeMessage({
tmplIds: [
'6bkRNahvR88pG4Tpk0c2aY81kszvFpdaIV-CdC_ENTM',
'XsR1BJRdE8JtFUC1o3w7DDcscXkCEGu62J8_smMofZI',
],
success(res) {
that.base.toast("报名已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mycourse/index'
})
}, 1500)
})
},
fail(err) {
that.base.toast("报名已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mycourse/index'
})
}, 1500)
})
}
})
} else {
that.base.toast("报名已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mycourse/index'
})
}, 1500)
})
}
}
})
}
} else {
console.log("9999")
that.base.toast("报名已提交", 1500, function() {
setTimeout(function() {
uni.redirectTo({
url: '/packages/mycourse/index'
})
}, 1500)
})
// 用户尚未开启订阅消息总开关,建议提醒用户开启
}
}
});
},
}
}
</script>
<style scoped lang="scss">
.container {
padding: 30rpx;
height: 100vh;
.cbg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
}
.wrap {
background-color: #fff;
padding: 20rpx 50rpx;
border-radius: 20rpx;
position: relative;
height: 100%;
overflow: scroll;
}
.form-btn {
width: 100%;
position: fixed;
left: 0;
bottom: 0;
padding: 20rpx 0;
&>view {
width: 70%;
text-align: center;
margin: 0 auto;
color: #fff;
background: linear-gradient(to right, #5e5fbc, #0d0398);
border-radius: 30rpx;
padding: 20rpx;
}
}
}
</style>