|
@@ -30,17 +30,20 @@
|
|
|
{{ option.name }}
|
|
{{ option.name }}
|
|
|
</el-checkbox>
|
|
</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;"
|
|
|
|
|
- :disabled="!canEditAnswers"
|
|
|
|
|
- @blur="onRemarkBlur(option)"/>
|
|
|
|
|
|
|
+ <!-- 备注输入区域 -->
|
|
|
|
|
+ <div v-if="option.open && isOptionSelected(answer, option)" style="display: inline-block;">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="option.remarkText"
|
|
|
|
|
+ placeholder="请输入备注信息"
|
|
|
|
|
+ size="mini"
|
|
|
|
|
+ maxlength="20"
|
|
|
|
|
+ show-word-limit
|
|
|
|
|
+ style="width: 200px; margin-left: 5px;"
|
|
|
|
|
+ :class="{ 'remark-required': isRemarkRequired(answer, option) }"
|
|
|
|
|
+ :disabled="!canEditAnswers"
|
|
|
|
|
+ @blur="onRemarkBlur(option)"/>
|
|
|
|
|
+ <div v-if="isRemarkRequired(answer, option)" class="remark-error-tip">此项为必填</div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</el-checkbox-group>
|
|
</el-checkbox-group>
|
|
|
</div>
|
|
</div>
|
|
@@ -180,7 +183,6 @@ export default {
|
|
|
qrCodeTitle: "用户信息采集分享",
|
|
qrCodeTitle: "用户信息采集分享",
|
|
|
qrCodeName: null,
|
|
qrCodeName: null,
|
|
|
codeImage: null,
|
|
codeImage: null,
|
|
|
- // 新增:加载状态
|
|
|
|
|
permissionLoading: false,
|
|
permissionLoading: false,
|
|
|
rules: {
|
|
rules: {
|
|
|
appId: [
|
|
appId: [
|
|
@@ -259,12 +261,9 @@ export default {
|
|
|
this.getQuestionOptions();
|
|
this.getQuestionOptions();
|
|
|
this.getAllPrivatePackge();
|
|
this.getAllPrivatePackge();
|
|
|
this.getSourceOptions();
|
|
this.getSourceOptions();
|
|
|
- // ==========获取销售代填权限配置 ==========
|
|
|
|
|
this.fetchSalesProxyFillPermission();
|
|
this.fetchSalesProxyFillPermission();
|
|
|
- // ==============================================
|
|
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
- // ==========获取销售代填权限 ==========
|
|
|
|
|
async fetchSalesProxyFillPermission() {
|
|
async fetchSalesProxyFillPermission() {
|
|
|
this.permissionLoading = true;
|
|
this.permissionLoading = true;
|
|
|
try {
|
|
try {
|
|
@@ -278,9 +277,14 @@ export default {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
|
|
+ // 判断某个选项的备注是否为必填且未填写
|
|
|
|
|
+ isRemarkRequired(answer, option) {
|
|
|
|
|
+ if (!this.isSalesProxyFill) return false;
|
|
|
|
|
+ return option.open && this.isOptionSelected(answer, option) && (!option.remarkText || option.remarkText.trim() === '');
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
// 监听复选框组的变化
|
|
// 监听复选框组的变化
|
|
|
onCheckboxGroupChange(answer) {
|
|
onCheckboxGroupChange(answer) {
|
|
|
- // 遍历所有选项,如果选项未被选中,则清除其备注文本
|
|
|
|
|
answer.options.forEach(option => {
|
|
answer.options.forEach(option => {
|
|
|
if (!answer.value.includes(option.value)) {
|
|
if (!answer.value.includes(option.value)) {
|
|
|
option.remarkText = '';
|
|
option.remarkText = '';
|
|
@@ -296,7 +300,6 @@ export default {
|
|
|
|
|
|
|
|
// 备注输入框失去焦点时的处理
|
|
// 备注输入框失去焦点时的处理
|
|
|
onRemarkBlur(option) {
|
|
onRemarkBlur(option) {
|
|
|
- // 如果备注文本为空,则清空
|
|
|
|
|
if (!option.remarkText?.trim()) {
|
|
if (!option.remarkText?.trim()) {
|
|
|
option.remarkText = '';
|
|
option.remarkText = '';
|
|
|
}
|
|
}
|
|
@@ -310,14 +313,12 @@ export default {
|
|
|
const origAnswer = original[i];
|
|
const origAnswer = original[i];
|
|
|
const currAnswer = current[i];
|
|
const currAnswer = current[i];
|
|
|
|
|
|
|
|
- // 比较基本属性
|
|
|
|
|
if (origAnswer.title !== currAnswer.title ||
|
|
if (origAnswer.title !== currAnswer.title ||
|
|
|
origAnswer.sort !== currAnswer.sort ||
|
|
origAnswer.sort !== currAnswer.sort ||
|
|
|
origAnswer.flag !== currAnswer.flag) {
|
|
origAnswer.flag !== currAnswer.flag) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 比较选择的值
|
|
|
|
|
if (!origAnswer.value || !currAnswer.value) {
|
|
if (!origAnswer.value || !currAnswer.value) {
|
|
|
if (origAnswer.value !== currAnswer.value) return false;
|
|
if (origAnswer.value !== currAnswer.value) return false;
|
|
|
} else {
|
|
} else {
|
|
@@ -329,7 +330,6 @@ export default {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 比较选项
|
|
|
|
|
if (origAnswer.options && currAnswer.options) {
|
|
if (origAnswer.options && currAnswer.options) {
|
|
|
if (origAnswer.options.length !== currAnswer.options.length) return false;
|
|
if (origAnswer.options.length !== currAnswer.options.length) return false;
|
|
|
|
|
|
|
@@ -337,7 +337,6 @@ export default {
|
|
|
const origOption = origAnswer.options[k];
|
|
const origOption = origAnswer.options[k];
|
|
|
const currOption = currAnswer.options[k];
|
|
const currOption = currAnswer.options[k];
|
|
|
|
|
|
|
|
- // 比较基本选项属性
|
|
|
|
|
if (origOption.name !== currOption.name ||
|
|
if (origOption.name !== currOption.name ||
|
|
|
origOption.value !== currOption.value ||
|
|
origOption.value !== currOption.value ||
|
|
|
origOption.open !== currOption.open ||
|
|
origOption.open !== currOption.open ||
|
|
@@ -358,11 +357,13 @@ export default {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
getSourceOptions() {
|
|
getSourceOptions() {
|
|
|
options().then(res => {
|
|
options().then(res => {
|
|
|
this.sourceList = res.data;
|
|
this.sourceList = res.data;
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
handleIsPackageChange(value) {
|
|
handleIsPackageChange(value) {
|
|
|
if (value === 0) {
|
|
if (value === 0) {
|
|
|
this.form.packageId = null;
|
|
this.form.packageId = null;
|
|
@@ -373,6 +374,7 @@ export default {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
downloadImage(imageSrc, fileName) {
|
|
downloadImage(imageSrc, fileName) {
|
|
|
const link = document.createElement('a');
|
|
const link = document.createElement('a');
|
|
|
link.href = imageSrc;
|
|
link.href = imageSrc;
|
|
@@ -381,6 +383,7 @@ export default {
|
|
|
link.click();
|
|
link.click();
|
|
|
document.body.removeChild(link);
|
|
document.body.removeChild(link);
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
handleShare(id, appId) {
|
|
handleShare(id, appId) {
|
|
|
let loadingRock = this.$loading({
|
|
let loadingRock = this.$loading({
|
|
|
lock: true,
|
|
lock: true,
|
|
@@ -398,16 +401,19 @@ export default {
|
|
|
loadingRock.close();
|
|
loadingRock.close();
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
getQuestionOptions() {
|
|
getQuestionOptions() {
|
|
|
questionOptions().then(response => {
|
|
questionOptions().then(response => {
|
|
|
this.questionOptions = response.rows;
|
|
this.questionOptions = response.rows;
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
getAllPrivatePackge() {
|
|
getAllPrivatePackge() {
|
|
|
allPrivatePackage().then(res => {
|
|
allPrivatePackage().then(res => {
|
|
|
this.privatePackageOptions = res.rows;
|
|
this.privatePackageOptions = res.rows;
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
selectQuestion(val) {
|
|
selectQuestion(val) {
|
|
|
if (!val) return;
|
|
if (!val) return;
|
|
|
|
|
|
|
@@ -443,7 +449,6 @@ export default {
|
|
|
flag: item.flag || false
|
|
flag: item.flag || false
|
|
|
}));
|
|
}));
|
|
|
|
|
|
|
|
- // 保存原始 answers
|
|
|
|
|
this.originalAnswers = JSON.parse(JSON.stringify(answers));
|
|
this.originalAnswers = JSON.parse(JSON.stringify(answers));
|
|
|
this.isAnswersModified = 0;
|
|
this.isAnswersModified = 0;
|
|
|
|
|
|
|
@@ -475,14 +480,12 @@ export default {
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- // 处理选项数据,添加备注相关的默认值
|
|
|
|
|
processOptions(options) {
|
|
processOptions(options) {
|
|
|
return options.map(option => {
|
|
return options.map(option => {
|
|
|
return {
|
|
return {
|
|
|
name: option.name || '',
|
|
name: option.name || '',
|
|
|
value: option.value,
|
|
value: option.value,
|
|
|
open: option.open || false,
|
|
open: option.open || false,
|
|
|
- // 添加备注相关的字段
|
|
|
|
|
remarkText: ''
|
|
remarkText: ''
|
|
|
};
|
|
};
|
|
|
});
|
|
});
|
|
@@ -512,12 +515,33 @@ export default {
|
|
|
this.originalAnswers = null;
|
|
this.originalAnswers = null;
|
|
|
this.isAnswersModified = 0;
|
|
this.isAnswersModified = 0;
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
|
|
+ // 自定义备注必填校验
|
|
|
|
|
+ validateRemarksRequired() {
|
|
|
|
|
+ if (!this.isSalesProxyFill) return true;
|
|
|
|
|
+ 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;
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
submitForm() {
|
|
submitForm() {
|
|
|
this.$refs["form"].validate(valid => {
|
|
this.$refs["form"].validate(valid => {
|
|
|
if (valid) {
|
|
if (valid) {
|
|
|
- // 1. 构建提交用的 answers 副本,组装 remarksList 并清理临时字段
|
|
|
|
|
|
|
+ // 1. 自定义备注必填校验
|
|
|
|
|
+ if (!this.validateRemarksRequired()) {
|
|
|
|
|
+ this.$message.error('请填写所有必填的备注信息');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 构建提交用的 answers 副本
|
|
|
const answersForSubmit = this.form.answers.map(answer => {
|
|
const answersForSubmit = this.form.answers.map(answer => {
|
|
|
- // 1. 构建 remarksList
|
|
|
|
|
const remarks = [];
|
|
const remarks = [];
|
|
|
answer.options.forEach(option => {
|
|
answer.options.forEach(option => {
|
|
|
if (option.remarkText && option.remarkText.trim()) {
|
|
if (option.remarkText && option.remarkText.trim()) {
|
|
@@ -528,18 +552,15 @@ export default {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- // 2. 清理 options,移除临时字段 remarkText
|
|
|
|
|
- const cleanOptions = answer.options.map(({ remarkText, ...opt }) => opt);
|
|
|
|
|
|
|
+ const cleanOptions = answer.options.map(({remarkText, ...opt}) => opt);
|
|
|
|
|
|
|
|
- // 3. 返回符合后端 AnswerVO 结构的对象
|
|
|
|
|
return {
|
|
return {
|
|
|
...answer,
|
|
...answer,
|
|
|
- remarksList: remarks, // 标准备注字段
|
|
|
|
|
- options: cleanOptions // 纯净的选项列表
|
|
|
|
|
|
|
+ remarksList: remarks,
|
|
|
|
|
+ options: cleanOptions
|
|
|
};
|
|
};
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- // 2. 构建提交数据,使用处理后的 answers
|
|
|
|
|
const submitData = {
|
|
const submitData = {
|
|
|
...this.form,
|
|
...this.form,
|
|
|
answers: answersForSubmit,
|
|
answers: answersForSubmit,
|
|
@@ -549,7 +570,6 @@ export default {
|
|
|
fillFlag: this.isAnswersModified
|
|
fillFlag: this.isAnswersModified
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- // 3. 根据是否关联套餐包清理无关字段
|
|
|
|
|
if (submitData.isPackage !== 1) {
|
|
if (submitData.isPackage !== 1) {
|
|
|
delete submitData.packageId;
|
|
delete submitData.packageId;
|
|
|
delete submitData.payType;
|
|
delete submitData.payType;
|
|
@@ -562,7 +582,6 @@ export default {
|
|
|
|
|
|
|
|
const appId = this.form.appId;
|
|
const appId = this.form.appId;
|
|
|
|
|
|
|
|
- // 4. 提交请求
|
|
|
|
|
createSimpleUserInfo(submitData).then(res => {
|
|
createSimpleUserInfo(submitData).then(res => {
|
|
|
this.$message.success("新增成功");
|
|
this.$message.success("新增成功");
|
|
|
this.dialogVisible = false;
|
|
this.dialogVisible = false;
|
|
@@ -577,6 +596,7 @@ export default {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
handleClose() {
|
|
handleClose() {
|
|
|
this.dialogVisible = false;
|
|
this.dialogVisible = false;
|
|
|
this.$emit('update:visible', false);
|
|
this.$emit('update:visible', false);
|
|
@@ -587,5 +607,16 @@ export default {
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
-/* 移除了原有的 remark-toggle 样式,因为我们不再使用 */
|
|
|
|
|
|
|
+/* 必填备注输入框红色边框 */
|
|
|
|
|
+.remark-required >>> .el-input__inner {
|
|
|
|
|
+ border-color: #f56c6c !important;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 必填提示文字 */
|
|
|
|
|
+.remark-error-tip {
|
|
|
|
|
+ color: #f56c6c;
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ line-height: 1.5;
|
|
|
|
|
+ margin-left: 5px;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|