mrr.sj.front/pages/shop/add-service.vue

2216 lines
52 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="add-service">
<view class="fixed-header">
<view class="tip" v-if="formData.back_text && formData.state == 4">
<image
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/390d9d12-3c30-4639-9ac3-7b604b606b6d.png"
class="tip-icon"></image>
<text>{{ formData.back_text }}</text>
</view>
</view>
<!-- 表单区域 -->
<view class="form-container">
<!-- 服务分类(仅显示不可编辑) -->
<view class="form-item service-class-item" v-if="serviceClassName">
<text class="form-label">服务分类:</text>
<text class="form-value service-class-value">{{ serviceClassName }}</text>
</view>
<!-- 动态表单区域 -->
<dynamic-form :fields="formFields" v-model="formData" :upload-user-id="formData.publish_user_id"
ref="dynamicForm" />
<!-- 服务流程 -->
<view class="form-step" v-if="!hasDynamicServiceStepField">
<view class="form-item">
<text class="form-label">服务流程</text>
<text @click="addStep" style="color: #FF4767;">添加步骤</text>
</view>
<view class="step" v-for="(item, i) in formData.process" :key="i">
<text class="form-label">{{ i + 1 }}</text>
<input type="text" class="step-inp" v-model="formData.process[i].text" placeholder="请输入步骤内容" />
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/wxstaic/images/delete_icon.png"
class="delete-icon" mode="aspectFit" @click="deleteStep(i)"></image>
</view>
</view>
<!-- 视频上传 -->
<view class="video-upload" v-if="!hasDynamicVideoField">
<view class="flex-c">
<text class="form-label required">上传视频</text>
<text class="upload-tip">(仅可上传1个视频)</text>
</view>
<ali-oss-uploader :max-count="1" :max-size="100" :type="artisanType + 1"
:user-id="formData.publish_user_id" :width="'654rpx'" :kind="2" :file-string="formData.video"
accept="video/*" button-text="上传视频" @input="setVideoValue" @change="setVideoValue"
@success="uploadVideoSuc" @error="uploadVideoErr" @delete="uploadVideoDel"
@ckeckisShowPer="ckeckisShowPer" @ckecknowQer="ckecknowQer">
</ali-oss-uploader>
</view>
</view>
<!-- 底部按钮 -->
<view class="bottom-buttons">
<button class="btn-draft" @click="saveDraft" v-if="!state || state == 0">
存草稿
</button>
<button class="btn-submit" @click="submitForm">提交</button>
</view>
<!-- 获取权限提示匡内容 -->
<view class="permission" :class="{ transform: isShowPer && nowQer === 'xc' }">
<view class="per-tit">美融融plus 对储存空间/照片权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像、发布商品等场景中读取相册和文件内容。</view>
</view>
<view class="permission" :class="{ transform: isShowPer && nowQer === 'xj' }">
<view class="per-tit">美融融plus 对相机拍摄权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像、发布商品等场景中所需内容。</view>
</view>
</view>
</template>
<script>
import request from "../../utils/request";
import CircleProgress from "@/components/circle-progress/circle-progress.vue";
import DynamicForm from "@/components/dynamic-form/dynamic-form.vue";
import sparkMD5 from "spark-md5"; // 引入MD5计算库
import {
debounce
} from "@/utils/debounce.js";
import AliOssUploader from "../../components/ali-oss-uploader/ali-oss-uploader.vue";
import permissionUtils from "../../utils/per";
import locationService from "../../utils/locationService";
import _public from "../../utils/public";
export default {
components: {
CircleProgress,
AliOssUploader,
DynamicForm,
},
data() {
return {
formFields: [], // 动态表单字段配置
processFieldKey: "", // 服务步骤在config_data中的key用作提交参数名
firstClassName: "",
secondClassName: "",
showReminderPopup: false,
artisanType: getApp().globalData.artisanType,
nowQer: "xc",
progress: 0,
isShow: false,
state: null,
isShowPer: false,
formData: {
publish_user_id: null,
server_kind: getApp().globalData.artisanType,
title: "",
server_price: "",
line_price: '',
server_time: "",
first_class_id: "",
second_class_id: "",
detail: [],
process: [],
video: "",
photo: [],
graphic_details: "",
sj_see: null, // 1代表商家端不可见 2代表商家端可见
// 新增的五个独立字段
efficacy: "",
crowd: "",
product: "",
scope: "",
prompt: "",
},
ratio: null,
// 服务简介部分
detailForm: {
effect: "",
crowd: "",
product: "",
scope: "",
tips: "",
},
detailOtherList: [],
imagesList: [], // 临时图片地址
addDetailList: [],
showProgress: false,
publish_user_id: null,
isAdd: false,
isDraft: false,
postid: 0
};
},
onShow() { },
async onLoad(options) {
// 监听图文详情编辑回调在onLoad注册确保navigateBack时能收到事件
uni.$on("updateGraphicDetails", (data) => {
// 替换整个formData对象引用确保dynamic-form的watch.value能触发
this.formData = Object.assign({}, this.formData, {
graphic_details: JSON.stringify(data)
});
});
this.state = options.state || "";
// 接收分类参数
if (options.first_class_id) {
this.formData.first_class_id = options.first_class_id;
}
if (options.second_class_id) {
this.formData.second_class_id = options.second_class_id;
}
// 获取模板先加载模板再获取详情确保formFields已就绪
await this.getTemplate();
if (options.id) {
this.formData.id = options.id;
await this.getInit();
}
// 获取分类名称用于顶部显示
await this.loadClassNames();
// 判断是否显示上门提醒弹窗
const notShow = uni.getStorageSync('addServiceReminderNotShow');
await this.getUserInfo();
},
onUnload() {
uni.$off("updateGraphicDetails");
},
computed: {
showShopPrice() {
return (
this.artisanType == 1 &&
this.formData.sj_see == 2 &&
this.formData.server_price &&
this.formData.first_class_id
);
},
shopPrice() {
return _public.roundUpToTwoDecimals(
this.formData.server_price,
this.ratio
);
},
hasDynamicVideoField() {
return this.formFields.some((group) => {
if (group.type === 'single' && group.field) {
return group.field.type === 'video';
}
if (group.type === 'section' && Array.isArray(group.fields)) {
return group.fields.some((field) => field.type === 'video');
}
return group.type === 'video';
});
},
hasDynamicServiceStepField() {
return this.formFields.some((group) => {
if (group.type === 'single' && group.field) {
return group.field.type === 'service_step';
}
if (group.type === 'section' && Array.isArray(group.fields)) {
return group.fields.some((field) => field.type === 'service_step');
}
return group.type === 'service_step';
});
},
serviceClassName() {
return [this.firstClassName, this.secondClassName].filter(Boolean).join('/');
},
},
methods: {
// 字段类型映射:接口类型 -> dynamic-form类型
mapFieldType(fieldType) {
const typeMap = {
'text': 'text',
'number': 'number',
'image_multi': 'image_multi',
'video': 'video',
'service_step': 'service_step',
'richtext_editor': 'richtext_editor',
'select': 'select',
'single_select': 'single_select',
'radio': 'single_select',
'switch': 'single_select',
'boolean': 'single_select',
'multi_select': 'multi_select',
'textarea': 'textarea',
};
return typeMap[fieldType] || 'text';
},
normalizeFieldOptions(options) {
if (!Array.isArray(options)) return [];
return options.map((item) => {
if (item && typeof item === 'object') {
const value = item.value !== undefined ? item.value :
(item.id !== undefined ? item.id :
(item.key !== undefined ? item.key :
(item.code !== undefined ? item.code : item.label)));
const label = item.label || item.title || item.name || item.text || String(value);
return {
...item,
label,
value,
};
}
return {
label: String(item),
value: item,
};
});
},
applyFieldHint(field, rawConfig) {
if (!rawConfig || !rawConfig.hint) return;
if (rawConfig.showHint === false || rawConfig.showHint === 0 || rawConfig.showHint === '0') return;
field.tip = rawConfig.hint;
},
// 将接口config_data转换为dynamic-form需要的分组格式
transformConfigToFields(configData) {
const groups = [];
let customFieldIndex = 0;
// 1. 处理presetFields预设字段- 每个字段独立一组
if (configData.presetFields && Array.isArray(configData.presetFields)) {
configData.presetFields.forEach((preset) => {
if (!preset.enabled) return;
const field = {
key: preset.key,
type: this.mapFieldType(preset.fieldType),
label: preset.title,
is_required: preset.required,
placeholder: preset.placeholder || `请输入${preset.title}`,
};
if (preset.options && Array.isArray(preset.options) && preset.options.length > 0) {
field.options = this.normalizeFieldOptions(preset.options);
}
if (preset.default_value !== undefined) {
field.default_value = preset.default_value;
} else if (preset.defaultValue !== undefined) {
field.default_value = preset.defaultValue;
}
this.applyFieldHint(field, preset);
if (preset.key === 'line_price' || preset.key === 'server_price') {
field.tips = '(元)';
if (!field.tip) {
field.tip = preset.key === 'line_price' ? '服务的基础定价,未参与任何优惠的价格' : '服务参与单品优惠后的价格';
}
} else if (preset.key === 'server_time') {
field.placeholder = '请输入服务时长';
field.tips = '分钟';
}
if (preset.maxCount) {
field.maxCount = preset.maxCount;
}
if (preset.maxLength && preset.fieldType === 'text') {
field.maxLength = preset.maxLength;
}
if (preset.maxFileSize) {
field.maxFileSize = preset.maxFileSize;
field.maxSize = preset.maxFileSize;
}
field._fieldType = preset.fieldType;
field._hasOriginalKey = !!preset.key;
groups.push({
type: 'single',
field
});
});
}
// 2. 处理sections区段- 整个section为一组
if (configData.sections && Array.isArray(configData.sections)) {
configData.sections.forEach((section) => {
const sectionFields = [];
if (section.fields && Array.isArray(section.fields)) {
section.fields.forEach((sectionField) => {
const fieldKey = sectionField.key ||
`custom_${sectionField.id || customFieldIndex++}`;
const field = {
key: fieldKey,
type: this.mapFieldType(sectionField.fieldType),
label: sectionField.title,
is_required: sectionField.required,
placeholder: sectionField.placeholder ||
`请输入${sectionField.title}`,
};
if (sectionField.key === 'server_time') {
field.placeholder = '请输入服务时长';
field.tips = '分钟';
}
this.applyFieldHint(field, sectionField);
if (sectionField.options && Array.isArray(sectionField.options) &&
sectionField.options.length > 0) {
field.options = this.normalizeFieldOptions(sectionField.options);
}
if (sectionField.default_value !== undefined) {
field.default_value = sectionField.default_value;
} else if (sectionField.defaultValue !== undefined) {
field.default_value = sectionField.defaultValue;
}
if (sectionField.maxCount && (sectionField.fieldType === 'multi_select' ||
sectionField.fieldType === 'image_multi' || sectionField.fieldType === 'video')) {
field.maxCount = sectionField.maxCount;
}
if (sectionField.maxLength && (sectionField.fieldType === 'text' ||
sectionField.fieldType === 'textarea')) {
field.maxLength = sectionField.maxLength;
}
if (sectionField.maxLength && sectionField.fieldType === 'number') {
field.maxLength = sectionField.maxLength;
}
if (sectionField.maxFileSize) {
field.maxFileSize = sectionField.maxFileSize;
field.maxSize = sectionField.maxFileSize;
}
field._fieldType = sectionField.fieldType;
field._hasOriginalKey = !!sectionField.key;
field._original = {
id: sectionField.id,
sectionId: section.id,
sectionType: section.sectionType,
userDefined: sectionField.userDefined,
};
field._sectionTitle = section.sectionTitle || '';
field._sectionId = section.id;
field._sectionType = section.sectionType;
sectionFields.push(field);
});
}
groups.push({
type: 'section',
sectionTitle: section.sectionTitle || '',
fields: sectionFields,
});
});
}
return groups;
},
// 获取服务模板
async getTemplate() {
try {
const res = await request.post("/sj/servers/getTemplate", {
first_class: this.formData.first_class_id,
});
console.log("模板接口返回数据:", res);
if (res.data && res.data.config_data) {
// 使用接口返回的config_data转换为表单字段
// config_data 可能是字符串,需要解析
const configData = typeof res.data.config_data === 'string' ?
JSON.parse(res.data.config_data) :
res.data.config_data;
console.log("解析后的config_data:", configData);
// 查找service_step类型的字段记录其key作为提交参数名
this.processFieldKey = "";
const allConfigFields = [
...(configData.presetFields || []),
...(configData.sections || []).reduce((acc, s) => acc.concat(s.fields || []), [])
];
const stepField = allConfigFields.find(f => f.fieldType === 'service_step');
if (stepField && stepField.key) {
this.processFieldKey = stepField.key;
}
const fields = this.transformConfigToFields(configData);
console.log("转换后的fields数组:", fields, "长度:", fields.length);
this.formFields = fields;
} else if (res.data && res.data.fields && res.data.fields.length > 0) {
// 兼容旧格式
this.formFields = res.data.fields;
}
} catch (e) {
console.error("获取模板失败", e);
}
// 初始化表单数据
const initialData = {};
const allFields = this.getDynamicFields();
allFields.forEach((field) => {
if (field.default_value !== undefined) {
initialData[field.key] = field.default_value;
} else if (
field.type === 'multi_select' ||
field.type === 'image_multi' ||
field.type === 'service_step' ||
(field.type === 'video' && field.maxCount > 1)
) {
initialData[field.key] = [];
} else if (!this.formData[field.key] && this.formData[field.key] !== 0) {
initialData[field.key] = '';
}
});
this.formData = {
...this.formData,
...initialData
};
},
getDynamicFields() {
const fields = [];
this.formFields.forEach((group) => {
if (group.type === 'single' && group.field) {
fields.push(group.field);
} else if (group.type === 'section' && Array.isArray(group.fields)) {
fields.push(...group.fields);
} else if (group.key) {
fields.push(group);
}
});
return fields;
},
// 根据分类ID获取分类名称
async loadClassNames() {
if (!this.formData.first_class_id) return;
try {
const firstRes = await request.post("/sj/firstclass", {});
if (firstRes.data && firstRes.data.length > 0) {
const matched = firstRes.data.find(item => item.id == this.formData.first_class_id);
if (matched) {
this.firstClassName = matched.title;
}
}
} catch (e) {
console.error("获取一级分类失败", e);
}
if (!this.formData.second_class_id) return;
try {
const secondRes = await request.post("/user/secondclass", {
id: this.formData.first_class_id,
});
if (secondRes.data && secondRes.data.length > 0) {
const matched = secondRes.data.find(item => item.id == this.formData.second_class_id);
if (matched) {
this.secondClassName = matched.title;
}
}
} catch (e) {
console.error("获取二级分类失败", e);
}
},
inpPrice2(e) {
let that = this;
let value = e.detail.value;
// 1. 移除非数字和小数点
value = value.replace(/[^\d.]/g, '');
// 2. 确保只有一个小数点
const parts = value.split('.');
if (parts.length > 2) {
value = parts[0] + '.' + parts.slice(1).join('');
}
// 3. 限制小数点后最多一位
if (parts.length > 1) {
value = parts[0] + '.' + parts[1].slice(0, 2);
}
// 4. 如果以小数点开头前面补0
if (value.startsWith('.')) {
value = '0' + value;
}
that.$set(that.formData, 'line_price', value);
},
// 服务简介部分
initDetailForm(detail = []) {
// 先重置 detailForm 为空
this.detailForm = {
effect: "",
crowd: "",
product: "",
scope: "",
tips: "",
};
this.detailOtherList = [];
// 优先从后端返回的新字段赋值
if (this.formData.efficacy) this.detailForm.effect = this.formData.efficacy;
if (this.formData.crowd) this.detailForm.crowd = this.formData.crowd;
if (this.formData.product) this.detailForm.product = this.formData.product;
if (this.formData.scope) this.detailForm.scope = this.formData.scope;
if (this.formData.prompt) this.detailForm.tips = this.formData.prompt;
// 优先从后端返回的新字段赋值
if (this.formData.efficacy) this.detailForm.effect = this.formData.efficacy;
if (this.formData.crowd) this.detailForm.crowd = this.formData.crowd;
if (this.formData.product) this.detailForm.product = this.formData.product;
if (this.formData.scope) this.detailForm.scope = this.formData.scope;
if (this.formData.prompt) this.detailForm.tips = this.formData.prompt;
// 如果新字段都为空,则尝试从旧的 detail 数组中提取(兼容旧数据)
if (!this.formData.efficacy && !this.formData.crowd && !this.formData.product) {
(detail || []).forEach((item) => {
if (item.title === "服务功效") {
this.detailForm.effect = item.text || "";
} else if (item.title === "适用人群") {
this.detailForm.crowd = item.text || "";
} else if (item.title === "产品清单") {
this.detailForm.product = item.text || "";
} else if (item.title === "适用范围" || item.title === "使用范围") {
this.detailForm.scope = item.text || "";
} else if (item.title === "温馨提示") {
this.detailForm.tips = item.text || "";
} else {
this.detailOtherList.push({
title: item.title || "",
text: item.text || "",
photo: item.photo || "",
});
}
});
}
},
syncDetailForm() {
// 双向同步如果formData有值来自dynamic-form同步到detailForm否则从detailForm同步到formData
if (this.formData.efficacy) {
this.detailForm.effect = this.formData.efficacy;
} else {
this.formData.efficacy = (this.detailForm.effect || "").trim();
}
if (this.formData.crowd) {
this.detailForm.crowd = this.formData.crowd;
} else {
this.formData.crowd = (this.detailForm.crowd || "").trim();
}
if (this.formData.product) {
this.detailForm.product = this.formData.product;
} else {
this.formData.product = (this.detailForm.product || "").trim();
}
if (this.formData.scope) {
this.detailForm.scope = this.formData.scope;
} else {
this.formData.scope = (this.detailForm.scope || "").trim();
}
if (this.formData.prompt) {
this.detailForm.tips = this.formData.prompt;
} else {
this.formData.prompt = (this.detailForm.tips || "").trim();
}
},
checkDetailForm() {
return true;
},
closeReminderPopup(notShowAgain) {
console.log('关闭弹窗,不再提示:', notShowAgain);
if (notShowAgain) {
uni.setStorageSync('addServiceReminderNotShow', true);
}
this.showReminderPopup = false;
},
goImgAndText() {
uni.navigateTo({
url: `/pages/shop/add-img-text?list=${this.formData.graphic_details}`,
});
},
ckeckisShowPer(value) {
console.log("ckeckisShowPer==========", value);
this.isShowPer = value;
},
ckecknowQer(value) {
this.nowQer = value;
},
addVideo(value) {
this.setVideoValue(value);
},
normalizeVideoValue(value) {
if (!value) return "";
if (typeof value === "string") {
const str = value.trim();
if (!str) return "";
if ((str.startsWith("{") && str.endsWith("}")) || (str.startsWith("[") && str.endsWith("]"))) {
try {
return this.normalizeVideoValue(JSON.parse(str));
} catch (error) {
return str;
}
}
return str;
}
if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
const url = this.normalizeVideoValue(value[i]);
if (url) return url;
}
return "";
}
if (typeof value === "object") {
const candidates = [value.url, value.path, value.filePath, value.tempFilePath, value.src, value.value];
for (let i = 0; i < candidates.length; i++) {
const url = this.normalizeVideoValue(candidates[i]);
if (url) return url;
}
return "";
}
return String(value);
},
setVideoValue(value) {
this.formData.video = this.normalizeVideoValue(value);
},
// addImg(arr) {
// this.formData.photo = this.formData.photo.concat(arr);
// },
// deleteImage(index) {
// this.formData.photo.splice(index, 1)
// },
onUploadSuccess(file) {
console.log("添加的图片", this.formData.photo);
},
onUploadError(error) {
console.error("上传失败:", error);
uni.showToast({
title: "上传失败",
icon: "none",
});
},
onFileDelete(file, index) {
console.log("删除文件:", this.formData.photo, index);
},
uploadVideoSuc(file) {
this.setVideoValue(file);
},
uploadVideoErr() { },
uploadVideoDel() {
this.formData.video = null;
},
async getInit() {
await request
.post("/sj/servers/detail", {
id: this.formData.id
})
.then(async (res) => {
// 直接合并所有字段,避免遗漏
this.formData = {
...this.formData,
...res.data
};
this.setVideoValue(this.formData.video);
if (this.formData.first_class_id && this.formFields.length === 0) {
await this.getTemplate();
}
// 确保 process 保持为数组(后端可能返回字符串)
if (!Array.isArray(this.formData.process)) {
this.formData.process = [];
}
// 确保 detail 数组被保留(可能用于兼容)
this.formData.detail = res.data.detail || [];
// 确保photo为纯字符串数组去除对象索引
if (this.formData.photo && !Array.isArray(this.formData.photo)) {
this.formData.photo = Object.values(this.formData.photo);
}
if (Array.isArray(this.formData.photo)) {
this.formData.photo = this.formData.photo.map(function (item) {
return typeof item === 'string' ? item : (item && item.url ? item.url :
String(item));
});
}
// 解析intro字段的JSON数据用于回显自定义字段
if (res.data.intro) {
try {
const introArr = typeof res.data.intro === 'string' ?
JSON.parse(res.data.intro) :
res.data.intro;
if (Array.isArray(introArr)) {
// 遍历所有表单字段,构建 id -> field 的映射
const idToFieldMap = {};
this.formFields.forEach(function (group) {
const fields = group.field ? [group.field] : (group.fields || []);
fields.forEach(function (f) {
if (f._original && f._original.id) {
idToFieldMap[f._original.id] = f;
}
});
});
// 用intro中的id去匹配表单字段将值回填到formData
introArr.forEach(function (item) {
const matchedField = idToFieldMap[item.id];
if (matchedField && item.value !== undefined) {
this.$set(this.formData, matchedField.key, item.value);
}
}.bind(this));
}
} catch (e) {
console.error('解析intro字段失败:', e);
}
}
// 解析服务步骤数据回显
if (this.processFieldKey && res.data[this.processFieldKey]) {
try {
const processRaw = res.data[this.processFieldKey];
const processArr = typeof processRaw === 'string' ?
JSON.parse(processRaw) : processRaw;
if (Array.isArray(processArr)) {
this.formData.process = processArr.map(item => ({
title: item.title || '',
text: item.text || '',
photo: item.photo || '',
}));
}
} catch (e) {
console.error('解析服务步骤数据失败:', e);
}
} else if (res.data.intro) {
// 无独立key时从intro数组中查找service_step
try {
const introArr = typeof res.data.intro === 'string' ?
JSON.parse(res.data.intro) : res.data.intro;
if (Array.isArray(introArr)) {
const stepItem = introArr.find(item => item.id === 'service_step');
if (stepItem && Array.isArray(stepItem.value)) {
this.formData.process = stepItem.value.map(item => ({
title: item.title || '',
text: item.text || '',
photo: item.photo || '',
}));
}
}
} catch (e) {
console.error('从intro解析服务步骤失败:', e);
}
}
// 调用初始化方法,它会优先使用新字段
this.initDetailForm(res.data.detail || []);
});
},
getUserInfo() {
return request
.post("/sj/user/getuser", {
type: 2,
})
.then((result) => {
console.log('getUserInfo返回:', result);
const userId = result.data.id || result.data.user_id || result.data.userId;
console.log('12121212');
if (userId) {
this.formData.publish_user_id = userId;
this.publish_user_id = userId;
uni.setStorageSync('userId', userId);
} else {
// 接口没有返回id从storage获取
this.formData.publish_user_id = uni.getStorageSync('userId') || '';
}
console.log('publish_user_id:', this.formData.publish_user_id);
this.postid = result.data.id
})
.catch((err) => {
console.error('getUserInfo失败:', err);
// 接口失败从storage获取
this.formData.publish_user_id = uni.getStorageSync('userId') || '';
});
},
// 是否在商家端售卖
changeSale(value) {
this.formData.sj_see = value;
},
// 输入价格
inpPrice(e) {
let that = this;
let value = e.detail.value;
// 1. 移除非数字和小数点
value = value.replace(/[^\d.]/g, "");
// 2. 确保只有一个小数点
const parts = value.split(".");
if (parts.length > 2) {
value = parts[0] + "." + parts.slice(1).join("");
}
// 3. 限制小数点后最多一位
if (parts.length > 1) {
value = parts[0] + "." + parts[1].slice(0, 2);
}
// 4. 如果以小数点开头前面补0
if (value.startsWith(".")) {
value = "0" + value;
}
that.$set(that.formData, "server_price", value);
},
deleteStep(i) {
this.formData.process.splice(i, 1);
},
addStep() {
let i = this.formData.process.length + 1;
let arr = {
title: "第" + i + "步",
text: "",
photo: "",
};
this.formData.process.push(arr);
},
// 视频上传相关方法
uploadVideoSuc(file) {
this.setVideoValue(file);
},
uploadVideoErr() { },
uploadVideoDel() {
this.formData.video = '';
},
ckeckisShowPer(val) {
this.isShowPer = val;
},
ckecknowQer(val) {
this.nowQer = val;
},
// 删除视频
deleteVideo() {
this.formData.video = "";
},
// 删除视频
deleteVideo() {
this.formData.video = "";
},
// 保存草稿
saveDraft: debounce(function () {
if (this.isDraft) return;
this.syncDetailForm();
const {
title,
server_price,
line_price,
server_time,
first_class_id,
second_class_id,
detail,
process,
video,
photo,
} = this.formData;
let item = {
title,
server_price,
line_price,
server_time,
first_class_id,
second_class_id,
detail,
process,
video,
photo,
};
// 检查是否所有字段都为空
const isEmpty = Object.values(item).every((value) => {
if (Array.isArray(value)) {
return value.length === 0;
}
return !value;
});
if (isEmpty) {
uni.showToast({
title: "请至少填写一项内容",
icon: "none",
});
return;
}
// 实现保存草稿逻辑
this.formData.state = 0;
const submitData = this.buildSubmitData();
submitData.state = 0;
let url = null;
if (!this.formData.id) {
url = "/user/serveradd";
} else {
url = "/user/serverchange";
}
request.post(url, submitData).then((res) => {
if (res.state == 1) {
this.isDraft = true;
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2]; // 上一个页面
uni.showToast({
title: res.msg,
icon: "success",
duration: 1000,
});
setTimeout(() => {
uni.navigateBack({
delta: 1,
success: () => {
prevPage.$vm.currentTab = 3;
prevPage.$vm.state = 0;
prevPage.$vm.getServicesList(); // 直接调用上个页面的刷新方法
},
});
}, 500);
} else {
uni.showToast({
title: res.msg,
icon: "none",
});
this.isDraft = false;
}
});
}, 500),
// 验证动态表单字段
validateDynamicForm() {
// 遍历 formGroups分组结构按顺序验证必填项
for (let i = 0; i < this.formFields.length; i++) {
const group = this.formFields[i];
const fieldsToCheck = [];
if (group.type === 'single' && group.field) {
fieldsToCheck.push(group.field);
} else if (group.type === 'section' && group.fields) {
fieldsToCheck.push(...group.fields);
}
for (let j = 0; j < fieldsToCheck.length; j++) {
const field = fieldsToCheck[j];
if (!field.is_required) continue;
const value = this.formData[field.key];
const isEmpty = value === undefined || value === null || value === '' ||
(Array.isArray(value) && value.length === 0);
if (isEmpty) {
// 根据字段类型显示不同的提示语
const prefix = (field.type === 'image_multi' || field.type === 'video') ? '请上传' :
(field.type === 'select' || field.type === 'single_select' || field.type === 'multi_select') ?
'请选择' : '请输入';
uni.showToast({
title: `${prefix}${field.label}`,
icon: "none",
});
return false;
}
if (field.type === 'service_step' && Array.isArray(value)) {
const hasEmptyStep = value.some((item) => !item || !item.text || !item.text.trim());
if (hasEmptyStep) {
uni.showToast({
title: "请完善服务流程内容",
icon: "none",
});
return false;
}
}
// 服务时长特殊验证
if (field.key === 'server_time') {
if (value < 10) {
uni.showToast({
title: "服务时长最短为10分钟",
icon: "none",
});
return false;
}
if (value > 240) {
uni.showToast({
title: "服务时长最长为240分钟",
icon: "none",
});
return false;
}
}
}
}
return true;
},
// 构建提交数据有key的字段直接作为参数没有key的字段放入intro数组
buildSubmitData() {
const submitData = {};
const introArr = [];
console.log(this.formData, '=-=-=-=-=-=');
// 添加固定字段
if (this.formData.publish_user_id) {
if (this.formData.id) {
submitData.id = this.formData.id;
}
submitData.publish_user_id = this.formData.publish_user_id || uni.getStorageSync('userId') || '';
submitData.first_class_id = this.formData.first_class_id || '';
submitData.second_class_id = this.formData.second_class_id || '';
submitData.server_kind = this.formData.server_kind || getApp().globalData.artisanType;
}
// 视频字段(独立上传组件)
const videoUrl = this.normalizeVideoValue(this.formData.video);
if (videoUrl) {
submitData.video = videoUrl;
}
// 遍历分组,按顺序处理字段
for (let i = 0; i < this.formFields.length; i++) {
const group = this.formFields[i];
let fieldsToProcess = [];
if (group.type === 'single' && group.field) {
fieldsToProcess.push(group.field);
} else if (group.type === 'section' && group.fields) {
fieldsToProcess = group.fields;
}
for (let j = 0; j < fieldsToProcess.length; j++) {
const field = fieldsToProcess[j];
const value = this.formData[field.key];
if (value === undefined || value === null || value === '') continue;
if (Array.isArray(value) && value.length === 0) continue;
if (field.type === 'service_step' && Array.isArray(value)) {
const processArr = value
.filter(item => item && item.text && item.text.trim())
.map(item => ({ text: item.text.trim() }));
if (processArr.length === 0) continue;
if (field._hasOriginalKey) {
submitData[field.key] = JSON.stringify(processArr);
} else {
introArr.push({
id: field._original ? field._original.id : field.key,
title: field.label,
type: field._fieldType || field.type,
value: processArr,
sectionId: field._sectionId || (field._original && field._original.sectionId),
sectionTitle: field._sectionTitle || '',
sectionType: field._sectionType || (field._original && field._original.sectionType),
});
}
continue;
}
if (field._hasOriginalKey) {
// 有key的字段直接作为请求参数
// 图片字段确保为纯URL字符串数组
if (field.type === 'image_multi' && Array.isArray(value)) {
submitData[field.key] = value.map(function (item) {
return typeof item === 'string' ? item : (item && item.url ? item.url : item);
});
} else {
submitData[field.key] = value;
}
} else {
// 没有key的字段放入intro数组
introArr.push({
id: field._original ? field._original.id : field.key,
title: field.label,
type: field._fieldType || field.type,
value: value,
sectionId: field._sectionId || (field._original && field._original.sectionId),
sectionTitle: field._sectionTitle || '',
sectionType: field._sectionType || (field._original && field._original.sectionType),
});
}
}
}
if (introArr.length > 0) {
submitData.intro = JSON.stringify(introArr);
}
// 服务步骤有key时作为独立参数无key时放入intro数组
if (!this.hasDynamicServiceStepField && this.formData.process && this.formData.process.length > 0) {
const processArr = this.formData.process
.filter(item => item.text && item.text.trim())
.map(item => ({ text: item.text.trim() }));
if (processArr.length > 0) {
if (this.processFieldKey) {
submitData[this.processFieldKey] = JSON.stringify(processArr);
} else {
let introList = [];
try {
introList = submitData.intro ? JSON.parse(submitData.intro) : [];
} catch (e) {
introList = [];
}
introList.push({
id: 'service_step',
title: '服务流程',
type: 'service_step',
value: processArr,
});
submitData.intro = JSON.stringify(introList);
}
}
}
return submitData;
},
// 提交表单
submitForm: debounce(function () {
if (this.isAdd) return;
// 先同步服务简介数据到formData
this.syncDetailForm();
if (!this.formData.first_class_id) {
uni.showToast({
title: "请选择服务分类",
icon: "none",
});
return;
}
// 验证动态表单字段
if (!this.validateDynamicForm()) {
return;
}
if (this.artisanType == 2) {
delete this.formData.sj_see;
}
// 提交表单逻辑
delete this.formData.state;
let url = null;
if (!this.formData.id) {
url = "/user/serveradd";
} else {
url = "/user/serverupdate";
}
console.log(this.formData, '-0-0-0-0-0-');
const submitData = this.buildSubmitData();
submitData.publish_user_id = this.formData.publish_user_id;
submitData.second_class_id = this.formData.second_class_id;
submitData.photo = Object.values(this.formData.photo || {});
console.log(submitData, 'submitData');
submitData.publish_user_id = this.postid
submitData.server_kind = 2
submitData.first_class_id = this.formData.first_class_id
request.post(url, submitData).then((res) => {
if (res.state == 1) {
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2]; // 上一个页面
uni.showToast({
title: res.msg,
icon: "success",
duration: 600,
mask: true,
});
this.isAdd = true;
setTimeout(() => {
uni.navigateBack({
delta: 1,
success: () => {
prevPage.$vm.currentTab = 1;
prevPage.$vm.state = 1;
prevPage.$vm.getServicesList(); // 直接调用上个页面的刷新方法
},
});
}, 500);
} else {
uni.showToast({
title: res.msg,
icon: "none",
});
this.isAdd = false;
}
});
}, 500),
},
};
</script>
<style lang="less">
.add-service {
padding: 24rpx 24rpx 0;
box-sizing: border-box;
}
.add-service {
padding: 24rpx 24rpx 0;
box-sizing: border-box;
}
.form-container {
margin-top: 20rpx;
}
.form-container {
margin-top: 20rpx;
}
.form-item {
background-color: #fff;
padding: 24rpx;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-radius: 10rpx;
margin-bottom: 24rpx;
}
.form-item {
background-color: #fff;
padding: 24rpx;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-radius: 10rpx;
margin-bottom: 24rpx;
}
.price-tip {
width: 100%;
margin-top: 40rpx;
.price-tip {
width: 100%;
margin-top: 40rpx;
.price-tip-card {
padding: 8rpx 12rpx;
background: #FDF0F0;
border-radius: 8rpx;
font-weight: 400;
font-size: 24rpx;
color: #EE4853;
line-height: 33rpx;
}
}
.price-tip-card {
padding: 8rpx 12rpx;
background: #FDF0F0;
border-radius: 8rpx;
font-weight: 400;
font-size: 24rpx;
color: #EE4853;
line-height: 33rpx;
}
}
.shopsale-box {
flex-flow: column;
justify-content: space-between;
align-items: space-between;
}
.shopsale-box {
flex-flow: column;
justify-content: space-between;
align-items: space-between;
}
.shopsale-change {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
margin-top: 24rpx;
}
.shopsale-change {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
margin-top: 24rpx;
}
.shopsale-option {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
}
.shopsale-option {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
}
.shopsale-option:last-child {
margin-left: 220rpx;
}
.shopsale-option:last-child {
margin-left: 220rpx;
}
.option-text {
padding-left: 16rpx;
}
.option-text {
padding-left: 16rpx;
}
.form-item-up {
background-color: #fff;
padding: 24rpx;
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: flex-start;
box-sizing: border-box;
border-radius: 10rpx;
margin-bottom: 24rpx;
}
.form-item-up {
background-color: #fff;
padding: 24rpx;
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
align-items: flex-start;
box-sizing: border-box;
border-radius: 10rpx;
margin-bottom: 24rpx;
}
.form-label {
font-size: 28rpx;
color: #333333;
}
.form-label {
font-size: 28rpx;
color: #333333;
}
.form-input {
flex: 1;
height: 40rpx;
font-size: 28rpx;
color: #333333;
align-items: center;
text-align: center;
}
.form-input {
flex: 1;
height: 40rpx;
font-size: 28rpx;
color: #333333;
align-items: center;
text-align: center;
}
.form-right {
display: flex;
justify-content: space-between;
align-items: center;
}
.form-right {
display: flex;
justify-content: space-between;
align-items: center;
}
.form-value {
font-size: 28rpx;
color: #333333;
margin-right: 16rpx;
}
.service-class-item {
justify-content: flex-start;
align-items: flex-start;
}
.service-class-value {
flex: 1;
margin-right: 0;
line-height: 40rpx;
word-break: break-all;
}
.placeholder {
font-weight: 400;
font-size: 28rpx;
color: #999999;
}
.placeholder {
font-weight: 400;
font-size: 28rpx;
color: #999999;
}
.textarea-item {
padding-bottom: 30rpx;
}
.textarea-item {
padding-bottom: 30rpx;
}
.form-textarea {
flex: 1;
height: 198rpx;
font-size: 28rpx;
color: #333333;
line-height: 1.5;
margin-left: 32rpx;
}
.form-textarea {
flex: 1;
height: 198rpx;
font-size: 28rpx;
color: #333333;
line-height: 1.5;
margin-left: 32rpx;
}
.upload-item {
padding-bottom: 30rpx;
}
.upload-item {
padding-bottom: 30rpx;
}
.upload-tip {
font-size: 24rpx;
color: #999999;
margin-left: 10rpx;
}
.upload-tip {
font-size: 24rpx;
color: #999999;
margin-left: 10rpx;
}
.upload-content {
margin-top: 20rpx;
position: relative;
}
.upload-content {
margin-top: 20rpx;
position: relative;
}
.progress-box {
width: 204rpx;
height: 204rpx;
background-color: rgba(0, 0, 0, 0.5);
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 99;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
.progress-box {
width: 204rpx;
height: 204rpx;
background-color: rgba(0, 0, 0, 0.5);
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 99;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
.progress-text {
font-size: 42rpx;
color: #ffffff;
font-weight: 500;
}
.progress-text {
font-size: 42rpx;
color: #ffffff;
font-weight: 500;
}
.progress-lable {
font-size: 28rpx;
color: #ffffff;
}
.progress-lable {
font-size: 28rpx;
color: #ffffff;
}
.progress-box progress {
/* width: 204rpx; */
position: absolute;
left: 0;
right: 0;
bottom: 0;
}
.progress-box progress {
/* width: 204rpx; */
position: absolute;
left: 0;
right: 0;
bottom: 0;
}
.video-preview,
.image-preview,
.upload-btn {
width: 200rpx;
height: 200rpx;
margin-right: 10rpx;
margin-bottom: 20rpx;
position: relative;
}
.video-preview,
.image-preview,
.upload-btn {
width: 200rpx;
height: 200rpx;
margin-right: 10rpx;
margin-bottom: 20rpx;
position: relative;
}
.preview-video,
.preview-image {
width: 200rpx;
height: 200rpx;
border-radius: 8rpx;
}
.preview-video,
.preview-image {
width: 200rpx;
height: 200rpx;
border-radius: 8rpx;
}
.upload-btn {
border: 2rpx dashed #dddddd;
border-radius: 8rpx;
display: flex;
justify-content: center;
align-items: center;
}
.upload-btn {
border: 2rpx dashed #dddddd;
border-radius: 8rpx;
display: flex;
justify-content: center;
align-items: center;
}
.plus-icon {
font-size: 60rpx;
color: #999999;
}
.plus-icon {
font-size: 60rpx;
color: #999999;
}
.delete-btn {
position: absolute;
top: -20rpx;
right: -20rpx;
width: 40rpx;
height: 40rpx;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
}
.delete-btn {
position: absolute;
top: -20rpx;
right: -20rpx;
width: 40rpx;
height: 40rpx;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
}
.bottom-buttons {
/* position: fixed;
.bottom-buttons {
/* position: fixed;
left: 0;
right: 0;
bottom: 0; */
height: 100rpx;
padding: 40rpx 0 64rpx;
box-sizing: border-box;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
}
.btn-draft,
.btn-submit {
width: 334rpx;
height: 76rpx;
line-height: 76rpx;
text-align: center;
font-size: 28rpx;
border-radius: 40rpx;
margin: 0 24rpx;
}
.btn-draft,
.btn-submit {
width: 334rpx;
height: 76rpx;
line-height: 76rpx;
text-align: center;
font-size: 28rpx;
border-radius: 40rpx;
margin: 0 24rpx;
}
.btn-draft {
background-color: #ffffff;
color: #e8101e;
border: 2rpx solid #e8101e;
box-sizing: border-box;
}
.btn-submit {
background-color: #e8101e;
color: #ffffff;
width: 705rpx;
height: 76rpx;
}
.form-step {
background-color: #fff;
margin-bottom: 24rpx;
}
.form-step {
background-color: #fff;
margin-bottom: 24rpx;
}
.form-step .form-item {
margin-bottom: 0;
}
.form-step .form-item {
margin-bottom: 0;
}
.step {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
padding: 0 24rpx 24rpx;
}
.step {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
padding: 0 24rpx 24rpx;
}
.step-inp {
flex: 1;
font-size: 28rpx;
color: #333333;
margin-left: 38rpx;
padding: 0 24rpx;
background-color: rgba(230, 230, 230, 0.5);
}
.step-inp {
flex: 1;
font-size: 28rpx;
color: #333333;
margin-left: 38rpx;
padding: 0 24rpx;
background-color: rgba(230, 230, 230, 0.5);
}
.step-textarea {
font-size: 24rpx;
flex: 1;
height: 70rpx;
border-radius: 6rpx;
margin-left: 38rpx;
padding: 24rpx;
background-color: rgba(230, 230, 230, 0.5);
}
.step-textarea {
font-size: 24rpx;
flex: 1;
height: 70rpx;
border-radius: 6rpx;
margin-left: 38rpx;
padding: 24rpx;
background-color: rgba(230, 230, 230, 0.5);
}
/* 选择器触发按钮样式 */
.picker-trigger {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx;
background-color: #ffffff;
border-radius: 12rpx;
margin-bottom: 24rpx;
}
/* 选择器触发按钮样式 */
.picker-trigger {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx;
background-color: #ffffff;
border-radius: 12rpx;
margin-bottom: 24rpx;
}
.picker-label {
font-size: 28rpx;
color: #333333;
}
.picker-label {
font-size: 28rpx;
color: #333333;
}
.picker-value {
font-size: 28rpx;
color: #666666;
}
.picker-value {
font-size: 28rpx;
color: #666666;
}
.picker-arrow {
width: 32rpx;
height: 32rpx;
margin-left: 16rpx;
}
.picker-arrow {
width: 32rpx;
height: 32rpx;
margin-left: 16rpx;
}
.delete-icon {
width: 32rpx;
height: 32rpx;
margin-left: 24rpx;
}
.delete-icon {
width: 32rpx;
height: 32rpx;
margin-left: 24rpx;
}
.form-detail {
position: relative;
}
.form-detail {
position: relative;
}
.required::before {
content: "*";
color: #ff0000;
margin-right: 4rpx;
}
.required::before {
content: "*";
color: #ff0000;
margin-right: 4rpx;
}
.step-inp,
.form-input {
height: 60rpx;
}
.step-inp,
.form-input {
height: 60rpx;
}
// 服务简介相关
.detail-card {
background: #ffffff;
border-radius: 20rpx;
padding: 0 24rpx 8rpx;
margin-bottom: 24rpx;
box-sizing: border-box;
overflow: hidden;
}
// 服务简介相关
.detail-card {
background: #ffffff;
border-radius: 20rpx;
padding: 0 24rpx 8rpx;
margin-bottom: 24rpx;
box-sizing: border-box;
overflow: hidden;
}
.detail-title {
padding: 24rpx 0 25rpx;
}
.detail-title {
padding: 24rpx 0 25rpx;
}
.detail-title .form-label {
font-size: 30rpx;
font-weight: 500;
color: #333;
line-height: 40rpx;
}
.detail-title .form-label {
font-size: 30rpx;
font-weight: 500;
color: #333;
line-height: 40rpx;
}
.detail-row {
padding: 0 0 36rpx;
}
.detail-row {
padding: 0 0 36rpx;
}
.detail-row .form-label {
display: block;
margin-bottom: 20rpx;
line-height: 40rpx;
}
.detail-row .form-label {
display: block;
margin-bottom: 20rpx;
line-height: 40rpx;
}
.detail-textarea-wrap {
position: relative;
background: #f7f7f7;
border-radius: 16rpx;
padding: 24rpx 24rpx 52rpx;
box-sizing: border-box;
}
.detail-textarea-wrap {
position: relative;
background: #f7f7f7;
border-radius: 16rpx;
padding: 24rpx 24rpx 52rpx;
box-sizing: border-box;
}
.detail-textarea {
width: 100%;
height: 108rpx;
min-height: 108rpx;
margin: 0;
padding: 0;
background: transparent;
border: 0;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
box-sizing: border-box;
}
.detail-textarea {
width: 100%;
height: 108rpx;
min-height: 108rpx;
margin: 0;
padding: 0;
background: transparent;
border: 0;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
box-sizing: border-box;
}
.detail-count {
position: absolute;
right: 24rpx;
bottom: 16rpx;
font-size: 22rpx;
color: #999999;
line-height: 32rpx;
}
.detail-count {
position: absolute;
right: 24rpx;
bottom: 16rpx;
font-size: 22rpx;
color: #999999;
line-height: 32rpx;
}
/* 平台特定样式 */
/* #ifdef H5 */
.form-input,
.form-textarea {
outline: none;
}
.upload-btn {
cursor: pointer;
}
/* #endif */
/* #ifdef APP-PLUS */
.form-input {
height: 90rpx;
}
.permission.transform {
top: calc(var(--status-bar-height) + 88rpx + 30rpx);
opacity: 1;
visibility: visible;
}
/* #endif */
/* #ifdef MP-WEIXIN */
.form-input {
height: 80rpx;
}
.bottom-buttons {
padding-bottom: env(safe-area-inset-bottom);
}
/* #endif */
.tip {
padding: 20rpx 30rpx;
background: #feefec;
font-weight: 400;
font-size: 30rpx;
color: #f31d2f;
line-height: 42rpx;
text-align: center;
font-style: normal;
.tip-icon {
width: 34rpx;
height: 34rpx;
margin-right: 10rpx;
transform: translateY(6rpx);
}
}
/* 淡入淡出动画 */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
/* 淡入淡出动画 */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.popup-mask2 {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
// z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
.popup-mask2 {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
// z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
.popup-content2 {
width: 600rpx;
background-color: #ffffff;
border-radius: 20rpx;
overflow: hidden;
padding: 40rpx 30rpx;
box-sizing: border-box;
}
.popup-content2 {
width: 600rpx;
background-color: #ffffff;
border-radius: 20rpx;
overflow: hidden;
padding: 40rpx 30rpx;
box-sizing: border-box;
}
.popup-title {
font-size: 36rpx;
font-weight: 600;
color: #333333;
text-align: center;
margin-bottom: 20rpx;
}
.popup-title {
font-size: 36rpx;
font-weight: 600;
color: #333333;
text-align: center;
margin-bottom: 20rpx;
}
.popup-message {
font-size: 30rpx;
color: #666666;
text-align: center;
margin-top: 40rpx;
margin-bottom: 30rpx;
line-height: 1.5;
}
.popup-message {
font-size: 30rpx;
color: #666666;
text-align: center;
margin-top: 40rpx;
margin-bottom: 30rpx;
line-height: 1.5;
}
.popup-buttons {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
padding: 20rpx 0 0 0;
gap: 60rpx;
}
.popup-buttons {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
padding: 20rpx 0 0 0;
gap: 60rpx;
}
.popup-btn {
flex: 1;
height: 80rpx;
line-height: 80rpx;
text-align: center;
font-size: 26rpx;
border-radius: 40rpx;
}
.popup-btn {
flex: 1;
height: 80rpx;
line-height: 80rpx;
text-align: center;
font-size: 26rpx;
border-radius: 40rpx;
}
.popup-btn-know {
background-color: #e8101e;
color: #ffffff;
}
.popup-btn-notshow {
background-color: #ffffff;
color: #e8101e;
border: 1rpx #e8101e solid;
}
.video-upload {
background-color: #fff;
padding: 24rpx;
margin-bottom: 24rpx;
}
.flex-c {
display: flex;
align-items: center;
}
.flex {
display: flex;
}
</style>