From bf5828ef4d64e473d6dedd71520504cb6a29eaad Mon Sep 17 00:00:00 2001 From: weiwei Date: Mon, 15 Sep 2025 19:27:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E7=BB=84=E4=BB=B6=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages.json | 2 +- ...goods-categary.vue => categary-manage.vue} | 57 +++----- src/pages/prosperity-shop/goods-form.vue | 134 +----------------- src/pages/prosperity-shop/goods-manage.vue | 47 +----- src/pages/prosperity-shop/shop-detail.vue | 43 +----- .../prosperity-shop/use-categary-manage.ts | 33 +++++ src/pages/prosperity-shop/use-goods-manage.ts | 42 ++++++ .../prosperity-shop/use-shop-detail-scroll.ts | 45 ++++++ src/pages/tabbar/my.vue | 4 +- .../{shop-categary-tree.vue => node-tree.vue} | 34 +++-- src/sheep/components/shop-categary-picker.vue | 12 +- 11 files changed, 180 insertions(+), 273 deletions(-) rename src/pages/prosperity-shop/{goods-categary.vue => categary-manage.vue} (68%) create mode 100644 src/pages/prosperity-shop/use-categary-manage.ts create mode 100644 src/pages/prosperity-shop/use-goods-manage.ts create mode 100644 src/pages/prosperity-shop/use-shop-detail-scroll.ts rename src/sheep/components/{shop-categary-tree.vue => node-tree.vue} (53%) diff --git a/src/pages.json b/src/pages.json index 0b406a4..c4b8023 100644 --- a/src/pages.json +++ b/src/pages.json @@ -174,7 +174,7 @@ } }, { - "path": "goods-categary", + "path": "categary-manage", "style": { "navigationBarTitleText": "商品分类管理", "disableScroll": true diff --git a/src/pages/prosperity-shop/goods-categary.vue b/src/pages/prosperity-shop/categary-manage.vue similarity index 68% rename from src/pages/prosperity-shop/goods-categary.vue rename to src/pages/prosperity-shop/categary-manage.vue index 884ee3b..393aea8 100644 --- a/src/pages/prosperity-shop/goods-categary.vue +++ b/src/pages/prosperity-shop/categary-manage.vue @@ -2,19 +2,22 @@ - - {{ item.name }} - {{ item.status == "0" ? "正常" : "禁用" }} - - - 编辑 - 删除 + + + + {{ item.name }} + {{ item.status == "0" ? "正常" : "禁用" }} + + + 编辑 + 删除 + - 新增分类 + 新增分类 父级分类 - - + + 保 存 @@ -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([]) const categaryFormDrawer = ref(false) const form = reactive({ id: "", @@ -74,16 +78,12 @@ const form = reactive({ const categoryTree = ref([]) const selectedNode = ref({}) +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() - } - }, - }) -} diff --git a/src/pages/prosperity-shop/goods-form.vue b/src/pages/prosperity-shop/goods-form.vue index 732ded7..d36c4de 100644 --- a/src/pages/prosperity-shop/goods-form.vue +++ b/src/pages/prosperity-shop/goods-form.vue @@ -74,7 +74,8 @@ 注:图片大小不超过5M - + + @@ -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>/gi, "# $1\n") - .replace(/]*>(.*?)<\/h2>/gi, "## $1\n") - .replace(/]*>(.*?)<\/h3>/gi, "### $1\n") - .replace(/]*>(.*?)<\/h4>/gi, "#### $1\n") - .replace(/]*>(.*?)<\/h5>/gi, "##### $1\n") - .replace(/]*>(.*?)<\/h6>/gi, "###### $1\n") - // 处理段落 - .replace(/]*>(.*?)<\/p>/gi, "$1\n\n") - // 处理换行 - .replace(//gi, "\n") - // 处理粗体 - .replace(/]*>(.*?)<\/strong>/gi, "**$1**") - .replace(/]*>(.*?)<\/b>/gi, "**$1**") - // 处理斜体 - .replace(/]*>(.*?)<\/em>/gi, "*$1*") - .replace(/]*>(.*?)<\/i>/gi, "*$1*") - // 处理下划线 - .replace(/]*>(.*?)<\/u>/gi, "__$1__") - // 处理链接 - .replace(/]*href=["']([^"']*)["'][^>]*>(.*?)<\/a>/gi, "[$2]($1)") - // 处理图片 - 更全面的图片处理 - .replace(/]*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(/]*src=["']([^"']*)["'][^>]*>/gi, (match, src) => { - // 直接使用原始URL,不添加额外前缀 - console.log("HTML图片转换 - 原始:", match) - console.log("HTML图片转换 - src:", src) - return `![图片](${src})` - }) - // 处理列表 - .replace(/]*>(.*?)<\/ul>/gis, (match, content) => { - return content.replace(/]*>(.*?)<\/li>/gi, "- $1\n") - }) - .replace(/]*>(.*?)<\/ol>/gis, (match, content) => { - let index = 1 - return content.replace(/]*>(.*?)<\/li>/gi, () => `${index++}. $1\n`) - }) - // 处理引用 - .replace(/]*>(.*?)<\/blockquote>/gis, (match, content) => { - return content.replace(/\n/g, "\n> ") + "\n" - }) - // 处理代码 - .replace(/]*>(.*?)<\/code>/gi, "`$1`") - .replace(/]*>(.*?)<\/pre>/gis, "```\n$1\n```") - // 处理分割线 - .replace(/]*>/gi, "---\n") - // 处理表格(简单处理) - .replace(/]*>(.*?)<\/table>/gis, (match, content) => { - // 这里可以添加更复杂的表格处理逻辑 - return content.replace(/]*>(.*?)<\/tr>/gi, (trMatch, trContent) => { - const cells = trContent.match(/]*>(.*?)<\/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, "

$1

") - .replace(/^## (.*$)/gim, "

$1

") - .replace(/^### (.*$)/gim, "

$1

") - .replace(/^#### (.*$)/gim, "

$1

") - .replace(/^##### (.*$)/gim, "
$1
") - .replace(/^###### (.*$)/gim, "
$1
") - // 处理粗体 - .replace(/\*\*(.*?)\*\*/g, "$1") - // 处理斜体 - .replace(/\*(.*?)\*/g, "$1") - // 处理链接 - .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1') - // 处理图片 - .replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '$1') - // 处理段落 - .replace(/^(?!<[h1-6]|$1

") - // 处理换行 - .replace(/\n/g, "
") - - 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: "提交中..." }) diff --git a/src/pages/prosperity-shop/goods-manage.vue b/src/pages/prosperity-shop/goods-manage.vue index 00ec454..cdcbf27 100644 --- a/src/pages/prosperity-shop/goods-manage.vue +++ b/src/pages/prosperity-shop/goods-manage.vue @@ -107,8 +107,8 @@
- 新增商品 - 分类管理 + 新增商品 + 分类管理
@@ -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({ 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" }) -} diff --git a/src/sheep/components/shop-categary-picker.vue b/src/sheep/components/shop-categary-picker.vue index 940fc87..8c94128 100644 --- a/src/sheep/components/shop-categary-picker.vue +++ b/src/sheep/components/shop-categary-picker.vue @@ -1,9 +1,9 @@