|
@@ -0,0 +1,307 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="800px" @close="handleClose" append-to-body>
|
|
|
|
|
+ <el-form validate-on-rule-change :rules="rules" ref="form" :model="form" label-width="140px">
|
|
|
|
|
+ <!-- 动态渲染问题区域 -->
|
|
|
|
|
+ <div v-if="form.answers && form.answers.length > 0">
|
|
|
|
|
+ <div style="margin-bottom: 20px;margin-top: 20px;" v-for="(answer, index) in form.answers" :key="index">
|
|
|
|
|
+ <div style="margin-bottom: 20px;margin-top: 20px;">
|
|
|
|
|
+ <span style="font-size: 15px;font-weight: bold; margin-left: 31px">{{ answer.title }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div style="margin-left: 31px;">
|
|
|
|
|
+ <el-checkbox-group
|
|
|
|
|
+ v-model="answer.value"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ @change="onCheckboxGroupChange(answer)">
|
|
|
|
|
+ <div v-for="(option, optionIndex) in answer.options" :key="`${index}-${optionIndex}`" style="display: flex; align-items: center; margin-bottom: 10px;">
|
|
|
|
|
+ <el-checkbox :label="option.value" style="margin-right: 10px; flex-shrink: 0;">
|
|
|
|
|
+ {{ option.name }}
|
|
|
|
|
+ </el-checkbox>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 如果选项的open为true且选项被选中,显示备注输入框 -->
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-if="option.open && isOptionSelected(answer, option)"
|
|
|
|
|
+ v-model="option.remarkText"
|
|
|
|
|
+ placeholder="请输入备注信息"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ maxlength="20"
|
|
|
|
|
+ show-word-limit
|
|
|
|
|
+ style="width: 200px; margin-left: 5px;"
|
|
|
|
|
+ @blur="onRemarkBlur(option)"/>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-checkbox-group>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
|
|
+ <el-button @click="dialogVisible = false">取 消</el-button>
|
|
|
|
|
+ <el-button type="primary" @click="submitForm">确 定</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script>
|
|
|
|
|
+import { getInfo, submitSalesInfo } from "@/api/qw/collectionPendingSales";
|
|
|
|
|
+
|
|
|
|
|
+export default {
|
|
|
|
|
+ name: "CompleteCollectionInfoDialog",
|
|
|
|
|
+ props: {
|
|
|
|
|
+ visible: {
|
|
|
|
|
+ type: Boolean,
|
|
|
|
|
+ default: false
|
|
|
|
|
+ },
|
|
|
|
|
+ id: {
|
|
|
|
|
+ type: Number,
|
|
|
|
|
+ required: true
|
|
|
|
|
+ },
|
|
|
|
|
+ userId: {
|
|
|
|
|
+ type: Number,
|
|
|
|
|
+ required: true
|
|
|
|
|
+ },
|
|
|
|
|
+ questionId: {
|
|
|
|
|
+ type: Number,
|
|
|
|
|
+ required: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ data() {
|
|
|
|
|
+ // 自定义验证规则:检查需要备注的选项是否填写了备注
|
|
|
|
|
+ const validateRequiredRemarks = (rule, value, callback) => {
|
|
|
|
|
+ if (!this.validateRequiredRemarks()) {
|
|
|
|
|
+ return callback(new Error('请填写必填的备注信息'));
|
|
|
|
|
+ }
|
|
|
|
|
+ callback();
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ dialogVisible: false,
|
|
|
|
|
+ form: {
|
|
|
|
|
+ id: null,
|
|
|
|
|
+ questionId: null,
|
|
|
|
|
+ packageId: null,
|
|
|
|
|
+ payType: null,
|
|
|
|
|
+ amount: null,
|
|
|
|
|
+ isPackage: null,
|
|
|
|
|
+ answers: [],
|
|
|
|
|
+ userName: '',
|
|
|
|
|
+ userPhoneFour: '',
|
|
|
|
|
+ sex: null,
|
|
|
|
|
+ age: null,
|
|
|
|
|
+ allergy: '',
|
|
|
|
|
+ remark: ''
|
|
|
|
|
+ },
|
|
|
|
|
+ privatePackageOptions: [],
|
|
|
|
|
+ // 新增:加载状态
|
|
|
|
|
+ loading: false,
|
|
|
|
|
+ rules: {
|
|
|
|
|
+ // 添加对备注的验证
|
|
|
|
|
+ answers: [
|
|
|
|
|
+ {required: true, validator: validateRequiredRemarks, trigger: 'blur'}
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+ computed: {
|
|
|
|
|
+ dialogTitle() {
|
|
|
|
|
+ return "完善采集信息";
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ watch: {
|
|
|
|
|
+ visible: {
|
|
|
|
|
+ handler(val) {
|
|
|
|
|
+ this.dialogVisible = val;
|
|
|
|
|
+ if (val) {
|
|
|
|
|
+ this.initDialog();
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ immediate: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ created() {
|
|
|
|
|
+ },
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ // 验证需要备注的选项是否填写了备注
|
|
|
|
|
+ validateRequiredRemarks() {
|
|
|
|
|
+ for (const answer of this.form.answers) {
|
|
|
|
|
+ for (const option of answer.options) {
|
|
|
|
|
+ if (option.open && answer.value.includes(option.value)) {
|
|
|
|
|
+ if (!option.remarkText || option.remarkText.trim() === '') {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return true;
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 监听复选框组的变化
|
|
|
|
|
+ onCheckboxGroupChange(answer) {
|
|
|
|
|
+ // 遍历所有选项,如果选项未被选中,则清除其备注文本
|
|
|
|
|
+ answer.options.forEach(option => {
|
|
|
|
|
+ if (!answer.value.includes(option.value)) {
|
|
|
|
|
+ option.remarkText = '';
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 检查选项是否被选中
|
|
|
|
|
+ isOptionSelected(answer, option) {
|
|
|
|
|
+ return answer.value && answer.value.includes(option.value);
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 备注输入框失去焦点时的处理
|
|
|
|
|
+ onRemarkBlur(option) {
|
|
|
|
|
+ // 如果备注文本为空,则清空
|
|
|
|
|
+ if (!option.remarkText?.trim()) {
|
|
|
|
|
+ option.remarkText = '';
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ initDialog() {
|
|
|
|
|
+ this.resetFormData();
|
|
|
|
|
+ if (this.userId) {
|
|
|
|
|
+ this.loadUserData();
|
|
|
|
|
+ }
|
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
|
+ if (this.$refs.form) {
|
|
|
|
|
+ this.$refs.form.clearValidate();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ loadUserData() {
|
|
|
|
|
+ this.loading = true;
|
|
|
|
|
+ getInfo({userId: this.userId, questionId: this.questionId}).then(response => {
|
|
|
|
|
+ const data = response.data;
|
|
|
|
|
+ this.form = {
|
|
|
|
|
+ id: data.id,
|
|
|
|
|
+ questionId: data.questionId,
|
|
|
|
|
+ packageId: data.packageId,
|
|
|
|
|
+ payType: data.payType,
|
|
|
|
|
+ amount: data.amount,
|
|
|
|
|
+ isPackage: data.isPackage,
|
|
|
|
|
+ answers: this.processAnswers(data.answers),
|
|
|
|
|
+ userName: data.userName,
|
|
|
|
|
+ userPhoneFour: data.userPhoneFour,
|
|
|
|
|
+ sex: data.sex,
|
|
|
|
|
+ age: data.age,
|
|
|
|
|
+ allergy: data.allergy,
|
|
|
|
|
+ remark: data.remark
|
|
|
|
|
+ };
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
|
+ this.$message.error('加载用户信息失败');
|
|
|
|
|
+ console.error('加载用户信息失败:', error);
|
|
|
|
|
+ }).finally(() => {
|
|
|
|
|
+ this.loading = false;
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 处理答案数据,确保选项有备注相关的字段
|
|
|
|
|
+ processAnswers(answers) {
|
|
|
|
|
+ if (!answers || !Array.isArray(answers)) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return answers.map(answer => {
|
|
|
|
|
+ // 建立 value -> text 的映射,用于快速回填备注
|
|
|
|
|
+ const remarksMap = {};
|
|
|
|
|
+ if (answer.remarksList && Array.isArray(answer.remarksList)) {
|
|
|
|
|
+ answer.remarksList.forEach(item => {
|
|
|
|
|
+ remarksMap[item.value] = item.text;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const processedOptions = (answer.options || []).map(option => ({
|
|
|
|
|
+ ...option,
|
|
|
|
|
+ remarkText: remarksMap[option.value] || '' // 有备注则填充,否则为空
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...answer,
|
|
|
|
|
+ options: processedOptions
|
|
|
|
|
+ // 保留原始的 remarksList,但在组件内不再使用它,而是使用选项上的 remarkText
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ resetFormData() {
|
|
|
|
|
+ this.form = {
|
|
|
|
|
+ id: null,
|
|
|
|
|
+ questionId: null,
|
|
|
|
|
+ packageId: null,
|
|
|
|
|
+ payType: null,
|
|
|
|
|
+ amount: null,
|
|
|
|
|
+ isPackage: null,
|
|
|
|
|
+ answers: [],
|
|
|
|
|
+ userName: '',
|
|
|
|
|
+ userPhoneFour: '',
|
|
|
|
|
+ sex: null,
|
|
|
|
|
+ age: null,
|
|
|
|
|
+ allergy: '',
|
|
|
|
|
+ remark: ''
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ submitForm() {
|
|
|
|
|
+ this.$refs["form"].validate(valid => {
|
|
|
|
|
+ if (valid) {
|
|
|
|
|
+ // 验证必填备注
|
|
|
|
|
+ if (!this.validateRequiredRemarks()) {
|
|
|
|
|
+ this.$message.error('请填写必填的备注信息');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建提交用的 answers 副本,组装 remarksList 并清理临时字段
|
|
|
|
|
+ const answersForSubmit = this.form.answers.map(answer => {
|
|
|
|
|
+ // 构建 remarksList
|
|
|
|
|
+ const remarks = [];
|
|
|
|
|
+ answer.options.forEach(option => {
|
|
|
|
|
+ if (option.remarkText && option.remarkText.trim()) {
|
|
|
|
|
+ remarks.push({
|
|
|
|
|
+ value: option.value,
|
|
|
|
|
+ text: option.remarkText.trim()
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 清理 options,移除临时字段 remarkText
|
|
|
|
|
+ const cleanOptions = answer.options.map(({remarkText, ...opt}) => opt);
|
|
|
|
|
+
|
|
|
|
|
+ // 返回符合后端 AnswerVO 结构的对象
|
|
|
|
|
+ return {
|
|
|
|
|
+ ...answer,
|
|
|
|
|
+ remarksList: remarks, // 标准备注字段
|
|
|
|
|
+ options: cleanOptions // 纯净的选项列表
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 构建提交数据,使用处理后的 answers
|
|
|
|
|
+ const submitData = {
|
|
|
|
|
+ ...this.form,
|
|
|
|
|
+ id: this.id,
|
|
|
|
|
+ answers: answersForSubmit
|
|
|
|
|
+ };
|
|
|
|
|
+ // 提交请求
|
|
|
|
|
+ submitSalesInfo(submitData).then(res => {
|
|
|
|
|
+ this.$message.success("完善信息成功");
|
|
|
|
|
+ this.dialogVisible = false;
|
|
|
|
|
+ this.$emit('success');
|
|
|
|
|
+ this.$emit('update:visible', false);
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
|
+ this.$message.error(error.msg || "完善信息失败");
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ handleClose() {
|
|
|
|
|
+ this.dialogVisible = false;
|
|
|
|
|
+ this.$emit('update:visible', false);
|
|
|
|
|
+ this.resetFormData();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+</style>
|