This commit is contained in:
cjl520cy 2026-04-03 15:49:27 +08:00
parent 8066f80b0c
commit 32dd0a94d2
7 changed files with 1432 additions and 1396 deletions

View File

@ -39,6 +39,7 @@
<view class="service-price">
<text v-if="dataItem.team_buy_id">{{`团购价: `}}</text>¥<text
style="font-size: 34rpx;">{{ dataItem.order_money }}</text>
<text class="service-price-line">{{ dataItem.line_money }}</text>
</view>
</view>
@ -258,6 +259,15 @@
line-height: 34rpx;
text-align: left;
font-style: normal;
.service-price-line {
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
margin-left: 10rpx;
text-decoration: line-through;
}
}
.service-type {

View File

@ -2,7 +2,9 @@
<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>
<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>
@ -12,48 +14,44 @@
<!-- 服务名称 -->
<view class="form-item">
<text class="form-label required">服务名称</text>
<input
type="text"
v-model="formData.title"
placeholder="请输入服务名称"
placeholder-class="placeholder"
class="form-input"
/>
<input type="text" v-model="formData.title" placeholder="请输入服务名称" placeholder-class="placeholder"
class="form-input" />
</view>
<!-- 服务价格 -->
<view class="form-item">
<text class="form-label required">服务价格</text>
<input
type="digit"
v-model.number="formData.server_price"
placeholder="请输入服务价格,最多两位小数"
placeholder-class="placeholder"
class="form-input"
@input="inpPrice"
@blur="inpPrice"
@confirm="inpPrice"
step="0.01"
/>
<view class="form-item" style="flex-wrap: wrap;">
<text class="form-label required">服务定价</text>
<input type="digit" v-model.number="formData.line_price" placeholder="请输入定价,最多两位小数"
placeholder-class="placeholder" class="form-input" @input="inpPrice2" @blur="inpPrice2"
@confirm="inpPrice2" step="0.01" />
<view class="price-tip">
<text class="price-tip-card">服务的基础定价未参与任何优惠的价格</text>
</view>
</view>
<!-- 服务价格 -->
<view class="form-item" style="flex-wrap: wrap;">
<text class="form-label required">服务售价</text>
<input type="digit" v-model.number="formData.server_price" placeholder="请输入售价,最多两位小数"
placeholder-class="placeholder" class="form-input" @input="inpPrice" @blur="inpPrice"
@confirm="inpPrice" step="0.01" />
<view class="price-tip">
<text class="price-tip-card">服务参与单品优惠后的价格</text>
</view>
</view>
<!-- 服务分类 -->
<view class="form-item">
<text class="form-label required">服务分类</text>
<view class="form-right" @click="openServiceTypePicker">
<text
:class="[
<text :class="[
'form-value',
formData.first_class_id ? '' : 'placeholder',
]"
>
]">
{{ serviceType || "选择分类" }}
</text>
<image
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/wxstaic/images/arrow_right.png"
class="arrow-right"
mode="aspectFit"
></image>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/wxstaic/images/arrow_right.png"
class="arrow-right" mode="aspectFit"></image>
</view>
</view>
@ -61,19 +59,14 @@
<view class="form-item" v-if="showCategory">
<text class="form-label required">服务子类</text>
<view class="form-right" @click="openCategoryPicker">
<text
:class="[
<text :class="[
'form-value',
formData.second_class_id ? '' : 'placeholder',
]"
>
]">
{{ category || "选择子类" }}
</text>
<image
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/wxstaic/images/arrow_right.png"
class="arrow-right"
mode="aspectFit"
></image>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/wxstaic/images/arrow_right.png"
class="arrow-right" mode="aspectFit"></image>
</view>
</view>
@ -106,13 +99,8 @@
<!-- 服务时间 -->
<view class="form-item">
<text class="form-label required">服务时长</text>
<input
type="number"
v-model="formData.server_time"
placeholder="请输入服务时间"
placeholder-class="placeholder"
class="form-input"
/>
<input type="number" v-model="formData.server_time" placeholder="请输入服务时间"
placeholder-class="placeholder" class="form-input" />
<text class="pr-240">分钟</text>
</view>
@ -148,13 +136,8 @@
<view class="detail-row">
<text class="form-label required">服务功效</text>
<view class="detail-textarea-wrap">
<textarea
class="detail-textarea"
v-model="detailForm.effect"
placeholder="请输入服务功效"
placeholder-class="placeholder"
maxlength="200"
></textarea>
<textarea class="detail-textarea" v-model="detailForm.effect" placeholder="请输入服务功效"
placeholder-class="placeholder" maxlength="200"></textarea>
<text class="detail-count">{{(detailForm.effect || '').length}}/200</text>
</view>
</view>
@ -162,13 +145,9 @@
<view class="detail-row">
<text class="form-label required">适用人群</text>
<view class="detail-textarea-wrap">
<textarea
class="detail-textarea"
v-model="detailForm.crowd"
placeholder="请输入不适用人群,例如:未成年人/孕妇不适用"
placeholder-class="placeholder"
maxlength="200"
></textarea>
<textarea class="detail-textarea" v-model="detailForm.crowd"
placeholder="请输入不适用人群,例如:未成年人/孕妇不适用" placeholder-class="placeholder"
maxlength="200"></textarea>
<text class="detail-count">{{(detailForm.crowd || '').length}}/200</text>
</view>
</view>
@ -176,13 +155,8 @@
<view class="detail-row">
<text class="form-label">产品清单</text>
<view class="detail-textarea-wrap">
<textarea
class="detail-textarea"
v-model="detailForm.product"
placeholder="请输入产品清单"
placeholder-class="placeholder"
maxlength="200"
></textarea>
<textarea class="detail-textarea" v-model="detailForm.product" placeholder="请输入产品清单"
placeholder-class="placeholder" maxlength="200"></textarea>
<text class="detail-count">{{(detailForm.product || '').length}}/200</text>
</view>
</view>
@ -190,13 +164,8 @@
<view class="detail-row">
<text class="form-label">适用范围</text>
<view class="detail-textarea-wrap">
<textarea
class="detail-textarea"
v-model="detailForm.scope"
placeholder="请输入使用时间/适用人数"
placeholder-class="placeholder"
maxlength="200"
></textarea>
<textarea class="detail-textarea" v-model="detailForm.scope" placeholder="请输入使用时间/适用人数"
placeholder-class="placeholder" maxlength="200"></textarea>
<text class="detail-count">{{(detailForm.scope || '').length}}/200</text>
</view>
</view>
@ -204,13 +173,8 @@
<view class="detail-row">
<text class="form-label">温馨提示</text>
<view class="detail-textarea-wrap">
<textarea
class="detail-textarea"
v-model="detailForm.tips"
placeholder="请输入其他注意事项"
placeholder-class="placeholder"
maxlength="200"
></textarea>
<textarea class="detail-textarea" v-model="detailForm.tips" placeholder="请输入其他注意事项"
placeholder-class="placeholder" maxlength="200"></textarea>
<text class="detail-count">{{(detailForm.tips || '').length}}/200</text>
</view>
</view>
@ -222,17 +186,9 @@
</view>
<view class="step" v-for="(item, i) in formData.process">
<text class="form-label">{{ i + 1 }}</text>
<input
type="text"
class="step-inp"
v-model="formData.process[i].text"
/>
<image
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/wxstaic/images/delete_icon.png"
class="delete-icon"
mode="aspectFit"
@click="deleteStep(i)"
></image>
<input type="text" class="step-inp" v-model="formData.process[i].text" />
<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>
@ -265,22 +221,10 @@
@addVideo="addVideo"
@deleteVideo="deleteVideo"
:video="formData.video"></upload-video> -->
<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="上传视频"
@success="uploadVideoSuc"
@error="uploadVideoErr"
@delete="uploadVideoDel"
@ckeckisShowPer="ckeckisShowPer"
@ckecknowQer="ckecknowQer"
>
<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="上传视频" @success="uploadVideoSuc" @error="uploadVideoErr"
@delete="uploadVideoDel" @ckeckisShowPer="ckeckisShowPer" @ckecknowQer="ckecknowQer">
</ali-oss-uploader>
</view>
@ -296,21 +240,10 @@
:width="'654rpx'"
@addImg="addImg"
@deleteImage="deleteImage"></upload-img> -->
<ali-oss-uploader
v-model="formData.photo"
:max-count="9"
:max-size="5"
:width="'654rpx'"
:type="artisanType + 1"
:user-id="formData.publish_user_id"
button-text="上传图片"
tips="最多上传3张图片每张不超过5MB"
@success="onUploadSuccess"
@error="onUploadError"
@delete="onFileDelete"
@ckeckisShowPer="ckeckisShowPer"
@ckecknowQer="ckecknowQer"
>
<ali-oss-uploader v-model="formData.photo" :max-count="9" :max-size="5" :width="'654rpx'"
:type="artisanType + 1" :user-id="formData.publish_user_id" button-text="上传图片"
tips="最多上传3张图片每张不超过5MB" @success="onUploadSuccess" @error="onUploadError" @delete="onFileDelete"
@ckeckisShowPer="ckeckisShowPer" @ckecknowQer="ckecknowQer">
</ali-oss-uploader>
</view>
</view>
@ -324,44 +257,23 @@
</view>
<!-- 服务类型选择器 -->
<popup-picker
:show="showServiceTypePicker"
title="选择服务类型"
:columns="[serviceTypes]"
:value="[selectedServiceTypeIndex]"
@close="showServiceTypePicker = false"
@confirm="handleServiceTypeConfirm"
/>
<popup-picker :show="showServiceTypePicker" title="选择服务类型" :columns="[serviceTypes]"
:value="[selectedServiceTypeIndex]" @close="showServiceTypePicker = false"
@confirm="handleServiceTypeConfirm" />
<!-- 服务分类选择器 -->
<PopupPickerMy
:show="showCategoryPicker"
title="选择服务分类"
:columns="[categoryAll]"
:value="selectedCategoryIndex"
@close="showCategoryPicker = false"
@confirm="handleCategoryConfirm"
/>
<PopupPickerMy :show="showCategoryPicker" title="选择服务分类" :columns="[categoryAll]" :value="selectedCategoryIndex"
@close="showCategoryPicker = false" @confirm="handleCategoryConfirm" />
<view class="mask" v-if="isShow" @click="isShow = false"></view>
<!-- 获取权限提示匡内容 -->
<view
class="permission"
:class="{ transform: isShowPer && nowQer === 'xc' }"
>
<view class="permission" :class="{ transform: isShowPer && nowQer === 'xc' }">
<view class="per-tit">美融融plus 对储存空间/照片权限申请说明</view>
<view class="per-cont"
>便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中读取相册和文件内容</view
>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中读取相册和文件内容</view>
</view>
<view
class="permission"
:class="{ transform: isShowPer && nowQer === 'xj' }"
>
<view class="permission" :class="{ transform: isShowPer && nowQer === 'xj' }">
<view class="per-tit">美融融plus 对相机拍摄权限申请说明</view>
<view class="per-cont"
>便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中所需内容</view
>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中所需内容</view>
</view>
<!-- 新增上门提醒弹窗-->
@ -387,7 +299,9 @@ import PopupPicker from "@/components/popup-picker/popup-picker.vue";
import PopupPickerMy from "@/components/popup-picker/PopupPickerMy.vue";
import CircleProgress from "@/components/circle-progress/circle-progress.vue";
import sparkMD5 from "spark-md5"; // MD5
import { debounce } from "@/utils/debounce.js";
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";
@ -406,7 +320,7 @@ export default {
artisanType: getApp().globalData.artisanType,
nowQer: "xc",
progress: 0,
// isShow: false,
isShow: false,
state: null,
isShowPer: false,
formData: {
@ -414,6 +328,7 @@ export default {
server_kind: getApp().globalData.artisanType,
title: "",
server_price: "",
line_price: '',
server_time: "",
first_class_id: "",
second_class_id: "",
@ -498,6 +413,29 @@ export default {
},
},
methods: {
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
@ -565,13 +503,13 @@ export default {
});
return false;
}
if (!this.detailForm.product || !this.detailForm.product.trim()) {
uni.showToast({
title: "请输入产品清单",
icon: "none",
});
return false;
}
// if (!this.detailForm.product || !this.detailForm.product.trim()) {
// uni.showToast({
// title: "",
// icon: "none",
// });
// return false;
// }
return true;
},
@ -634,7 +572,10 @@ export default {
})
.then((res) => {
//
this.formData = { ...this.formData, ...res.data };
this.formData = {
...this.formData,
...res.data
};
// detail
this.formData.detail = res.data.detail || [];
// 使
@ -730,6 +671,7 @@ export default {
const {
title,
server_price,
line_price,
server_time,
first_class_id,
second_class_id,
@ -741,6 +683,7 @@ export default {
let item = {
title,
server_price,
line_price,
server_time,
first_class_id,
second_class_id,
@ -816,12 +759,19 @@ export default {
});
return;
}
if (!this.formData.line_price) {
uni.showToast({
title: '请输入服务定价',
icon: 'none'
})
return
}
if (!this.formData.server_price) {
uni.showToast({
title: "请输入服务价格",
icon: "none",
});
return;
title: '请输入服务售价',
icon: 'none'
})
return
}
if (!this.formData.first_class_id) {
@ -1027,6 +977,21 @@ export default {
margin-bottom: 24rpx;
}
.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;
}
}
.shopsale-box {
flex-flow: column;
justify-content: space-between;
@ -1450,10 +1415,13 @@ export default {
}
/* 淡入淡出动画 */
.fade-enter-active, .fade-leave-active {
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
.fade-enter,
.fade-leave-to {
opacity: 0;
}

View File

@ -35,6 +35,7 @@
<view class="service-price" >
<text v-if="dataItem.team_buy_id">{{`团购价: `}}</text>¥<text
style="font-size: 34rpx;">{{ dataItem.order_money }}</text>
<text class="service-price-line">{{ dataItem.line_money }}</text>
</view>
</view>
@ -285,6 +286,14 @@
line-height: 34rpx;
text-align: left;
font-style: normal;
.service-price-line {
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
margin-left: 10rpx;
text-decoration: line-through;
}
}
.service-type {

View File

@ -39,6 +39,7 @@
<view class="service-price">
<text v-if="dataItem.team_buy_id">{{`团购价: `}}</text>¥<text
style="font-size: 34rpx;">{{ dataItem.order_money }}</text>
<text class="service-price-line">{{ dataItem.line_money }}</text>
</view>
</view>
@ -258,6 +259,14 @@
line-height: 34rpx;
text-align: left;
font-style: normal;
.service-price-line {
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 34rpx;
margin-left: 10rpx;
text-decoration: line-through;
}
}
.service-type {

View File

@ -105,7 +105,9 @@
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中所需内容</view>
</view>
<video v-show="videoPlay" :src="videoUrl" controls id="myvideo" style="height: 0;width: 0;" @fullscreenchange="screenChange"></video>
<video v-show="videoPlay" :src="videoUrl" controls id="myvideo" style="height: 0; width: 0; position: absolute; top: -999rpx; left: -999rpx;"
@fullscreenchange="screenChange"></video>
<uv-divider></uv-divider>
</view>
</template>
@ -120,6 +122,7 @@
},
data() {
return {
videoContext:null,
videoPlay: false,
videoUrl: "",
disabled: false,
@ -201,10 +204,13 @@
},
methods: {
screenChange(e) {
let fullScreen = e.detail.fullScreen; // truefalse退
console.log(e, "全屏");
if (!fullScreen) {
//退
this.videoContext.pause()
plus.screen.lockOrientation('portrait-primary');
this.videoPlay = false; //
}
},
@ -366,7 +372,8 @@
if (this.formData.type == 1) {
res = await uploadImage.handleUpload(this.userInfo.id, 3);
} else {
res = await uploadImage.handleUpload(this.userInfo.id, 3, ['album', 'camera'], 'video');
res = await uploadImage.handleUpload(this.userInfo.id, 3, ['album', 'camera'],
'video');
}
console.log('上传单张图片', res)
this.formData.url = res;
@ -420,7 +427,8 @@
// 1.
// const { granted } = await permissionUtils.checkPermission('photo_library', '');
this.nowQer = 'xc';
const xc = await permissionUtils.checkPermission('photo_library', '需要相册权限用于上传照片');
const xc = await permissionUtils.checkPermission('photo_library',
'需要相册权限用于上传照片');
this.nowQer = 'xj';
const xj = await permissionUtils.checkPermission('camera', '需要相机权限用于拍摄照片');
this.isShowPer = false;
@ -439,8 +447,10 @@
if (!confirm) return;
// 3.
const result1 = await permissionUtils.requestPermission('photo_library', '我们需要访问您的相册以上传图片/视频');
const result2 = await permissionUtils.requestPermission('camera', '我们需要访问您的相机以上传图片/视频');
const result1 = await permissionUtils.requestPermission('photo_library',
'我们需要访问您的相册以上传图片/视频');
const result2 = await permissionUtils.requestPermission('camera',
'我们需要访问您的相机以上传图片/视频');
if (result1 && result2) {
this.openCamera();
} else {

View File

@ -35,6 +35,10 @@
<image class="photo-mask-img" mode="aspectFill" src="/static/images/icons/time.png"></image>
<text class="photo-mask-text">审核中</text>
</view>
<view class="content-photo-mask" v-if="item2.apply_state==3">
<image class="photo-mask-img" mode="aspectFill" src="/static/images/icons/close2.png"></image>
<view class="photo-mask-text">已驳回</view>
</view>
</view>
</view>
<view class="card-content flex-row-center" v-else>
@ -151,7 +155,25 @@
// });
},
goAdd(id, item) {
console.log(11111, id)
if (this.type == 1) {
if ( this.imgVideoList[id] && this.imgVideoList[id].length >= 20) {
uni.showToast({
title: '最多上传20张图片',
icon: 'none',
duration: 2000
});
return
}
} else if (this.type == 2) {
if ( this.imgVideoList[id] && this.imgVideoList[id].length >= 10) {
uni.showToast({
title: '最多上传10张视频',
icon: 'none',
duration: 2000
});
return
}
}
// 1. id
if (!id) {
uni.showToast({
@ -186,14 +208,19 @@
});
},
async getList() {
await request.post("/sj/imgVideo/list", {
try {
const res = await request.post("/sj/imgVideo/list", {
type: this.type
}).then(res => {
if (res.code == 200) {
this.imgVideoList = res.data.list[this.type]
});
// imgVideoList
this.imgVideoList = res.data?.list?.[this.type] || {};
// res.data.list[this.type]id
// this.imgVideoList = res.data?.list?.[this.type] || {};
} catch (err) {
// imgVideoList
console.error("获取图片/视频列表失败:", err);
this.imgVideoList = {};
}
})
}
}
}

View File

@ -121,7 +121,8 @@
async handleDelete() {
// ID
let deleteIds = this.selectedItems.map(index => this.imgVideoList[index].id);
let auth_ids = this.selectedItems.map(index => this.imgVideoList[index].auth_id).filter(item => item !== 0);
let auth_ids = this.selectedItems.map(index => this.imgVideoList[index].auth_id).filter(item =>
item !== 0);
console.log(1111, deleteIds, auth_ids, [1, 6])
try {
const res = await request.post("/sj/imgVideo/del", {
@ -129,10 +130,6 @@
auth_ids: auth_ids
});
if (res.code == 200) {
uni.showToast({
title: '删除成功',
icon: 'success'
});
//
await this.getList();
// 退
@ -206,14 +203,20 @@
return obj
},
async getList() {
await request.post("/sj/imgVideo/list", {
try {
const res = await request.post("/sj/imgVideo/list", {
type: this.type,
class_type: this.class_type
}).then(res => {
if (res.code == 200) {
this.imgVideoList = res.data.list[this.type][this.class_type]
});
// + 访
this.imgVideoList = res.code === 200 ?
res.data?.list?.[this.type]?.[this.class_type] || [] :
[];
} catch (err) {
//
console.error("获取媒体列表失败:", err);
this.imgVideoList = [];
}
})
}
}
}