Merge branch 'master' of https://gitea.zianxin.com/zax/biz-mobile-react-cloud
# Conflicts: # src/pages/tabbar/integrated.vue
This commit is contained in:
commit
91e77c8232
18 files changed
+269
-330
No files matched your search
+1
-1
@@ -107,7 +107,7 @@ const tabbar: TabbarItem[] = [
|
||||
iconPath: "/static/tabbar/integrated.png",
|
||||
selectedIconPath: "/static/tabbar/integrated-select.png",
|
||||
launchParam: ["integrated"],
|
||||
auth: [],
|
||||
auth: ["user"],
|
||||
},
|
||||
{
|
||||
pagePath: "pages/tabbar/my",
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "goods-categary",
|
||||
"path": "categary-manage",
|
||||
"style": {
|
||||
"navigationBarTitleText": "商品分类管理",
|
||||
"disableScroll": true
|
||||
|
||||
@@ -79,21 +79,22 @@ const doSubmit = async () => {
|
||||
<template>
|
||||
<crud-layout :title="state.detailId ? '修改人脸' : '人脸上传'" bg="/static/page/blue-bg.png">
|
||||
<view class="h-30rpx" />
|
||||
<view class="card p-x-30rpx p-y-40rpx">
|
||||
<view class="card px-30rpx py-40rpx">
|
||||
<tm-form ref="applyFormRef" v-model="applyForm" :rules="applyFormRules" direction="vertical">
|
||||
<tm-form-item name="faceImg" label="人脸图片" :required="false" :showBottom="false">
|
||||
<view class="h-10rpx" />
|
||||
<tm-upload-photo
|
||||
:maxFileSize="1024 * 1024"
|
||||
:maxFileSize="1024 * 1024 * 5"
|
||||
:header="state.header"
|
||||
:rangUrl="applyForm.faceImg[0]"
|
||||
:beforeComplete="beforeComplete"
|
||||
v-model="applyForm.faceImg"
|
||||
:maxCount="1"
|
||||
:column="2"
|
||||
img-height="320"
|
||||
:url="'/api/admin/sys-file/upload'"
|
||||
/>
|
||||
</tm-form-item>
|
||||
<view class="sub-text-20 c-red!">注:图片大小不超过1M</view>
|
||||
<view class="sub-text-20 c-red!">注:图片大小不超过5M</view>
|
||||
</tm-form>
|
||||
</view>
|
||||
<view
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app"
|
||||
import { onShow } from "@dcloudio/uni-app"
|
||||
|
||||
import { hooks, router } from "@@/index"
|
||||
import { faceApi } from "@@/api"
|
||||
@@ -19,7 +19,6 @@ const query = (page: number, pagesize: number) => {
|
||||
pageHook.startPage(page, pagesize, false, state.pa)
|
||||
}
|
||||
|
||||
onLoad(() => {})
|
||||
onShow(() => {
|
||||
if (pageRef.value) {
|
||||
pageRef.value.reload(false)
|
||||
@@ -64,27 +63,25 @@ const doDel = (id: string) => {
|
||||
@scroll="pageHook.scroll"
|
||||
>
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-col card p-x-20rpx p-y-30rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="v.id">
|
||||
<view class="flex items-center justify-between second-text-26">
|
||||
<div class="flex items-center">
|
||||
<image mode="aspectFill" class="w-100rpx h-100rpx rounded-50rpx" :src="filePath(v.faceImg)" />
|
||||
<view class="w-30rpx" />
|
||||
<text class="font-600">{{ v.username }}</text>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<!-- <text class="botder_btn" @click="doEdit(v.id)">修改</text> -->
|
||||
<view class="w-30rpx" />
|
||||
<tm-modal v-if="false" title="确定删除吗?" height="auto" @confirm="doDel(v.id)">
|
||||
<template v-slot:trigger><text class="botder_btn">删除</text></template>
|
||||
</tm-modal>
|
||||
</div>
|
||||
<view class="card flex-col-center p-20rpx mb-20rpx" v-for="(v, i) in pageHook.list" :key="v.id">
|
||||
<image
|
||||
class="w-300rpx h-300rpx rounded-50rpx mb-2"
|
||||
:src="filePath(v.faceImg)"
|
||||
mode="aspectFill"
|
||||
@click.stop="hooks.usePreviewImage(filePath(v.faceImg))"
|
||||
/>
|
||||
<view class="sub-text-30 mb-2">{{ v.username }}·{{ v.deptName }}</view>
|
||||
<view v-if="false" class="flex w-full items-center justify-end gap-2 second-text-26">
|
||||
<text class="botder_btn" @click="doEdit(v.id)">修改</text>
|
||||
<tm-modal title="确定删除吗?" height="auto" @confirm="doDel(v.id)">
|
||||
<template v-slot:trigger><text class="botder_btn">删除</text></template>
|
||||
</tm-modal>
|
||||
</view>
|
||||
</view>
|
||||
<template #bottom>
|
||||
<view v-if="false" class="bg-#0094ff p-y-20rpx text-center rounded-40rpx m-x-30rpx m-t-60rpx sub-text-30 color-white!" @tap="doAdd">
|
||||
<view v-if="false" class="bg-#0094ff py-20rpx text-center rounded-40rpx mx-30rpx my-4 sub-text-30 color-white!" @tap="doAdd">
|
||||
添加
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
</template>
|
||||
</z-paging>
|
||||
</crud-layout>
|
||||
|
||||
@@ -7,60 +7,60 @@
|
||||
</tm-alert>
|
||||
<tm-sheet :margin="[0, 20]" class="second-text-30">
|
||||
<tm-text class="prefix_title" font-size="32">访客信息</tm-text>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>访客姓名:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">访客姓名</text>
|
||||
<text>{{ detail.name }}</text>
|
||||
</view>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>访客手机号:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">访客手机号</text>
|
||||
<text>{{ detail.mobile }}</text>
|
||||
</view>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>来访公司名称:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">来访公司名称</text>
|
||||
<text>{{ detail.companyName }}</text>
|
||||
</view>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>来访原因:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">来访原因</text>
|
||||
<text>{{ visitorReasonList.find((item) => item.id == detail.reasonValue)?.title || "" }}</text>
|
||||
</view>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>接待人:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">接待人</text>
|
||||
<text>{{ detail.userName }}</text>
|
||||
</view>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>来访人数:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">来访人数</text>
|
||||
<text>{{ detail.peopleNumber }}</text>
|
||||
</view>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>是否可随行人员:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">是否可随行人员</text>
|
||||
<text>{{ detail.isOtherPeople == "1" ? "是" : "否" }}</text>
|
||||
</view>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>是否可驾驶车辆:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">是否可驾驶车辆</text>
|
||||
<text>{{ detail.isDrive == "1" ? "是" : "否" }}</text>
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<tm-sheet :margin="[0, 20]" class="second-text-30">
|
||||
<tm-text class="prefix_title" font-size="32">时间</tm-text>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>预计来访时间:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">预计来访时间</text>
|
||||
<text>{{ detail.vendDate }}</text>
|
||||
</view>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>预计离开时间:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">预计离开时间</text>
|
||||
<text>{{ detail.vstartDate }}</text>
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
<tm-sheet :margin="[0, 20]" class="second-text-30">
|
||||
<tm-text class="prefix_title" font-size="32">其他</tm-text>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>创建方式:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">创建方式</text>
|
||||
<text>{{ detail.type == "1" ? "主动申请" : detail.type == "2" ? "邀约" : "后台创建" }}</text>
|
||||
</view>
|
||||
<view class="flex justify-between mt-1">
|
||||
<text>提交时间:</text>
|
||||
<view class="flex mt-1">
|
||||
<text class="w-220rpx mr-6">提交时间</text>
|
||||
<text>{{ detail.createTime }}</text>
|
||||
</view>
|
||||
</tm-sheet>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll bg="/static/page/blue-bg.png">
|
||||
<view class="h-20rpx" />
|
||||
<tm-sheet margin="[0]">
|
||||
<view class="mx-auto mb-1 text-center text-lg">访客邀约</view>
|
||||
<tm-sheet :margin="[0]">
|
||||
<tm-alert :border="['2']" :borderColor="['#89c0ff']" :darkBorderColor="['#3b5066']">访客邀约请填写以下信息</tm-alert>
|
||||
<tm-form @submit="onsubmit" v-model="form" :rules="rules" direction="vertical">
|
||||
<!-- <tm-form-item name="name" label="访客姓名">
|
||||
@@ -70,7 +69,7 @@
|
||||
<tm-form-item name="isDrive" label="是否可驾驶车辆" direction="horizontal" labelWidth="500">
|
||||
<tm-switch v-model="form.isDrive" />
|
||||
</tm-form-item>
|
||||
<tm-button form-type="submit" block>提交</tm-button>
|
||||
<tm-button class="mt-4" form-type="submit" block>提交</tm-button>
|
||||
</tm-form>
|
||||
</tm-sheet>
|
||||
|
||||
|
||||
+41
-41
@@ -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,9 +50,20 @@
|
||||
</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>
|
||||
<view class="prefix_title mb-2">分类图</view>
|
||||
<tm-upload-photo
|
||||
v-model="form.picUrl"
|
||||
:maxFileSize="1024 * 1024 * 5"
|
||||
:url="'/api/admin/sys-file/upload'"
|
||||
:header="hooks.useDefaultHeader()"
|
||||
:column="1.6"
|
||||
img-height="360"
|
||||
:max-count="1"
|
||||
/>
|
||||
<view class="sub-text-20 c-red! mb-2">注:图片大小不超过5M</view>
|
||||
<tm-button form-type="submit" block>保 存</tm-button>
|
||||
</tm-form>
|
||||
</view>
|
||||
@@ -61,29 +75,28 @@
|
||||
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 { hooks } from "@@/index"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
|
||||
const categoryList = ref<any>([])
|
||||
const categaryFormDrawer = ref(false)
|
||||
const form = reactive({
|
||||
const form = reactive<any>({
|
||||
id: "",
|
||||
name: "",
|
||||
status: "0", // 状态(0正常,1下架)
|
||||
parentId: "",
|
||||
picUrl: [],
|
||||
})
|
||||
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" })
|
||||
@@ -98,6 +111,7 @@ const addCategary = () => {
|
||||
name: "",
|
||||
status: "0",
|
||||
parentId: "",
|
||||
picUrl: [],
|
||||
})
|
||||
selectedNode.value = {}
|
||||
categaryFormDrawer.value = true
|
||||
@@ -106,7 +120,8 @@ const addCategary = () => {
|
||||
// 编辑分类
|
||||
const editCategary = (item) => {
|
||||
getCategaryTree()
|
||||
Object.assign(form, item)
|
||||
const picUrl = [{ path: filePath(item.picUrl), response: JSON.stringify({ data: { url: item.picUrl } }) }]
|
||||
Object.assign(form, { ...item, picUrl })
|
||||
selectedNode.value = { id: item.parentId }
|
||||
categaryFormDrawer.value = true
|
||||
}
|
||||
@@ -114,9 +129,13 @@ 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 }
|
||||
const params = {
|
||||
...form,
|
||||
parentId: selectedNode.value.id,
|
||||
picUrl: JSON.parse(form.picUrl[0].response).data.url,
|
||||
}
|
||||
uni.showLoading({ title: "保存中..." })
|
||||
const { code, msg } = await (form.id ? prosperityShopApi.editCategary(params) : prosperityShopApi.addCategary(params))
|
||||
if (code != 0) return uni.showToast({ title: msg || "保存失败", icon: "none" })
|
||||
@@ -127,23 +146,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>
|
||||
@@ -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 ``
|
||||
})
|
||||
.replace(/<img[^>]*src=["']([^"']*)["'][^>]*>/gi, (match, src) => {
|
||||
// 直接使用原始URL,不添加额外前缀
|
||||
console.log("HTML图片转换 - 原始:", match)
|
||||
console.log("HTML图片转换 - src:", src)
|
||||
return ``
|
||||
})
|
||||
// 处理列表
|
||||
.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: "提交中..." })
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
@@ -95,6 +95,16 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
function goPage(item) {
|
||||
// 访客邀约功能正在开发中
|
||||
if (item.name === 'visitor') {
|
||||
uni.showToast({
|
||||
title: '访客邀约功能正在开发中',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (item.url) {
|
||||
uni.navigateTo({ url: item.url })
|
||||
}
|
||||
|
||||
@@ -84,8 +84,8 @@ const state = reactive<{
|
||||
userInfo: {},
|
||||
menuList: [
|
||||
{ text: "扫一扫", icon: "/static/icon/scan.png", router: "" },
|
||||
{ text: "钱包管理", icon: "/static/icon/service_3.png", router: "/pages/wallet/list" },
|
||||
{ text: "人脸管理", icon: "/static/icon/service_5.png", router: "/pages/human-face/list" },
|
||||
{ text: "我的钱包", icon: "/static/icon/service_3.png", router: "/pages/wallet/list" },
|
||||
{ text: "我的人脸", icon: "/static/icon/service_5.png", router: "/pages/human-face/list" },
|
||||
// { text: "车辆管理", icon: "/static/icon/service_6.png", router: "/pages/car/userCar/list" },
|
||||
{ text: "清除缓存", icon: "/static/icon/clear-storage.png", router: "" },
|
||||
],
|
||||
@@ -426,14 +426,14 @@ onLoad(async () => {
|
||||
|
||||
await userApi.userRole()
|
||||
|
||||
await isMerchant()
|
||||
await isMallMchUser()
|
||||
|
||||
// 获取存储中的用户信息
|
||||
storage.getUserInfo()
|
||||
})
|
||||
|
||||
const isMerchant = async () => {
|
||||
const { data } = await userApi.isMerchant()
|
||||
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" })
|
||||
}
|
||||
|
||||
@@ -60,12 +60,18 @@ export default {
|
||||
},
|
||||
})
|
||||
},
|
||||
// 判断是否是商户角色
|
||||
// 判断是否是合作商家商户角色
|
||||
isMerchant: (): Promise<any> =>
|
||||
request({
|
||||
url: "/admin/role/isMchUser",
|
||||
method: "GET",
|
||||
}),
|
||||
// 判断是否是共富商城商户角色
|
||||
isMallMchUser: (): Promise<any> =>
|
||||
request({
|
||||
url: "/admin/role/isMallMchUser",
|
||||
method: "GET",
|
||||
}),
|
||||
// 判断用户移动端角色
|
||||
userRole: () =>
|
||||
request({
|
||||
|
||||
@@ -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>
|
||||
|
||||
<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>
|
||||
Reference in new issue
Block a user