feat:组件调整

This commit is contained in:
weiwei committed 2025-09-15 19:27:49 +08:00
1 parent afe6ab17f8
commit bf5828ef4d
11 files changed
+180 -273

No files matched your search

+1 -1
View File
@@ -174,7 +174,7 @@
}
},
{
"path": "goods-categary",
"path": "categary-manage",
"style": {
"navigationBarTitleText": "商品分类管理",
"disableScroll": true
@@ -2,19 +2,22 @@
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
<view class="h-40rpx"></view>
<view class="card flex justify-between items-center mb-2 mx-20rpx p-4" v-for="item in categoryList" :key="item.id">
<view class="flex-row-center gap-2">
<text class="sub-text-30">{{ item.name }}</text>
<text class="c-#0094ff! sub-text-24 mr-20rpx px-2 bg-#0094ff22 rounded-2">{{ item.status == "0" ? "正常" : "禁用" }}</text>
</view>
<view class="flex-row-center gap-2">
<tm-button class="px-2" size="xs" :linear="['to right', '#62abff', '#0779FD99']" @click="editCategary(item)">编辑</tm-button>
<tm-button class="px-2" size="xs" :linear="['to right', '#FFC328', '#E2000099']" @click="delCategary(item.id)">删除</tm-button>
<image :src="filePath(item.picUrl)" class="size-100rpx mr-4" />
<view class="flex-1 flex-col">
<view class="flex justify-between items-center">
<text class="sub-text-30">{{ item.name }}</text>
<text class="c-#0094ff! sub-text-24 px-2 bg-#0094ff22 rounded-2">{{ item.status == "0" ? "正常" : "禁用" }}</text>
</view>
<view class="flex justify-end items-center gap-2 mt-2">
<tm-button class="px-2" size="s" :linear="['to right', '#62abff', '#0779FD99']" @click="editCategary(item)">编辑</tm-button>
<tm-button class="px-2" size="s" :linear="['to right', '#FFC328', '#E2000099']" @click="delCategary(item.id)">删除</tm-button>
</view>
</view>
</view>
<view class="h-100rpx"></view>
<view class="fixed bottom-80rpx left-40rpx">
<tm-button class="px-2" size="s" :linear="['to right', '#0779FD', '#62abff']" @click="addCategary">新增分类</tm-button>
<tm-button class="px-2" size="m" :linear="['to right', '#0779FD', '#62abff']" @click="addCategary">新增分类</tm-button>
</view>
<tm-drawer
@@ -47,8 +50,8 @@
</tm-radio-group>
</tm-form-item>
<view class="prefix_title mb-2">父级分类</view>
<view class="card my-2">
<shop-categary-tree v-model="selectedNode" :node-data="categoryTree" />
<view class="my-2">
<node-tree v-model="selectedNode" :node-data="categoryTree" />
</view>
<tm-button form-type="submit" block>保 存</tm-button>
</tm-form>
@@ -61,9 +64,10 @@
import { prosperityShopApi } from "@/sheep/api"
import { onLoad } from "@dcloudio/uni-app"
import { reactive, ref } from "vue"
import ShopCategaryTree from "@/sheep/components/shop-categary-tree.vue"
import NodeTree from "@/sheep/components/node-tree.vue"
import { useCategaryManage } from "./use-categary-manage"
import { filePath } from "@/sheep/utils/file"
const categoryList = ref<any>([])
const categaryFormDrawer = ref(false)
const form = reactive({
id: "",
@@ -74,16 +78,12 @@ const form = reactive({
const categoryTree = ref([])
const selectedNode = ref<any>({})
const { categoryList, getGoodsCategory, delCategary } = useCategaryManage()
onLoad(() => {
getGoodsCategory()
})
const getGoodsCategory = async () => {
const { code, data, msg } = await prosperityShopApi.getGoodsCategory()
if (code != 0) return uni.showToast({ title: msg || "商品分类获取失败", icon: "none" })
categoryList.value = data
}
const getCategaryTree = async () => {
const { code, data, msg } = await prosperityShopApi.getGoodsCategoryTree()
if (code != 0) return uni.showToast({ title: msg || "商品分类获取失败", icon: "none" })
@@ -114,7 +114,7 @@ const editCategary = (item) => {
// 提交保存
const saveCategary = async () => {
if (!form.name) return uni.showToast({ title: "请填写分类名称", icon: "none" })
if (selectedNode.value.id === form.id) return uni.showToast({ title: "父级分类不能是自身", icon: "none" })
if (selectedNode.value.id === form.id) return uni.showToast({ title: "父级分类不能是自己", icon: "none" })
try {
const params = { ...form, parentId: selectedNode.value.id }
uni.showLoading({ title: "保存中..." })
@@ -127,23 +127,4 @@ const saveCategary = async () => {
uni.hideLoading()
}
}
// 删除分类
const delCategary = async (id: string) => {
if (!id) return uni.showToast({ title: "分类id不存在", icon: "none" })
uni.showModal({
title: "确定删除分类吗?",
content: "",
success: async (res) => {
if (res.confirm) {
uni.showLoading({ title: "正在删除" })
const { code, msg } = await prosperityShopApi.delCategary(id)
if (code != 0) return uni.showToast({ title: msg || "删除失败", icon: "none" })
uni.showToast({ title: "删除成功", icon: "none" })
getGoodsCategory()
uni.hideLoading()
}
},
})
}
</script>
+5 -129
View File
@@ -74,7 +74,8 @@
</tm-form-item>
<view class="sub-text-20 c-red! mb-2">注:图片大小不超过5M</view>
<tm-form-item name="description" label="详情描述" direction="vertical" required="">
<rich-text-input v-model="form.description" placeholder="点击编辑详情描述..." label="详情描述" />
<!-- <rich-text-input v-model="form.description" placeholder="点击编辑详情描述..." label="详情描述" /> -->
<tm-input v-model="form.description" type="textarea" :showClear="false" placeholder="请输入详情描述"></tm-input>
</tm-form-item>
<tm-form-item name="priceType" label="定价方式">
<tm-radio-group v-model="form.priceType" align="flex-end">
@@ -151,7 +152,7 @@
title="请选择分类"
:showClose="true"
:showFooter="false"
size="auto"
size="70%"
v-model:show="showCategaryPicker"
:duration="100"
zIndex="100"
@@ -168,7 +169,6 @@ import { reactive, ref } from "vue"
import { hooks } from "@@/index"
import { prosperityShopApi } from "@/sheep/api"
import ShopCategaryPicker from "@/sheep/components/shop-categary-picker.vue"
import RichTextInput from "@/sheep/components/rich-text-input/rich-text-input.vue"
import { onLoad } from "@dcloudio/uni-app"
import { filePath } from "@/sheep/utils/file"
import { displayPrice, storePrice } from "@/sheep/utils/formatMoney"
@@ -228,7 +228,7 @@ const getGoodsDetail = async (id: string) => {
uni.showLoading({ title: "加载中..." })
const { code, data, msg } = await prosperityShopApi.getGoodsDetail(id)
if (code != 0 || !data) return uni.showToast({ title: msg || "商品详情获取失败", icon: "none" })
const skuList = data.skuList.map((item: any) => ({ ...item, status: item.status.toString() }))
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 categoryName = categoryList.value.find((item: any) => item.id == data.categoryId)?.name
const saleStartTime = data.saleStartTime
@@ -236,11 +236,6 @@ const getGoodsDetail = async (id: string) => {
_saleStartTimeStr.value = saleStartTime
_saleEndTimeStr.value = saleEndTime
// 转换HTML为Markdown格式
const description = convertHtmlToMarkdown(data.description || "")
console.log("原始HTML:", data.description)
console.log("转换后Markdown:", description)
Object.assign(form, {
...data,
status: data.status.toString(),
@@ -251,95 +246,11 @@ const getGoodsDetail = async (id: string) => {
categoryName,
saleStartTime,
saleEndTime,
skuList: data.skuList.map((item: any) => {
return {
...item,
price: displayPrice(item.price, ""),
}
}),
description,
skuList,
})
uni.hideLoading()
}
// HTML转Markdown函数
const convertHtmlToMarkdown = (html: string): string => {
if (!html) return ""
// 移除HTML标签,保留文本内容
let markdown = html
// 处理标题
.replace(/<h1[^>]*>(.*?)<\/h1>/gi, "# $1\n")
.replace(/<h2[^>]*>(.*?)<\/h2>/gi, "## $1\n")
.replace(/<h3[^>]*>(.*?)<\/h3>/gi, "### $1\n")
.replace(/<h4[^>]*>(.*?)<\/h4>/gi, "#### $1\n")
.replace(/<h5[^>]*>(.*?)<\/h5>/gi, "##### $1\n")
.replace(/<h6[^>]*>(.*?)<\/h6>/gi, "###### $1\n")
// 处理段落
.replace(/<p[^>]*>(.*?)<\/p>/gi, "$1\n\n")
// 处理换行
.replace(/<br\s*\/?>/gi, "\n")
// 处理粗体
.replace(/<strong[^>]*>(.*?)<\/strong>/gi, "**$1**")
.replace(/<b[^>]*>(.*?)<\/b>/gi, "**$1**")
// 处理斜体
.replace(/<em[^>]*>(.*?)<\/em>/gi, "*$1*")
.replace(/<i[^>]*>(.*?)<\/i>/gi, "*$1*")
// 处理下划线
.replace(/<u[^>]*>(.*?)<\/u>/gi, "__$1__")
// 处理链接
.replace(/<a[^>]*href=["']([^"']*)["'][^>]*>(.*?)<\/a>/gi, "[$2]($1)")
// 处理图片 - 更全面的图片处理
.replace(/<img[^>]*src=["']([^"']*)["'][^>]*alt=["']([^"']*)["'][^>]*>/gi, (match, src, alt) => {
// 直接使用原始URL,不添加额外前缀
console.log("HTML图片转换 - 原始:", match)
console.log("HTML图片转换 - src:", src)
console.log("HTML图片转换 - alt:", alt)
return `![${alt || "图片"}](${src})`
})
.replace(/<img[^>]*src=["']([^"']*)["'][^>]*>/gi, (match, src) => {
// 直接使用原始URL,不添加额外前缀
console.log("HTML图片转换 - 原始:", match)
console.log("HTML图片转换 - src:", src)
return `![图片](${src})`
})
// 处理列表
.replace(/<ul[^>]*>(.*?)<\/ul>/gis, (match, content) => {
return content.replace(/<li[^>]*>(.*?)<\/li>/gi, "- $1\n")
})
.replace(/<ol[^>]*>(.*?)<\/ol>/gis, (match, content) => {
let index = 1
return content.replace(/<li[^>]*>(.*?)<\/li>/gi, () => `${index++}. $1\n`)
})
// 处理引用
.replace(/<blockquote[^>]*>(.*?)<\/blockquote>/gis, (match, content) => {
return content.replace(/\n/g, "\n> ") + "\n"
})
// 处理代码
.replace(/<code[^>]*>(.*?)<\/code>/gi, "`$1`")
.replace(/<pre[^>]*>(.*?)<\/pre>/gis, "```\n$1\n```")
// 处理分割线
.replace(/<hr[^>]*>/gi, "---\n")
// 处理表格(简单处理)
.replace(/<table[^>]*>(.*?)<\/table>/gis, (match, content) => {
// 这里可以添加更复杂的表格处理逻辑
return content.replace(/<tr[^>]*>(.*?)<\/tr>/gi, (trMatch, trContent) => {
const cells = trContent.match(/<t[hd][^>]*>(.*?)<\/t[hd]>/gi)
if (cells) {
return "| " + cells.map((cell) => cell.replace(/<[^>]*>/g, "")).join(" | ") + " |\n"
}
return ""
})
})
// 移除剩余的HTML标签
.replace(/<[^>]*>/g, "")
// 清理多余的换行
.replace(/\n{3,}/g, "\n\n")
.trim()
return markdown
}
const getGoodsCategory = async () => {
const { code, data, msg } = await prosperityShopApi.getGoodsCategory()
if (code != 0) return uni.showToast({ title: msg || "商品分类获取失败", icon: "none" })
@@ -381,46 +292,12 @@ const addSkuListItem = () => {
})
}
// Markdown转HTML函数
const convertMarkdownToHtml = (markdown: string): string => {
if (!markdown) return ""
let html = markdown
// 处理标题
.replace(/^# (.*$)/gim, "<h1>$1</h1>")
.replace(/^## (.*$)/gim, "<h2>$1</h2>")
.replace(/^### (.*$)/gim, "<h3>$1</h3>")
.replace(/^#### (.*$)/gim, "<h4>$1</h4>")
.replace(/^##### (.*$)/gim, "<h5>$1</h5>")
.replace(/^###### (.*$)/gim, "<h6>$1</h6>")
// 处理粗体
.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
// 处理斜体
.replace(/\*(.*?)\*/g, "<em>$1</em>")
// 处理链接
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>')
// 处理图片
.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" style="max-width: 100%; height: auto;" />')
// 处理段落
.replace(/^(?!<[h1-6]|<img|<ul|<ol|<li)(.+)$/gim, "<p>$1</p>")
// 处理换行
.replace(/\n/g, "<br>")
return html
}
// 保存
const onsubmit = async (evt: TM.FORM_SUBMIT_RESULT) => {
// console.log("校验结果:", evt)
// 将Markdown格式的description转换为HTML
const htmlDescription = convertMarkdownToHtml(form.description)
console.log("原始Markdown:", form.description)
console.log("转换后HTML:", htmlDescription)
const submitData = {
...form,
description: htmlDescription, // 使用转换后的HTML
coverImage: JSON.parse(form.coverImage[0].response).data.url,
}
console.log("提交的数据:", submitData)
@@ -451,7 +328,6 @@ const onsubmit = async (evt: TM.FORM_SUBMIT_RESULT) => {
price: storePrice(item.price),
}
}),
description: htmlDescription, // 使用转换后的HTML
coverImage: JSON.parse(form.coverImage[0].response).data.url,
}
uni.showLoading({ title: "提交中..." })
+5 -42
View File
@@ -107,8 +107,8 @@
</view>
</z-paging>
<view class="fixed bottom-80rpx left-40rpx flex-col gap-2">
<tm-button class="px-2" size="s" :linear="['to right', '#0779FD', '#62abff']" @click="addGoods">新增商品</tm-button>
<tm-button class="px-2" size="s" :linear="['to right', '#0779FD', '#62abff']" @click="categaryManage">分类管理</tm-button>
<tm-button class="px-2" size="m" :linear="['to right', '#0779FD', '#62abff']" @click="addGoods">新增商品</tm-button>
<tm-button class="px-2" size="m" :linear="['to right', '#0779FD', '#62abff']" @click="categaryManage">分类管理</tm-button>
</view>
</crud-layout>
</template>
@@ -120,6 +120,7 @@ import { hooks } from "@/sheep"
import { filePath } from "@/sheep/utils/file"
import { onLoad, onShow } from "@dcloudio/uni-app"
import { displayPrice } from "@/sheep/utils/formatMoney"
import { useGoodsManage } from "./use-goods-manage"
const state = reactive<any>({
params: {
@@ -137,6 +138,8 @@ const query = (page: number, pagesize: number) => {
pageHook.startPage(page, pagesize, false, state.params)
}
const { addGoods, editGoods, deleteGoods, doGoodsDetail, categaryManage } = useGoodsManage(pageRef)
onLoad(async () => {
await getGoodsCategory()
})
@@ -167,46 +170,6 @@ const search = () => {
const inputClear = () => {
pageRef.value && pageRef.value.reload(false)
}
const doGoodsDetail = (id: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.navigateTo({
url: `/pages/prosperity-shop/goods-detail?id=${id}`,
})
}
// 新增商品
const addGoods = () => {
uni.navigateTo({ url: `/pages/prosperity-shop/goods-form` })
}
// 编辑商品
const editGoods = (id: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.navigateTo({ url: `/pages/prosperity-shop/goods-form?id=${id}` })
}
// 删除商品
const deleteGoods = (id: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.showModal({
title: "确定删除商品吗?",
content: "",
success: async (res) => {
if (res.confirm) {
const { code } = await prosperityShopApi.deleteGoods(id)
if (code != 0) return uni.showToast({ title: "删除失败", icon: "error" })
uni.showToast({ title: "删除成功", icon: "none" })
pageRef.value && pageRef.value.reload(false)
}
},
})
}
// 分类管理
const categaryManage = () => {
uni.navigateTo({ url: "/pages/prosperity-shop/goods-categary" })
}
</script>
<style scoped lang="scss">
+4 -39
View File
@@ -1,5 +1,5 @@
<template>
<crud-layout mainIsScroll bg="/static/page/blue-bg.png" @scroll="scroll">
<crud-layout mainIsScroll bg="/static/page/blue-bg.png" @scroll="onScroll">
<view class="w-full h-400rpx relative">
<image :src="filePath(state.detail.images)" class="w-full h-full bg-#eeeeee" mode="aspectFill" />
<view class="absolute w-full h-full top-0 left-0" :style="filterStyle"></view>
@@ -88,21 +88,13 @@
</template>
<script setup lang="ts">
import { computed, reactive, ref } from "vue"
import { reactive } from "vue"
import { prosperityShopApi } from "@/sheep/api"
import { onLoad } from "@dcloudio/uni-app"
import { filePath } from "@/sheep/utils/file"
import treeToList from "@/sheep/utils/tree-to-list"
import { displayPrice } from "@/sheep/utils/formatMoney"
interface scrollDetail {
deltaX: number
deltaY: number
scrollHeight: number
scrollLeft: number
scrollTop: number
scrollWidth: number
}
import { useShopDetailScroll } from "./use-shop-detail-scroll"
const state = reactive<any>({
id: "",
@@ -111,7 +103,7 @@ const state = reactive<any>({
curCategoryIndex: 0,
goodsList: [],
})
const scrollDetail = ref<scrollDetail>({} as scrollDetail)
const { scrollDetail, onScroll, filterStyle, searchStyle } = useShopDetailScroll()
onLoad(async (option: any) => {
if (!option.id) return uni.showToast({ title: "参数错误", icon: "error" })
@@ -155,33 +147,6 @@ const doCategory = async (index: number) => {
uni.hideLoading()
}
const scroll = (e: any) => {
scrollDetail.value = e.detail
}
const filterStyle = computed(() => {
const scrollY = scrollDetail.value.scrollTop
const blur = Math.min(1, scrollY / 400) * 20
return {
backdropFilter: `blur(${blur}rpx)`,
}
})
const searchStyle = computed(() => {
const minWidth = 10
const scrollY = scrollDetail.value.scrollTop
const scrollHeight = scrollDetail.value.scrollHeight
const scrollWidth = scrollDetail.value.scrollWidth
const calcWidth = (scrollY / scrollHeight) * scrollWidth
if (isNaN(calcWidth)) return { width: `${minWidth}%` }
if (calcWidth < 2) return { width: `${calcWidth + minWidth}%` }
return {
width: `${calcWidth + minWidth}%`,
border: `2rpx solid #1879ff`,
opacity: (calcWidth / 100) * 2,
}
})
const doGoodsDetail = (id: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.navigateTo({
@@ -0,0 +1,33 @@
import { prosperityShopApi } from "@/sheep/api"
import { ref } from "vue"
export function useCategaryManage() {
const categoryList = ref<any>([])
// 获取商品分类
const getGoodsCategory = async () => {
const { code, data, msg } = await prosperityShopApi.getGoodsCategory()
if (code != 0) return uni.showToast({ title: msg || "商品分类获取失败", icon: "none" })
categoryList.value = data
}
// 删除分类
const delCategary = async (id: string) => {
if (!id) return uni.showToast({ title: "分类id不存在", icon: "none" })
uni.showModal({
title: "确定删除分类吗?",
content: "",
success: async (res) => {
if (res.confirm) {
uni.showLoading({ title: "正在删除" })
const { code, msg } = await prosperityShopApi.delCategary(id)
if (code != 0) return uni.showToast({ title: msg || "删除失败", icon: "none" })
uni.showToast({ title: "删除成功", icon: "none" })
getGoodsCategory()
uni.hideLoading()
}
},
})
}
return { categoryList, getGoodsCategory, delCategary }
}
@@ -0,0 +1,42 @@
import { prosperityShopApi } from "@/sheep/api"
export function useGoodsManage(pageRef) {
// 新增商品
const addGoods = () => {
uni.navigateTo({ url: `/pages/prosperity-shop/goods-form` })
}
// 编辑商品
const editGoods = (id: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.navigateTo({ url: `/pages/prosperity-shop/goods-form?id=${id}` })
}
// 删除商品
const deleteGoods = (id: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.showModal({
title: "确定删除商品吗?",
content: "",
success: async (res) => {
if (res.confirm) {
const { code } = await prosperityShopApi.deleteGoods(id)
if (code != 0) return uni.showToast({ title: "删除失败", icon: "error" })
uni.showToast({ title: "删除成功", icon: "none" })
pageRef.value && pageRef.value.reload(false)
}
},
})
}
// 查看详情
const doGoodsDetail = (id: string) => {
if (!id) return uni.showToast({ title: "商品id不存在", icon: "none" })
uni.navigateTo({
url: `/pages/prosperity-shop/goods-detail?id=${id}`,
})
}
// 分类管理
const categaryManage = () => {
uni.navigateTo({ url: "/pages/prosperity-shop/categary-manage" })
}
return { addGoods, editGoods, deleteGoods, doGoodsDetail, categaryManage }
}
@@ -0,0 +1,45 @@
import { computed, ref } from "vue"
interface scrollDetail {
deltaX: number
deltaY: number
scrollHeight: number
scrollLeft: number
scrollTop: number
scrollWidth: number
}
export function useShopDetailScroll() {
const scrollDetail = ref<scrollDetail>({} as scrollDetail)
const onScroll = (e: any) => {
scrollDetail.value = e.detail
}
const filterStyle = computed(() => {
if (!scrollDetail.value.scrollTop) return {}
const scrollY = scrollDetail.value.scrollTop
const blur = Math.min(1, scrollY / 400) * 10
return {
backdropFilter: `blur(${blur}rpx)`,
}
})
const searchStyle = computed(() => {
if (!scrollDetail.value.scrollTop) return {}
const minWidth = 10
const scrollY = scrollDetail.value.scrollTop
const scrollHeight = scrollDetail.value.scrollHeight
const scrollWidth = scrollDetail.value.scrollWidth
const calcWidth = Math.min((scrollY / scrollHeight) * scrollWidth, scrollWidth)
if (isNaN(calcWidth)) return { width: `${minWidth}%` }
if (calcWidth < 2) return { width: `${calcWidth + minWidth}%` }
return {
width: `${calcWidth + minWidth}%`,
border: `2rpx solid #1879ff`,
opacity: (calcWidth / 100) * 6,
}
})
return { scrollDetail, onScroll, filterStyle, searchStyle }
}
+2 -2
View File
@@ -426,13 +426,13 @@ onLoad(async () => {
await userApi.userRole()
await isMerchant()
await isMallMchUser()
// 获取存储中的用户信息
storage.getUserInfo()
})
const isMerchant = async () => {
const isMallMchUser = async () => {
const { data } = await userApi.isMallMchUser()
if (data)
state.menuList.unshift({ text: "共富商城商品管理", icon: "/static/icon/service_4.png", router: "/pages/prosperity-shop/goods-manage" })
@@ -3,17 +3,18 @@
<view v-for="item in nodeData" :key="item.id">
<view
class="tree-item"
:style="item.id == selectedNode.id ? { backgroundColor: '#4b93ff', color: '#fff' } : { color: '#000' }"
:style="item.id == selectedNode.id ? { borderColor: '#1879ff' } : { color: '#000' }"
@click.stop="toCurrentNode(item)"
>
<image class="tree-item-icon" :src="filePath(item.picUrl)" />
<text>{{ item.name }}</text>
</view>
<shop-categary-tree
<node-tree
v-model="selectedNode"
v-if="item.children && item.children.length"
:node-data="item.children"
:style="{ marginLeft: `${getLevel() * 60}rpx` }"
:style="{ marginLeft: `${getLevel(item.level) * 60}rpx` }"
@currentNode="(v) => emit('currentNode', v)"
/>
</view>
@@ -21,14 +22,10 @@
</template>
<script setup lang="ts">
import ShopCategaryTree from "./shop-categary-tree.vue"
import { filePath } from "../utils/file"
import NodeTree from "./node-tree.vue"
defineProps({
nodeData: {
type: Array<any>,
default: () => [],
},
})
withDefaults(defineProps<{ nodeData: any[] }>(), { nodeData: () => [] })
const emit = defineEmits(["currentNode"])
const selectedNode = defineModel<any>("modelValue")
@@ -37,19 +34,26 @@ const toCurrentNode = (item) => {
selectedNode.value = item
}
const getLevel = () => {
return 1
const getLevel = (level) => {
return level
}
</script>
<style scoped>
.tree-container {
padding: 0 40rpx;
overflow: hidden;
}
.tree-item {
border-bottom: 1rpx solid #e4e7ed;
border: 4rpx solid #e4e7ed77;
margin-bottom: 16rpx;
display: flex;
padding: 10rpx 0 10rpx 20rpx;
align-items: center;
padding: 10rpx 20rpx;
border-radius: 10rpx;
}
.tree-item-icon {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
</style>
@@ -1,9 +1,9 @@
<template>
<view class="max-h-[60vh] overflow-y-auto mb-20rpx">
<shop-categary-tree v-model="selectedNode" :node-data="categoryTree" />
<view v-if="categoryTree.length === 0" class="text-center text-[#888] py-[40rpx]">暂无数据</view>
<view class="mb-20rpx">
<node-tree v-model="selectedNode" :node-data="categoryTree" />
<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">
<view class="px-20rpx py-2 flex justify-between sticky bottom-0 bg-white">
<tm-button skin="thin" block @click="emit('cancel')">取消</tm-button>
&nbsp;&nbsp;
<tm-button block :disabled="!selectedNode" @click="onConfirm">确定</tm-button>
@@ -12,7 +12,7 @@
<script setup lang="ts">
import { ref } from "vue"
import ShopCategaryTree from "@/sheep/components/shop-categary-tree.vue"
import NodeTree from "@/sheep/components/node-tree.vue"
defineProps({
categoryTree: {
@@ -31,5 +31,3 @@ function onConfirm() {
emit("confirm", { ...selectedNode, categoryId: selectedNode.value.id, categoryName: selectedNode.value.name })
}
</script>
<style scoped></style>