This commit is contained in:
zjf committed 2025-11-09 21:41:06 +08:00
commit 74068cbc86
7 files changed
+86 -40

No files matched your search

+2 -2
View File
@@ -33,10 +33,10 @@
color="transparent"
/>
</tm-form-item>
<tm-form-item name="isOtherPeople" label="是否可随行人员" direction="horizontal" labelWidth="500">
<tm-form-item name="isOtherPeople" label="是否有随行人员" direction="horizontal" labelWidth="500">
<tm-switch v-model="form.isOtherPeople" />
</tm-form-item>
<tm-form-item name="isDrive" label="是否可驾驶车辆" direction="horizontal" labelWidth="500">
<tm-form-item name="isDrive" label="是否有驾驶车辆" direction="horizontal" labelWidth="500">
<tm-switch v-model="form.isDrive" />
</tm-form-item>
<tm-button class="mt-4" form-type="submit" block>提 交</tm-button>
@@ -35,12 +35,12 @@
:key="v.id"
@click="onSelectSku(v)"
>
{{ (v.skuName || "") + " / " + (v.skuWeight || "") + "克" }}
{{ v.skuName || "未知" }}
</view>
</view>
</view>
<!-- 购买数量 -->
<!-- 购买 数量 -->
<view class="flex-col card p-y-20rpx p-x-30rpx mb-20rpx">
<view class="prefix_title mb-15rpx">购买数量</view>
<view class="flex items-center justify-between">
+19 -5
View File
@@ -1,6 +1,18 @@
<template>
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
<image :src="filePath(goodsDetail.coverImage)" class="w-full h-500rpx bg-#eeeeee" mode="aspectFill" />
<swiper
class="w-full h-500rpx"
circular
:indicator-dots="true"
indicator-active-color="#0779FD"
indicator-color="#ffffff"
:autoplay="true"
>
<swiper-item v-for="(v, i) in goodsDetail.carouselImages?.split(',')" :key="i">
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
</swiper-item>
</swiper>
<view v-if="goodsDetail.id" class="card p-20rpx mt-10rpx mx-20rpx bg-gradient-to-b from-#0094ff33 to-#fff">
<view v-if="goodsDetail.priceType == '2'" class="w-full flex justify-between items-center">
<view class="flex items-center">
@@ -42,16 +54,15 @@
<view class="bg-#1879ff09 rounded-1 my-2 p-3" v-for="(item, index) in goodsDetail.skuList" :key="index">
<view class="sub-text-30">{{ item.skuName }}</view>
<view class="second-text-28 mt-1 flex justify-between items-center">
<text>售价 {{ displayPrice(item.price) }}</text>
<text>重量 {{ item.weightG }}克</text>
<text>¥{{ displayPrice(item.price) }}</text>
<text>库存 {{ item.stock }}</text>
</view>
</view>
</view>
<view class="mt-20rpx card p-20rpx mx-20rpx">
<view class="prefix_title">商品描述</view>
<view class="mt-20rpx overflow-auto text-26rpx!" v-html="goodsDetail.description"></view>
<view class="prefix_title">详情</view>
<view class="w-full mt-20rpx overflow-hidden text-26rpx!" v-html="description"></view>
</view>
<view class="h-30rpx" />
@@ -86,6 +97,9 @@ const state = reactive<any>({
showCartDialog: false,
})
const goodsDetail = computed(() => state.goodsDetail)
const description = computed(() => {
return goodsDetail.value.description?.replaceAll(`<img`, `<img style="width: 100%;"`)
})
onLoad(async (option: any) => {
const { id, mchId } = option
+58 -27
View File
@@ -7,13 +7,24 @@
<tm-form-item name="title" label="商品标题">
<tm-input v-model="form.title" type="text" :showClear="true" placeholder="请输入商品标题"></tm-input>
</tm-form-item>
<tm-form-item name="unit" label="计量单位">
<tm-input v-model="form.unit" type="text" :showClear="true" placeholder="请输入计量单位"></tm-input>
</tm-form-item>
<tm-form-item name="categoryId" label="分类" @click="selectCategary">
<tm-input v-model="form.categoryName" placeholder="请选择商品分类" style="pointer-events: none" disabled />
<!-- color="transparent" -->
</tm-form-item>
<tm-form-item name="productNature" label="商品性质">
<tm-picker
rang-key="title"
rang-text="title"
v-model="form.productNature"
v-model:model-str="form.productNatureName"
:list="[
{ title: '普通商品', id: '1' },
{ title: '电子称重商品', id: '2' },
]"
>
<tm-input v-model="form.productNature" placeholder="请选择商品性质" style="pointer-events: none" disabled />
</tm-picker>
</tm-form-item>
<tm-form-item name="status" label="状态">
<tm-radio-group v-model="form.status" align="flex-end">
<tm-radio :value="index.toString()" :label="item" v-for="(item, index) in ['上架', '下架']" :key="index"></tm-radio>
@@ -61,7 +72,7 @@
</tm-input>
</tm-picker-date>
</tm-form-item>
<tm-form-item name="coverImage" label="商品图">
<tm-form-item name="coverImage" label="商品主图">
<tm-upload-photo
v-model="form.coverImage"
:maxFileSize="1024 * 1024 * 5"
@@ -73,6 +84,17 @@
/>
</tm-form-item>
<view class="sub-text-20 c-red! mb-2">注:图片大小不超过5M</view>
<!-- <tm-form-item name="carouselImages" label="轮播图">
<tm-upload-photo
v-model="form.carouselImages"
:maxFileSize="1024 * 1024 * 5"
:url="'/api/admin/sys-file/upload'"
:header="hooks.useDefaultHeader()"
:column="2"
img-height="200"
:max-count="5"
/>
</tm-form-item> -->
<tm-form-item name="description" label="详情描述" direction="vertical" required="">
<!-- <rich-text-input v-model="form.description" placeholder="点击编辑详情描述..." label="详情描述" /> -->
<tm-input v-model="form.description" type="textarea" :showClear="false" placeholder="请输入详情描述"></tm-input>
@@ -84,10 +106,10 @@
:label="item.label"
v-for="(item, index) in [
{ label: '多SKU模式', value: '1' },
{ label: '单价SPU模式', value: '2' },
// { label: '单价SPU模式', value: '2' },
]"
:key="index"
></tm-radio>
/>
</tm-radio-group>
</tm-form-item>
<view v-if="form.priceType == '2'">
@@ -110,7 +132,9 @@
<view v-if="index !== 0" class="my-4 h-3rpx bg-#A0A0A044"></view>
<view class="flex justify-between items-center mb-2">
<text>编号:{{ index + 1 }}</text>
<tm-button v-if="index !== 0" class="px-2" size="xs" skin="thin" @click.stop="delSkuListItem(index)">删 除</tm-button>
<tm-button v-if="index !== 0" class="px-2" size="s" color="error" skin="thin" @click.stop="delSkuListItem(index)">
删 除
</tm-button>
</view>
<tm-form-item name="skuList[index].skuCode" label="SKU编码">
<tm-input v-model="item.skuCode" placeholder="请输入SKU编码"></tm-input>
@@ -131,33 +155,30 @@
<tm-stepper :max="10000" width="300" v-model="item.stock"></tm-stepper>
</view>
</tm-form-item>
<tm-form-item name="skuList[index].weightG" label="重量(克)">
<!-- <tm-form-item name="skuList[index].weightG" label="重量(克)">
<view class="flex justify-end">
<tm-stepper :max="10000" width="300" v-model="item.weightG"></tm-stepper>
</view>
</tm-form-item>
</tm-form-item> -->
<tm-form-item name="skuList[index].status" label="状态">
<tm-radio-group v-model="item.status" align="flex-end">
<tm-radio :value="index.toString()" :label="item" v-for="(item, index) in ['启用', '禁用']" :key="index"></tm-radio>
</tm-radio-group>
</tm-form-item>
</view>
<tm-button block size="s" skin="dashed" color="#E5F1FF" @click.stop="addSkuListItem()">添 加</tm-button>
<tm-button block size="m" color="#E5F1FF" @click.stop="addSkuListItem()">添 加</tm-button>
</view>
<tm-button form-type="submit" block>提 交</tm-button>
</tm-form>
<tm-drawer
title="请选择分类"
:showClose="true"
:showFooter="false"
size="70%"
v-model:show="showCategaryPicker"
:duration="100"
zIndex="100"
>
<shop-categary-picker :categoryTree="categoryTree" @confirm="onCategaryConfirm" @cancel="showCategaryPicker = false" />
<tm-drawer title="请选择分类" :showClose="true" :showFooter="false" size="70%" v-model:show="showCategaryPicker">
<shop-categary-picker
v-model="form.categoryId"
:categoryTree="categoryTree"
@confirm="onCategaryConfirm"
@cancel="showCategaryPicker = false"
/>
</tm-drawer>
<view class="h-30rpx" />
@@ -165,7 +186,7 @@
</template>
<script setup lang="ts">
import { reactive, ref } from "vue"
import { reactive, ref, watch } from "vue"
import { hooks } from "@@/index"
import { prosperityShopApi } from "@/sheep/api"
import ShopCategaryPicker from "@/sheep/components/shop-categary-picker.vue"
@@ -176,15 +197,16 @@ import { displayPrice, storePrice } from "@/sheep/utils/formatMoney"
const form = reactive<any>({
id: "",
title: "",
unit: "",
categoryId: "",
categoryName: "",
productNature: "",
status: "0",
saleStartTime: "",
saleEndTime: "",
coverImage: [],
// carouselImages: [],
description: "",
priceType: "1", // 定价方式(1:多SKU,2:单价SPU)
priceType: 1, // 定价方式(1:多SKU,2:单价SPU)
spuPrice: 0,
originalPrice: 0,
skuList: [
@@ -209,12 +231,13 @@ const categoryList = ref<any>([])
const rules: Record<string, TM.FORM_RULE[]> = {
title: [{ required: true, message: "请输入商品标题" }],
unit: [{ required: true, message: "请输入商品单位" }],
categoryId: [{ required: true, message: "请选择商品分类" }],
productNature: [{ required: true, message: "请选择商品性质" }],
status: [{ required: true, message: "请选择状态" }],
saleStartTime: [{ required: true, message: "请选择售卖开始时间" }],
saleEndTime: [{ required: true, message: "请选择售卖结束时间" }],
coverImage: [{ required: true, message: "请上传商品图" }],
coverImage: [{ required: true, message: "请上传商品主图" }],
// carouselImages: [{ required: true, message: "请上传轮播图" }],
}
onLoad(async (options: any) => {
@@ -230,6 +253,10 @@ const getGoodsDetail = async (id: string) => {
if (code != 0 || !data) return uni.showToast({ title: msg || "商品详情获取失败", icon: "none" })
const skuList = data.skuList.map((item: any) => ({ ...item, status: item.status.toString(), price: displayPrice(item.price, "") }))
const coverImage = [{ path: filePath(data.coverImage), response: JSON.stringify({ data: { url: data.coverImage } }) }]
// const carouselImages = data.carouselImages?.split(",").map((url: string) => ({
// path: filePath(url),
// response: JSON.stringify({ data: { url } }),
// }))
const categoryName = categoryList.value.find((item: any) => item.id == data.categoryId)?.name
const saleStartTime = data.saleStartTime
const saleEndTime = data.saleEndTime
@@ -243,6 +270,7 @@ const getGoodsDetail = async (id: string) => {
spuPrice: displayPrice(data.spuPrice, ""),
originalPrice: displayPrice(data.originalPrice, ""),
coverImage,
// carouselImages,
categoryName,
saleStartTime,
saleEndTime,
@@ -295,16 +323,18 @@ const addSkuListItem = () => {
// 保存
const onsubmit = async (evt: TM.FORM_SUBMIT_RESULT) => {
// console.log("校验结果:", evt)
console.log(form.carouselImages)
const submitData = {
...form,
coverImage: JSON.parse(form.coverImage[0].response).data.url,
// carouselImages: form.carouselImages.map((item: any) => JSON.parse(item.response).data.url).join(","),
}
console.log("提交的数据:", submitData)
if (!evt.isPass) return
if (form.priceType == "1") {
if (form.priceType == 1) {
for (let i = 0; i < form.skuList.length; i++) {
const skuItem = form.skuList[i]
for (const key in skuItem) {
@@ -313,7 +343,7 @@ const onsubmit = async (evt: TM.FORM_SUBMIT_RESULT) => {
}
}
if (form.priceType == "2") {
if (form.priceType == 2) {
form.skuList = []
}
@@ -329,6 +359,7 @@ const onsubmit = async (evt: TM.FORM_SUBMIT_RESULT) => {
}
}),
coverImage: JSON.parse(form.coverImage[0].response).data.url,
// carouselImages: form.carouselImages.map((item: any) => JSON.parse(item.response).data.url).join(","),
}
uni.showLoading({ title: "提交中..." })
const { code, msg } = await (form.id ? prosperityShopApi.editGoods(params) : prosperityShopApi.addGoods(params))
+1 -1
View File
@@ -100,7 +100,7 @@
<tm-button class="px-2" size="s" :linear="['to right', '#62abff', '#0779FD99']" @click.stop="editGoods(v.id)">
编辑商品
</tm-button>
<tm-button class="px-2" size="s" :linear="['to right', '#00B960', '#00552C99']" @click.stop="doGoodsDetail(v.id)">
<tm-button class="px-2" size="s" :linear="['to right', '#00B960', '#00552C99']" @click.stop="doGoodsDetail(v.id, v.merchantId)">
查看详情
</tm-button>
</view>
@@ -27,10 +27,10 @@ export function useGoodsManage(pageRef) {
})
}
// 查看详情
const doGoodsDetail = (id: string) => {
const doGoodsDetail = (id: string, merchantId: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.navigateTo({
url: `/pages/prosperity-shop/goods-detail?id=${id}`,
url: `/pages/prosperity-shop/goods-detail?id=${id}&mchId=${merchantId}`,
})
}
// 分类管理
@@ -1,6 +1,6 @@
<template>
<view class="mb-20rpx">
<node-tree :node-data="categoryTree" @currentNode="currentNode" />
<node-tree v-model="selectedNodeId" :node-data="categoryTree" @currentNode="currentNode" />
<view v-if="categoryTree.length === 0" class="text-center text-#888 py-40rpx">暂无数据</view>
</view>
<view class="px-20rpx py-2 flex justify-between sticky bottom-0 bg-white">
@@ -20,6 +20,7 @@ defineProps({
default: () => [],
},
})
const selectedNodeId = defineModel("modelValue")
const emit = defineEmits(["confirm", "cancel"])
const selectedNode = ref<any>({})