From 820d8ab76a708fdc1cc1b14f8b23b275a51f7485 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 30 May 2023 10:00:04 +0800 Subject: [PATCH 1/6] =?UTF-8?q?fix:=20pnpm=20=E4=BB=93=E5=BA=93=E4=B8=AD?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=20video.js=208.0.4=20=E8=BF=99=E4=B8=AA?= =?UTF-8?q?=E7=89=88=E6=9C=AC=EF=BC=8C=E6=9B=B4=E6=94=B9=E4=B8=BA=208.3.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7a00c122..3d9bbd75 100644 --- a/package.json +++ b/package.json @@ -62,8 +62,8 @@ "qs": "^6.11.1", "steady-xml": "^0.1.0", "url": "^0.11.0", - "video.js": "^8.0.4", - "vue": "3.2.47", + "video.js": "^8.3.0", + "vue": "3.3.4", "vue-i18n": "9.2.2", "vue-router": "^4.1.6", "vue-types": "^5.0.2", From e555977757f76516638ce2c8fb90eb6a186bc25b Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 30 May 2023 18:14:40 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=20review=20?= =?UTF-8?q?=E6=8F=90=E5=88=B0=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=88=86=E7=B1=BB=E9=80=89=E6=8B=A9=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E3=80=81=E5=AE=8C=E6=95=B4=E5=B1=82=E7=BA=A7?= =?UTF-8?q?=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mall/product/spu.ts | 14 ++-- src/utils/tree.ts | 81 ++++++++++++++++++ src/views/mall/product/spu/addForm.vue | 15 ++-- .../product/spu/components/BasicInfoForm.vue | 59 ++++++++----- .../spu/components/DescriptionForm.vue | 6 +- .../spu/components/OtherSettingsForm.vue | 6 +- .../components/ProductAttributesAddForm.vue | 3 +- .../mall/product/spu/components/SkuList.vue | 58 ++++++++----- src/views/mall/product/spu/index.vue | 84 ++++++++++++++----- 9 files changed, 238 insertions(+), 88 deletions(-) diff --git a/src/api/mall/product/spu.ts b/src/api/mall/product/spu.ts index fd55e126..5555ce10 100644 --- a/src/api/mall/product/spu.ts +++ b/src/api/mall/product/spu.ts @@ -7,8 +7,7 @@ export interface Property { valueName?: string // 属性值名称 } -// TODO puhui999:是不是直接叫 Sku 更简洁一点哈。type 待后面,总感觉有个类型? -export interface SkuType { +export interface Sku { id?: number // 商品 SKU 编号 spuId?: number // SPU 编号 properties?: Property[] // 属性数组 @@ -25,8 +24,7 @@ export interface SkuType { salesCount?: number // 商品销量 } -// TODO puhui999:是不是直接叫 Spu 更简洁一点哈。type 待后面,总感觉有个类型? -export interface SpuType { +export interface Spu { id?: number name?: string // 商品名称 categoryId?: number | null // 商品分类 @@ -39,9 +37,9 @@ export interface SpuType { brandId?: number | null // 商品品牌编号 specType?: boolean // 商品规格 subCommissionType?: boolean // 分销类型 - skus: SkuType[] // sku数组 + skus: Sku[] // sku数组 description?: string // 商品详情 - sort?: string // 商品排序 + sort?: number // 商品排序 giveIntegral?: number // 赠送积分 virtualSalesCount?: number // 虚拟销量 recommendHot?: boolean // 是否热卖 @@ -62,12 +60,12 @@ export const getTabsCount = () => { } // 创建商品 Spu -export const createSpu = (data: SpuType) => { +export const createSpu = (data: Spu) => { return request.post({ url: '/product/spu/create', data }) } // 更新商品 Spu -export const updateSpu = (data: SpuType) => { +export const updateSpu = (data: Spu) => { return request.put({ url: '/product/spu/update', data }) } diff --git a/src/utils/tree.ts b/src/utils/tree.ts index 445adf1b..82b5bc34 100644 --- a/src/utils/tree.ts +++ b/src/utils/tree.ts @@ -3,6 +3,7 @@ interface TreeHelperConfig { children: string pid: string } + const DEFAULT_CONFIG: TreeHelperConfig = { id: 'id', children: 'children', @@ -133,6 +134,7 @@ export const filter = ( ): T[] => { config = getConfig(config) const children = config.children as string + function listFilter(list: T[]) { return list .map((node: any) => ({ ...node })) @@ -141,6 +143,7 @@ export const filter = ( return func(node) || (node[children] && node[children].length) }) } + return listFilter(tree) } @@ -264,6 +267,7 @@ export const handleTree = (data: any[], id?: string, parentId?: string, children } } } + return tree } @@ -302,3 +306,80 @@ export const handleTree2 = (data, id, parentId, children, rootId) => { }) return treeData !== '' ? treeData : data } +/** + * + * @param tree 要操作的树结构数据 + * @param nodeId 需要判断在什么层级的数据 + * @param level 检查的级别, 默认检查到二级 + */ +export const checkSelectedNode = (tree: any[], nodeId, level = 2) => { + if (typeof tree === 'undefined' || !Array.isArray(tree) || tree.length === 0) { + console.warn('tree must be an array') + return false + } + // 校验是否是一级节点 + if (tree.some((item) => item.id === nodeId)) { + return false + } + // 递归计数 + let count = 1 + + // 深层次校验 + function performAThoroughValidation(arr) { + count += 1 + for (const item of arr) { + if (item.id === nodeId) { + return true + } else if (typeof item.children !== 'undefined' && item.children.length !== 0) { + performAThoroughValidation(item.children) + } + } + return false + } + + for (const item of tree) { + count = 1 + if (performAThoroughValidation(item.children)) { + // 找到后对比是否是期望的层级 + if (count >= level) return true + } + } + return false +} +/** + * 获取节点的完整结构 + * @param tree 树数据 + * @param nodeId 节点 id + */ +export const treeToString = (tree: any[], nodeId) => { + if (typeof tree === 'undefined' || !Array.isArray(tree) || tree.length === 0) { + console.warn('tree must be an array') + return '' + } + // 校验是否是一级节点 + const node = tree.find((item) => item.id === nodeId) + if (typeof node !== 'undefined') { + return node.name + } + let str = '' + + function performAThoroughValidation(arr) { + for (const item of arr) { + if (item.id === nodeId) { + str += `/${item.name}` + return true + } else if (typeof item.children !== 'undefined' && item.children.length !== 0) { + performAThoroughValidation(item.children) + } + } + return false + } + + for (const item of tree) { + str = `${item.name}` + if (performAThoroughValidation(item.children)) { + break + } + } + return str +} diff --git a/src/views/mall/product/spu/addForm.vue b/src/views/mall/product/spu/addForm.vue index 18f9d0b6..1ae1a4c2 100644 --- a/src/views/mall/product/spu/addForm.vue +++ b/src/views/mall/product/spu/addForm.vue @@ -51,15 +51,15 @@ const basicInfoRef = ref>() // 商品信息Re const descriptionRef = ref>() // 商品详情Ref const otherSettingsRef = ref>() // 其他设置Ref // spu 表单数据 -const formData = ref({ +const formData = ref({ name: '', // 商品名称 categoryId: null, // 商品分类 keyword: '', // 关键字 unit: null, // 单位 picUrl: '', // 商品封面图 - sliderPicUrls: [], // 商品轮播图 + sliderPicUrls: [''], // 商品轮播图 introduction: '', // 商品简介 - deliveryTemplateId: 1, // 运费模版 + deliveryTemplateId: null, // 运费模版 brandId: null, // 商品品牌 specType: false, // 商品规格 subCommissionType: false, // 分销类型 @@ -94,7 +94,7 @@ const getDetail = async () => { if (id) { formLoading.value = true try { - const res = (await ProductSpuApi.getSpu(id)) as ProductSpuApi.SpuType + const res = (await ProductSpuApi.getSpu(id)) as ProductSpuApi.Spu res.skus.forEach((item) => { // 回显价格分转元 item.price = formatToFraction(item.price) @@ -120,8 +120,9 @@ const submitForm = async () => { await unref(basicInfoRef)?.validate() await unref(descriptionRef)?.validate() await unref(otherSettingsRef)?.validate() - const deepCopyFormData = cloneDeep(unref(formData.value)) // 深拷贝一份 fix:这样最终 server 端不满足,不需要恢复, - // TODO 兜底处理 sku 空数据 + // 深拷贝一份, 这样最终 server 端不满足,不需要恢复, + const deepCopyFormData = cloneDeep(unref(formData.value)) + // 兜底处理 sku 空数据 formData.value.skus.forEach((sku) => { // 因为是空数据这里判断一下商品条码是否为空就行 if (sku.barCode === '') { @@ -150,7 +151,7 @@ const submitForm = async () => { }) deepCopyFormData.sliderPicUrls = newSliderPicUrls // 校验都通过后提交表单 - const data = deepCopyFormData as ProductSpuApi.SpuType + const data = deepCopyFormData as ProductSpuApi.Spu const id = params.spuId as number if (!id) { await ProductSpuApi.createSpu(data) diff --git a/src/views/mall/product/spu/components/BasicInfoForm.vue b/src/views/mall/product/spu/components/BasicInfoForm.vue index d800e332..60fc7c69 100644 --- a/src/views/mall/product/spu/components/BasicInfoForm.vue +++ b/src/views/mall/product/spu/components/BasicInfoForm.vue @@ -7,7 +7,7 @@ - + @@ -119,9 +120,9 @@ import { PropType } from 'vue' import { copyValueToTarget } from '@/utils' import { propTypes } from '@/utils/propTypes' -import { defaultProps, handleTree } from '@/utils/tree' +import { checkSelectedNode, defaultProps, handleTree } from '@/utils/tree' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' -import type { SpuType } from '@/api/mall/product/spu' +import type { Spu } from '@/api/mall/product/spu' import { UploadImg, UploadImgs } from '@/components/UploadFile' import { ProductAttributes, ProductAttributesAddForm, SkuList } from './index' import * as ProductCategoryApi from '@/api/mall/product/category' @@ -131,7 +132,7 @@ const message = useMessage() // 消息弹窗 const props = defineProps({ propFormData: { - type: Object as PropType, + type: Object as PropType, default: () => {} }, activeName: propTypes.string.def('') @@ -144,7 +145,7 @@ const skuListRef = ref() // 商品属性列表Ref const generateSkus = (propertyList) => { skuListRef.value.generateTableData(propertyList) } -const formData = reactive({ +const formData = reactive({ name: '', // 商品名称 categoryId: null, // 商品分类 keyword: '', // 关键字 @@ -185,26 +186,24 @@ watch( formData.sliderPicUrls = data['sliderPicUrls'].map((item) => ({ url: item })) - // TODO @puhui999:if return,减少嵌套层级 // 只有是多规格才处理 - if (formData.specType) { - // 直接拿返回的 skus 属性逆向生成出 propertyList - const properties = [] - formData.skus.forEach((sku) => { - sku.properties.forEach(({ propertyId, propertyName, valueId, valueName }) => { - // 添加属性 - if (!properties.some((item) => item.id === propertyId)) { - properties.push({ id: propertyId, name: propertyName, values: [] }) - } - // 添加属性值 - const index = properties.findIndex((item) => item.id === propertyId) - if (!properties[index].values.some((value) => value.id === valueId)) { - properties[index].values.push({ id: valueId, name: valueName }) - } - }) + if (!formData.specType) return + // 直接拿返回的 skus 属性逆向生成出 propertyList + const properties = [] + formData.skus.forEach((sku) => { + sku.properties.forEach(({ propertyId, propertyName, valueId, valueName }) => { + // 添加属性 + if (!properties.some((item) => item.id === propertyId)) { + properties.push({ id: propertyId, name: propertyName, values: [] }) + } + // 添加属性值 + const index = properties.findIndex((item) => item.id === propertyId) + if (!properties[index].values.some((value) => value.id === valueId)) { + properties[index].values.push({ id: valueId, name: valueName }) + } }) - propertyList.value = properties - } + }) + propertyList.value = properties }, { immediate: true @@ -216,6 +215,11 @@ watch( */ const emit = defineEmits(['update:activeName']) const validate = async () => { + // 校验 sku + if (!skuListRef.value.validateSku()) { + message.warning('商品相关价格不能低于0.01元!!') + throw new Error('商品相关价格不能低于0.01元!!') + } // 校验表单 if (!productSpuBasicInfoRef) return return await unref(productSpuBasicInfoRef).validate((valid) => { @@ -263,6 +267,15 @@ const onChangeSpec = () => { } const categoryList = ref([]) // 分类树 +/** + * 选择分类时触发校验 + */ +const nodeClick = () => { + if (!checkSelectedNode(categoryList.value, formData.categoryId)) { + formData.categoryId = null + message.warning('必须选择二级节点!!') + } +} const brandList = ref([]) // 精简商品品牌列表 onMounted(async () => { // 获得分类树 diff --git a/src/views/mall/product/spu/components/DescriptionForm.vue b/src/views/mall/product/spu/components/DescriptionForm.vue index fbae9a86..23a3e99a 100644 --- a/src/views/mall/product/spu/components/DescriptionForm.vue +++ b/src/views/mall/product/spu/components/DescriptionForm.vue @@ -7,7 +7,7 @@ diff --git a/src/views/mall/product/spu/index.vue b/src/views/mall/product/spu/index.vue index 539171b0..34719775 100644 --- a/src/views/mall/product/spu/index.vue +++ b/src/views/mall/product/spu/index.vue @@ -8,18 +8,16 @@ class="-mb-15px" label-width="68px" > - - + - - + @@ -80,31 +79,60 @@ /> - +虚拟销量:999 --> @@ -202,7 +230,7 @@ import { TabsPaneContext } from 'element-plus' import { cloneDeep } from 'lodash-es' import { createImageViewer } from '@/components/ImageViewer' import { dateFormatter } from '@/utils/formatTime' -import { defaultProps, handleTree } from '@/utils/tree' +import { checkSelectedNode, defaultProps, handleTree, treeToString } from '@/utils/tree' import { ProductSpuStatusEnum } from '@/utils/constants' import { formatToFraction } from '@/utils' import download from '@/utils/download' @@ -391,7 +419,7 @@ const handleExport = async () => { } } -// 监听路由变化更新列表 TODO @puhui999:这个是必须加的么?fix: 因为编辑表单是以路由的方式打开,保存表单后列表不会刷新 +// 监听路由变化更新列表,解决商品保存后,列表不刷新的问题。 watch( () => currentRoute.value, () => { @@ -400,6 +428,22 @@ watch( ) const categoryList = ref() // 分类树 +/** + * 获取分类的节点的完整结构 + * @param categoryId 分类id + */ +const categoryString = (categoryId) => { + return treeToString(categoryList.value, categoryId) +} +/** + * 校验所选是否为二级节点 + */ +const nodeClick = () => { + if (!checkSelectedNode(categoryList.value, queryParams.value.categoryId)) { + queryParams.value.categoryId = null + message.warning('必须选择二级节点!!') + } +} /** 初始化 **/ onMounted(async () => { await getTabsCount() From 39c92cb944e2b41007d1870d411f5255c9da1d70 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 31 May 2023 14:42:45 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=20SPU=20=E6=9F=A5?= =?UTF-8?q?=E7=9C=8B=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mall/product/spu.ts | 2 +- src/router/modules/remaining.ts | 13 +++ src/utils/tree.ts | 21 +++- src/views/mall/product/spu/addForm.vue | 12 +- .../product/spu/components/BasicInfoForm.vue | 80 ++++++++++++- .../spu/components/DescriptionForm.vue | 25 ++++- .../spu/components/OtherSettingsForm.vue | 37 +++++- .../mall/product/spu/components/SkuList.vue | 106 ++++++++++++++++-- .../mall/product/spu/components/spu.data.ts | 105 +++++++++++++++++ src/views/mall/product/spu/index.vue | 23 ++-- 10 files changed, 387 insertions(+), 37 deletions(-) create mode 100644 src/views/mall/product/spu/components/spu.data.ts diff --git a/src/api/mall/product/spu.ts b/src/api/mall/product/spu.ts index 5555ce10..e0d4ec83 100644 --- a/src/api/mall/product/spu.ts +++ b/src/api/mall/product/spu.ts @@ -37,7 +37,7 @@ export interface Spu { brandId?: number | null // 商品品牌编号 specType?: boolean // 商品规格 subCommissionType?: boolean // 分销类型 - skus: Sku[] // sku数组 + skus?: Sku[] // sku数组 description?: string // 商品详情 sort?: number // 商品排序 giveIntegral?: number // 赠送积分 diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index e530c410..f7e56fd0 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -379,6 +379,19 @@ const remainingRouter: AppRouteRecordRaw[] = [ title: '编辑商品', activeMenu: '/product/product-spu' } + }, + { + path: 'productSpuDetail/:spuId(\\d+)', + component: () => import('@/views/mall/product/spu/addForm.vue'), + name: 'productSpuDetail', + meta: { + noCache: true, + hidden: true, + canTo: true, + icon: 'ep:view', + title: '商品详情', + activeMenu: '/product/product-spu' + } } ] } diff --git a/src/utils/tree.ts b/src/utils/tree.ts index 82b5bc34..65a9345c 100644 --- a/src/utils/tree.ts +++ b/src/utils/tree.ts @@ -312,26 +312,30 @@ export const handleTree2 = (data, id, parentId, children, rootId) => { * @param nodeId 需要判断在什么层级的数据 * @param level 检查的级别, 默认检查到二级 */ -export const checkSelectedNode = (tree: any[], nodeId, level = 2) => { +export const checkSelectedNode = (tree: any[], nodeId: any, level = 2): boolean => { if (typeof tree === 'undefined' || !Array.isArray(tree) || tree.length === 0) { console.warn('tree must be an array') return false } + // 校验是否是一级节点 if (tree.some((item) => item.id === nodeId)) { return false } + // 递归计数 let count = 1 // 深层次校验 - function performAThoroughValidation(arr) { + function performAThoroughValidation(arr: any[]): boolean { count += 1 for (const item of arr) { if (item.id === nodeId) { return true } else if (typeof item.children !== 'undefined' && item.children.length !== 0) { - performAThoroughValidation(item.children) + if (performAThoroughValidation(item.children)) { + return true + } } } return false @@ -341,11 +345,15 @@ export const checkSelectedNode = (tree: any[], nodeId, level = 2) => { count = 1 if (performAThoroughValidation(item.children)) { // 找到后对比是否是期望的层级 - if (count >= level) return true + if (count >= level) { + return true + } } } + return false } + /** * 获取节点的完整结构 * @param tree 树数据 @@ -369,7 +377,10 @@ export const treeToString = (tree: any[], nodeId) => { str += `/${item.name}` return true } else if (typeof item.children !== 'undefined' && item.children.length !== 0) { - performAThoroughValidation(item.children) + str += `/${item.name}` + if (performAThoroughValidation(item.children)) { + return true + } } } return false diff --git a/src/views/mall/product/spu/addForm.vue b/src/views/mall/product/spu/addForm.vue index 1ae1a4c2..737b5e17 100644 --- a/src/views/mall/product/spu/addForm.vue +++ b/src/views/mall/product/spu/addForm.vue @@ -5,6 +5,7 @@ @@ -12,6 +13,7 @@ @@ -19,6 +21,7 @@ @@ -42,11 +45,12 @@ import { convertToInteger, formatToFraction } from '@/utils' const { t } = useI18n() // 国际化 const message = useMessage() // 消息弹窗 const { push, currentRoute } = useRouter() // 路由 -const { params } = useRoute() // 查询参数 +const { params, name } = useRoute() // 查询参数 const { delView } = useTagsViewStore() // 视图操作 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用 const activeName = ref('basicInfo') // Tag 激活的窗口 +const isDetail = ref(false) // 是否查看详情 const basicInfoRef = ref>() // 商品信息Ref const descriptionRef = ref>() // 商品详情Ref const otherSettingsRef = ref>() // 其他设置Ref @@ -90,12 +94,13 @@ const formData = ref({ /** 获得详情 */ const getDetail = async () => { + console.log(name) const id = params.spuId as number if (id) { formLoading.value = true try { const res = (await ProductSpuApi.getSpu(id)) as ProductSpuApi.Spu - res.skus.forEach((item) => { + res.skus!.forEach((item) => { // 回显价格分转元 item.price = formatToFraction(item.price) item.marketPrice = formatToFraction(item.marketPrice) @@ -123,7 +128,7 @@ const submitForm = async () => { // 深拷贝一份, 这样最终 server 端不满足,不需要恢复, const deepCopyFormData = cloneDeep(unref(formData.value)) // 兜底处理 sku 空数据 - formData.value.skus.forEach((sku) => { + formData.value.skus!.forEach((sku) => { // 因为是空数据这里判断一下商品条码是否为空就行 if (sku.barCode === '') { const index = deepCopyFormData.skus.findIndex( @@ -171,7 +176,6 @@ const close = () => { delView(unref(currentRoute)) push('/product/product-spu') } - /** 初始化 */ onMounted(async () => { await getDetail() diff --git a/src/views/mall/product/spu/components/BasicInfoForm.vue b/src/views/mall/product/spu/components/BasicInfoForm.vue index 60fc7c69..2cc5a7c2 100644 --- a/src/views/mall/product/spu/components/BasicInfoForm.vue +++ b/src/views/mall/product/spu/components/BasicInfoForm.vue @@ -1,5 +1,11 @@ diff --git a/src/views/mall/product/spu/index.vue b/src/views/mall/product/spu/index.vue index f3e0476b..47a9c8d5 100644 --- a/src/views/mall/product/spu/index.vue +++ b/src/views/mall/product/spu/index.vue @@ -408,7 +408,7 @@ const openForm = (id?: number) => { * 查看商品详情 */ const openDetail = (id?: number) => { - push('/product/productSpuDetail' + id) + push('/product/productSpuDetail/' + id) } /** 导出按钮操作 */ From 6a10a81f58f055eede23e2126938f6ae37909b6e Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 31 May 2023 15:58:35 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=E5=BC=95=E5=85=A5=20v-dompurify-htm?= =?UTF-8?q?l=20=E6=8C=87=E4=BB=A4=E8=A7=A3=E5=86=B3=20v-html=20=E7=9A=84?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E9=9A=90=E6=82=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.dev | 4 ++-- package.json | 1 + src/components/Form/src/Form.vue | 16 ++++++++-------- src/main.ts | 5 ++++- src/views/infra/build/index.vue | 8 ++++---- src/views/infra/codegen/PreviewCode.vue | 2 +- .../product/spu/components/DescriptionForm.vue | 2 +- src/views/system/mail/log/MailLogDetail.vue | 2 +- 8 files changed, 22 insertions(+), 18 deletions(-) diff --git a/.env.dev b/.env.dev index a52eec30..9249ced8 100644 --- a/.env.dev +++ b/.env.dev @@ -19,13 +19,13 @@ VITE_API_URL=/admin-api VITE_BASE_PATH=/ # 是否删除debugger -VITE_DROP_DEBUGGER=false +VITE_DROP_DEBUGGER=true # 是否删除console.log VITE_DROP_CONSOLE=false # 是否sourcemap -VITE_SOURCEMAP=true +VITE_SOURCEMAP=false # 输出路径 VITE_OUT_DIR=dist-dev diff --git a/package.json b/package.json index 3d9bbd75..8cdf9380 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "url": "^0.11.0", "video.js": "^8.3.0", "vue": "3.3.4", + "vue-dompurify-html": "^4.1.4", "vue-i18n": "9.2.2", "vue-router": "^4.1.6", "vue-types": "^5.0.2", diff --git a/src/components/Form/src/Form.vue b/src/components/Form/src/Form.vue index c1121641..3dca6c94 100644 --- a/src/components/Form/src/Form.vue +++ b/src/components/Form/src/Form.vue @@ -1,16 +1,16 @@