jgy-public-component 0.0.21 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -0
- package/dist/components/JProductDetail/JProductDetailDialog.d.ts +41 -0
- package/dist/components/JProductDetail/JSkuLink.d.ts +36 -0
- package/dist/components/JProductDetail/index.d.ts +4 -0
- package/dist/components/JProductDetail/types.d.ts +38 -0
- package/dist/components/JProductDetail/useProductDetailDialog.d.ts +16 -0
- package/dist/components/JSearchInputDialog/JSearchInputDialog.d.ts +112 -0
- package/dist/components/JSearchInputDialog/index.d.ts +2 -0
- package/dist/components/JSearchInputDialog/types.d.ts +33 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +1979 -634
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +2 -1
- package/dist/index.umd.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/components/JButton/JButton.vue","../src/components/JUploadImg/JUploadImg.vue","../src/components/JIconRender/JIconRender.vue","../src/components/JSearchHeader/JSearchHeader.vue","../src/components/JImportExcel/JImportExcel.vue","../src/components/JSidebar/JSideMenuItem.vue","../src/components/JSidebar/JSidebar.vue","../src/components/JAdminLayout/JAdminLayout.vue","../src/utils/transform.ts","../src/router/helpers.ts","../src/router/guards.ts","../src/index.ts"],"sourcesContent":["<template>\r\n <button\r\n class=\"j-button\"\r\n :class=\"[\r\n `j-button--${type}`,\r\n `j-button--${size}`,\r\n {\r\n 'j-button--plain': plain,\r\n 'j-button--round': round,\r\n 'j-button--disabled': disabled,\r\n 'j-button--loading': loading,\r\n },\r\n ]\"\r\n :disabled=\"disabled || loading\"\r\n @click=\"handleClick\"\r\n >\r\n <span v-if=\"loading\" class=\"j-button__loading-icon\" />\r\n <span v-if=\"$slots.default\" class=\"j-button__text\">\r\n <slot />\r\n </span>\r\n </button>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport type { ButtonType, ButtonSize } from './types'\r\n\r\ninterface Props {\r\n type?: ButtonType\r\n size?: ButtonSize\r\n plain?: boolean\r\n round?: boolean\r\n disabled?: boolean\r\n loading?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n type: 'default',\r\n size: 'medium',\r\n plain: false,\r\n round: false,\r\n disabled: false,\r\n loading: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n click: [event: MouseEvent]\r\n}>()\r\n\r\nfunction handleClick(event: MouseEvent) {\r\n if (!props.disabled && !props.loading) {\r\n emit('click', event)\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.j-button {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: $spacing-xs;\r\n padding: 8px 16px;\r\n font-size: $font-size-base;\r\n font-weight: 400;\r\n line-height: 1;\r\n white-space: nowrap;\r\n cursor: pointer;\r\n border: 1px solid $color-border;\r\n border-radius: $border-radius-base;\r\n background-color: $color-white;\r\n color: $color-text-regular;\r\n transition: $transition-fast;\r\n outline: none;\r\n user-select: none;\r\n\r\n &:hover {\r\n color: $color-primary;\r\n border-color: $color-primary;\r\n background-color: color.adjust($color-primary, $lightness: 40%);\r\n }\r\n\r\n // 尺寸\r\n &--small {\r\n padding: 5px 12px;\r\n font-size: $font-size-xs;\r\n }\r\n\r\n &--medium {\r\n padding: 8px 16px;\r\n font-size: $font-size-base;\r\n }\r\n\r\n &--large {\r\n padding: 12px 20px;\r\n font-size: $font-size-md;\r\n }\r\n\r\n // 类型\r\n &--primary {\r\n background-color: $color-primary;\r\n border-color: $color-primary;\r\n color: $color-white;\r\n &:hover {\r\n background-color: color.adjust($color-primary, $lightness: 10%);\r\n border-color: color.adjust($color-primary, $lightness: 10%);\r\n color: $color-white;\r\n }\r\n }\r\n\r\n &--success {\r\n background-color: $color-success;\r\n border-color: $color-success;\r\n color: $color-white;\r\n &:hover {\r\n background-color: color.adjust($color-success, $lightness: 10%);\r\n border-color: color.adjust($color-success, $lightness: 10%);\r\n color: $color-white;\r\n }\r\n }\r\n\r\n &--danger {\r\n background-color: $color-danger;\r\n border-color: $color-danger;\r\n color: $color-white;\r\n &:hover {\r\n background-color: color.adjust($color-danger, $lightness: 10%);\r\n border-color: color.adjust($color-danger, $lightness: 10%);\r\n color: $color-white;\r\n }\r\n }\r\n\r\n &--warning {\r\n background-color: $color-warning;\r\n border-color: $color-warning;\r\n color: $color-white;\r\n &:hover {\r\n background-color: color.adjust($color-warning, $lightness: 10%);\r\n border-color: color.adjust($color-warning, $lightness: 10%);\r\n color: $color-white;\r\n }\r\n }\r\n\r\n // 朴素按钮\r\n &--plain {\r\n &.j-button--primary {\r\n background-color: color.adjust($color-primary, $lightness: 40%);\r\n color: $color-primary;\r\n &:hover {\r\n background-color: $color-primary;\r\n color: $color-white;\r\n }\r\n }\r\n }\r\n\r\n // 圆角\r\n &--round {\r\n border-radius: $border-radius-round;\r\n }\r\n\r\n // 禁用\r\n &--disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n pointer-events: none;\r\n }\r\n\r\n // 加载\r\n &--loading {\r\n opacity: 0.7;\r\n cursor: not-allowed;\r\n pointer-events: none;\r\n }\r\n\r\n &__loading-icon {\r\n display: inline-block;\r\n width: 14px;\r\n height: 14px;\r\n border: 2px solid currentColor;\r\n border-top-color: transparent;\r\n border-radius: 50%;\r\n animation: j-spin 0.6s linear infinite;\r\n }\r\n\r\n @keyframes j-spin {\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n }\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"j-upload-img-container\">\r\n <!-- 多图模式 -->\r\n <template v-if=\"multiple\">\r\n <div class=\"images-wrapper\">\r\n <draggable\r\n v-model=\"imageList\"\r\n class=\"images-list\"\r\n item-key=\"uid\"\r\n :animation=\"200\"\r\n :disabled=\"disabled\"\r\n @end=\"handleDragEnd\"\r\n >\r\n <template #item=\"{ element, index }\">\r\n <div class=\"image-item\">\r\n <el-image\r\n :src=\"element.url\"\r\n :preview-src-list=\"imageList.map(img => img.url)\"\r\n :initial-index=\"index\"\r\n fit=\"cover\"\r\n class=\"image-preview\"\r\n :preview-teleported=\"true\"\r\n :hide-on-click-modal=\"true\"\r\n />\r\n <div v-if=\"!disabled\" class=\"delete-btn\" @click.stop=\"handleRemove(index)\">\r\n <el-icon class=\"icon-delete\">\r\n <Delete />\r\n </el-icon>\r\n </div>\r\n </div>\r\n </template>\r\n </draggable>\r\n\r\n <!-- 多图上传按钮 -->\r\n <el-upload\r\n v-if=\"!disabled && (!limit || imageList.length < limit)\"\r\n class=\"image-uploader\"\r\n :auto-upload=\"false\"\r\n :show-file-list=\"false\"\r\n :on-change=\"handleFileChange\"\r\n :disabled=\"uploading\"\r\n list-type=\"picture-card\"\r\n :accept=\"accept\"\r\n >\r\n <el-icon v-if=\"!uploading\" class=\"uploader-icon\">\r\n <Plus />\r\n </el-icon>\r\n <el-icon v-else class=\"uploader-icon is-loading\">\r\n <Loading />\r\n </el-icon>\r\n </el-upload>\r\n </div>\r\n </template>\r\n\r\n <!-- 单图模式 -->\r\n <template v-else>\r\n <!-- 已有图片:独立展示,hover 显示操作遮罩 -->\r\n <div v-if=\"imageUrl\" class=\"image-item single-image-item\">\r\n <el-image\r\n :src=\"imageUrl\"\r\n fit=\"cover\"\r\n class=\"image-preview\"\r\n />\r\n <div class=\"image-actions\">\r\n <el-icon class=\"action-icon\" @click.stop=\"handlePreviewSingle\">\r\n <ZoomIn />\r\n </el-icon>\r\n <el-icon v-if=\"!disabled\" class=\"action-icon\" @click.stop=\"handleRemoveSingle\">\r\n <Delete />\r\n </el-icon>\r\n </div>\r\n </div>\r\n\r\n <!-- 无图片:显示上传按钮 -->\r\n <el-upload\r\n v-else\r\n class=\"image-uploader\"\r\n :auto-upload=\"false\"\r\n :show-file-list=\"false\"\r\n :on-change=\"handleFileChange\"\r\n :disabled=\"disabled || uploading\"\r\n :accept=\"accept\"\r\n list-type=\"picture-card\"\r\n >\r\n <el-icon class=\"uploader-icon\">\r\n <Plus v-if=\"!uploading\" />\r\n <Loading v-else class=\"is-loading\" />\r\n </el-icon>\r\n </el-upload>\r\n\r\n <!-- 大图预览 -->\r\n <el-image-viewer\r\n v-if=\"showPreview\"\r\n :url-list=\"[imageUrl]\"\r\n :teleported=\"true\"\r\n @close=\"showPreview = false\"\r\n />\r\n </template>\r\n\r\n <div v-if=\"showTipText\" class=\"upload-tip\">\r\n <span>{{ tip }}</span>\r\n <span v-if=\"multiple && limit\"> (最多 {{ limit }} 张)</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, watch } from 'vue'\r\nimport { ElMessage, ElImage, ElIcon, ElUpload, ElImageViewer } from 'element-plus'\r\nimport type { UploadFile } from 'element-plus'\r\nimport { Plus, Loading, Delete, ZoomIn } from '@element-plus/icons-vue'\r\nimport draggable from 'vuedraggable'\r\nimport type { ImageItem } from './types'\r\n\r\ndefineOptions({\r\n name: 'JUploadImg'\r\n})\r\n\r\nconst props = withDefaults(defineProps<{\r\n modelValue?: string | string[]\r\n disabled?: boolean\r\n multiple?: boolean\r\n limit?: number\r\n maxSize?: number\r\n accept?: string\r\n tip?: string\r\n showTip?: boolean\r\n /** 自定义上传函数,接收 File 返回图片 URL */\r\n uploadFn?: (file: File) => Promise<string>\r\n}>(), {\r\n modelValue: '',\r\n disabled: false,\r\n multiple: false,\r\n limit: 9,\r\n maxSize: 2,\r\n accept: 'image/jpeg,image/png,image/jpg,image/gif',\r\n tip: '只能上传jpg/png/gif格式的图片,且不超过2MB',\r\n showTip: true,\r\n uploadFn: undefined\r\n})\r\n\r\nconst emit = defineEmits<{\r\n (e: 'update:modelValue', value: string | string[]): void\r\n (e: 'success', url: string): void\r\n (e: 'error', error: any): void\r\n}>()\r\n\r\n// 单图模式\r\nconst imageUrl = ref<string>('')\r\nconst showPreview = ref(false)\r\nconst showTipText = props.showTip\r\n\r\nconst handlePreviewSingle = () => {\r\n showPreview.value = true\r\n}\r\n\r\nconst handleRemoveSingle = () => {\r\n imageUrl.value = ''\r\n emit('update:modelValue', '')\r\n ElMessage.success('删除成功')\r\n}\r\n\r\n// 多图模式\r\nconst imageList = ref<ImageItem[]>([])\r\nconst uploading = ref(false)\r\n\r\n// 初始化图片列表(多图模式)\r\nconst initImageList = (urls: string[]) => {\r\n imageList.value = urls.map((url, index) => ({\r\n uid: Date.now() + index,\r\n url\r\n }))\r\n}\r\n\r\n// 监听外部值变化\r\nwatch(() => props.modelValue, (val) => {\r\n if (props.multiple) {\r\n if (Array.isArray(val) && val.length > 0) {\r\n initImageList(val)\r\n } else {\r\n imageList.value = []\r\n }\r\n } else {\r\n if (typeof val === 'string') {\r\n imageUrl.value = val\r\n } else {\r\n imageUrl.value = ''\r\n }\r\n }\r\n}, { immediate: true })\r\n\r\n// 拖拽结束(多图模式)\r\nconst handleDragEnd = () => {\r\n emitMultipleUpdate()\r\n}\r\n\r\n// 删除图片(多图模式)\r\nconst handleRemove = (index: number) => {\r\n imageList.value.splice(index, 1)\r\n emitMultipleUpdate()\r\n ElMessage.success('删除成功')\r\n}\r\n\r\n// 文件改变时触发\r\nconst handleFileChange = async (uploadFile: UploadFile) => {\r\n const file = uploadFile.raw as File\r\n\r\n if (!file) {\r\n ElMessage.error('文件不存在,请重试')\r\n return\r\n }\r\n\r\n if (file.size > props.maxSize * 1024 * 1024) {\r\n ElMessage.error(`图片大小不能超过 ${props.maxSize}MB`)\r\n return\r\n }\r\n\r\n if (!props.uploadFn) {\r\n ElMessage.error('未配置上传函数 (uploadFn)')\r\n return\r\n }\r\n\r\n try {\r\n uploading.value = true\r\n const url = await props.uploadFn(file)\r\n\r\n if (props.multiple) {\r\n imageList.value.push({ uid: Date.now(), url })\r\n emitMultipleUpdate()\r\n } else {\r\n imageUrl.value = url\r\n emit('update:modelValue', url)\r\n }\r\n\r\n emit('success', url)\r\n ElMessage.success('上传成功')\r\n } catch (error) {\r\n console.error('上传出错:', error)\r\n ElMessage.error('上传失败,请重试')\r\n emit('error', error)\r\n } finally {\r\n uploading.value = false\r\n }\r\n}\r\n\r\n// 触发多图更新\r\nconst emitMultipleUpdate = () => {\r\n const urls = imageList.value.map(item => item.url)\r\n emit('update:modelValue', urls)\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.j-upload-img-container {\r\n display: inline-block;\r\n}\r\n\r\n/* 多图模式样式 */\r\n.images-wrapper {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n align-items: flex-start;\r\n}\r\n\r\n.images-list {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n}\r\n\r\n.image-item {\r\n position: relative;\r\n width: 74px;\r\n height: 74px;\r\n border: 1px solid var(--el-border-color);\r\n border-radius: 6px;\r\n overflow: hidden;\r\n cursor: move;\r\n}\r\n\r\n.image-preview {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.delete-btn {\r\n position: absolute;\r\n top: 2px;\r\n right: 2px;\r\n width: 20px;\r\n height: 20px;\r\n background-color: rgba(0, 0, 0, 0.6);\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n opacity: 0;\r\n transition: opacity 0.3s;\r\n cursor: pointer;\r\n z-index: 1;\r\n}\r\n\r\n.image-item:hover .delete-btn {\r\n opacity: 1;\r\n}\r\n\r\n.delete-btn:hover {\r\n background-color: rgba(0, 0, 0, 0.8);\r\n}\r\n\r\n.icon-delete {\r\n font-size: 12px;\r\n color: #fff;\r\n}\r\n\r\n/* 单图和多图共用样式 */\r\n.image-uploader {\r\n display: inline-block;\r\n vertical-align: top;\r\n}\r\n\r\n.image-uploader :deep(.el-upload) {\r\n border: 1px dashed var(--el-border-color);\r\n border-radius: 6px;\r\n cursor: pointer;\r\n position: relative;\r\n overflow: hidden;\r\n transition: var(--el-transition-duration-fast);\r\n width: 74px !important;\r\n height: 74px !important;\r\n}\r\n\r\n.image-uploader :deep(.el-upload:hover) {\r\n border-color: var(--el-color-primary);\r\n}\r\n\r\n.uploader-icon {\r\n font-size: 20px;\r\n color: #8c939d;\r\n width: 74px;\r\n height: 74px;\r\n text-align: center;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.single-image-item {\r\n cursor: default;\r\n}\r\n\r\n.image-actions {\r\n position: absolute;\r\n inset: 0;\r\n background-color: rgba(0, 0, 0, 0.5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 12px;\r\n opacity: 0;\r\n transition: opacity 0.3s;\r\n}\r\n\r\n.single-image-item:hover .image-actions,\r\n.image-item:hover .image-actions {\r\n opacity: 1;\r\n}\r\n\r\n.action-icon {\r\n font-size: 18px;\r\n color: #fff;\r\n cursor: pointer;\r\n transition: transform 0.2s;\r\n}\r\n\r\n.action-icon:hover {\r\n transform: scale(1.2);\r\n}\r\n\r\n.upload-tip {\r\n margin-top: 8px;\r\n font-size: 12px;\r\n color: #909399;\r\n line-height: 1.5;\r\n}\r\n</style>\r\n","<template>\r\n <Icon v-if=\"icon\" :icon=\"icon\" :width=\"size\" :height=\"size\" v-bind=\"$attrs\" />\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { Icon } from '@iconify/vue'\r\n\r\ndefineOptions({\r\n name: 'JIconRender'\r\n})\r\n\r\nwithDefaults(defineProps<{\r\n icon: string\r\n size?: string | number\r\n}>(), {\r\n size: 24,\r\n})\r\n</script>\r\n","<template>\r\n <el-card shadow=\"never\" class=\"j-search-header-card\">\r\n <el-form inline class=\"search-form\">\r\n <div\r\n ref=\"formItemsRef\"\r\n class=\"form-items-wrapper\"\r\n :class=\"{ 'is-animated': isAnimated }\"\r\n >\r\n <slot />\r\n </div>\r\n </el-form>\r\n\r\n <div class=\"action-bar\" :style=\"{ marginTop: expanded ? '0px' : '10px' }\">\r\n <div class=\"action-left\">\r\n <el-button v-if=\"showAdd\" type=\"primary\" :icon=\"Plus\" @click=\"emit('add')\">\r\n {{ addText }}\r\n </el-button>\r\n <el-button\r\n v-if=\"showBatchDelete\"\r\n type=\"danger\"\r\n :icon=\"Delete\"\r\n :disabled=\"selectedCount === 0\"\r\n @click=\"emit('batchDelete')\"\r\n >\r\n 批量删除{{ selectedCount ? `(${selectedCount})` : '' }}\r\n </el-button>\r\n <el-button v-if=\"showSearch\" type=\"primary\" :icon=\"Search\" @click=\"emit('search')\">搜索</el-button>\r\n <el-button v-if=\"showReset\" :icon=\"Refresh\" @click=\"emit('reset')\">重置</el-button>\r\n <slot name=\"actions\" />\r\n </div>\r\n <el-button\r\n v-if=\"shouldCollapse\"\r\n link\r\n type=\"primary\"\r\n @click=\"toggleExpand\"\r\n >\r\n {{ expanded ? '收起' : '展开' }}\r\n <el-icon class=\"toggle-icon\" :class=\"{ 'is-expanded': expanded }\">\r\n <ArrowDown />\r\n </el-icon>\r\n </el-button>\r\n </div>\r\n </el-card>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, onMounted, onBeforeUnmount } from 'vue'\r\nimport { ElCard, ElForm, ElButton, ElIcon } from 'element-plus'\r\nimport { Search, Refresh, Plus, Delete, ArrowDown } from '@element-plus/icons-vue'\r\n\r\ndefineOptions({\r\n name: 'JSearchHeader'\r\n})\r\n\r\nconst props = withDefaults(defineProps<{\r\n selectedCount?: number\r\n addText?: string\r\n defaultVisible?: number\r\n showAdd?: boolean\r\n showBatchDelete?: boolean\r\n showSearch?: boolean\r\n showReset?: boolean\r\n}>(), {\r\n selectedCount: 0,\r\n addText: '新增',\r\n defaultVisible: 5,\r\n showAdd: true,\r\n showBatchDelete: true,\r\n showSearch: true,\r\n showReset: true\r\n})\r\n\r\nconst emit = defineEmits<{\r\n search: []\r\n reset: []\r\n add: []\r\n batchDelete: []\r\n}>()\r\n\r\nconst formItemsRef = ref<HTMLElement>()\r\nconst expanded = ref(false)\r\nconst isAnimated = ref(false)\r\nconst itemCount = ref(0)\r\nconst collapsedHeight = ref(0)\r\n\r\nconst shouldCollapse = computed(() => itemCount.value > props.defaultVisible)\r\n\r\nconst measureItems = () => {\r\n if (!formItemsRef.value) return\r\n const items = Array.from(formItemsRef.value.children) as HTMLElement[]\r\n itemCount.value = items.length\r\n\r\n const lastVisibleItem = items[props.defaultVisible - 1]\r\n if (lastVisibleItem && formItemsRef.value) {\r\n const wrapperRect = formItemsRef.value.getBoundingClientRect()\r\n const lastVisibleRect = lastVisibleItem.getBoundingClientRect()\r\n collapsedHeight.value = lastVisibleRect.bottom - wrapperRect.top\r\n }\r\n}\r\n\r\nconst toggleExpand = () => {\r\n const el = formItemsRef.value\r\n if (!el) return\r\n\r\n if (!expanded.value) {\r\n expanded.value = true\r\n el.style.maxHeight = el.scrollHeight + 'px'\r\n const onEnd = () => {\r\n el.style.maxHeight = 'none'\r\n el.removeEventListener('transitionend', onEnd)\r\n }\r\n el.addEventListener('transitionend', onEnd)\r\n } else {\r\n measureItems()\r\n expanded.value = false\r\n el.style.maxHeight = el.scrollHeight + 'px'\r\n el.offsetHeight\r\n el.style.maxHeight = collapsedHeight.value + 'px'\r\n }\r\n}\r\n\r\nlet observer: MutationObserver | null = null\r\n\r\nonMounted(() => {\r\n measureItems()\r\n if (shouldCollapse.value && formItemsRef.value) {\r\n formItemsRef.value.style.maxHeight = collapsedHeight.value + 'px'\r\n }\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(() => {\r\n isAnimated.value = true\r\n })\r\n })\r\n if (formItemsRef.value) {\r\n observer = new MutationObserver(() => {\r\n measureItems()\r\n if (shouldCollapse.value && !expanded.value && formItemsRef.value) {\r\n formItemsRef.value.style.maxHeight = collapsedHeight.value + 'px'\r\n }\r\n })\r\n observer.observe(formItemsRef.value, { childList: true })\r\n }\r\n})\r\n\r\nonBeforeUnmount(() => {\r\n observer?.disconnect()\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.j-search-header-card :deep(.el-card__body) {\r\n padding: 16px 20px 12px;\r\n}\r\n\r\n.search-form {\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n gap: 0;\r\n}\r\n\r\n.form-items-wrapper {\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n overflow: hidden;\r\n}\r\n\r\n.form-items-wrapper.is-animated {\r\n transition: max-height 0.3s ease-in-out;\r\n}\r\n\r\n.form-items-wrapper :deep(.el-form-item) {\r\n margin-bottom: 10px;\r\n margin-right: 16px;\r\n}\r\n\r\n.action-bar {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding-top: 10px;\r\n border-top: 1px solid #ebeef5;\r\n}\r\n\r\n.action-left {\r\n display: flex;\r\n gap: 8px;\r\n}\r\n\r\n.toggle-icon {\r\n margin-left: 2px;\r\n transition: transform 0.25s;\r\n}\r\n\r\n.toggle-icon.is-expanded {\r\n transform: rotate(180deg);\r\n}\r\n</style>\r\n","<template>\r\n <el-dialog\r\n v-model=\"visible\"\r\n :title=\"props.title\"\r\n width=\"900px\"\r\n :close-on-click-modal=\"false\"\r\n @open=\"handleOpen\"\r\n @close=\"handleClose\"\r\n >\r\n <!-- 上传区域 -->\r\n <el-card shadow=\"never\" class=\"j-import-upload-card\">\r\n <div class=\"j-import-upload-card-title\">导入 EXCEL</div>\r\n <el-divider style=\"margin: 10px 0\" />\r\n <div class=\"j-import-upload-row\">\r\n <el-upload\r\n accept=\".xlsx,.xls\"\r\n :auto-upload=\"false\"\r\n :show-file-list=\"false\"\r\n :on-change=\"handleFileChange\"\r\n >\r\n <el-button size=\"small\">点击上传</el-button>\r\n </el-upload>\r\n <el-link\r\n v-if=\"dataColumns.length\"\r\n type=\"primary\"\r\n class=\"j-import-no-wrap\"\r\n @click=\"handleDownloadTemplate\"\r\n >\r\n 下载导入模板.xlsx\r\n </el-link>\r\n </div>\r\n </el-card>\r\n\r\n <!-- 统计信息 + 确认导入 -->\r\n <el-row class=\"j-import-stats-row\" :gutter=\"20\" align=\"middle\">\r\n <el-col :span=\"18\">\r\n <el-row class=\"j-import-stats-cols\">\r\n <el-col :span=\"4\" class=\"j-import-stat-item\">\r\n <div class=\"j-import-stat-num\">{{ stats.total }}</div>\r\n <div class=\"j-import-stat-label\">导入数量</div>\r\n </el-col>\r\n <el-col :span=\"4\" class=\"j-import-stat-item\">\r\n <div class=\"j-import-stat-num\">{{ stats.fail }}</div>\r\n <div class=\"j-import-stat-label\">失败数量</div>\r\n </el-col>\r\n <el-col :span=\"4\" class=\"j-import-stat-item\">\r\n <div class=\"j-import-stat-num\">{{ stats.success }}</div>\r\n <div class=\"j-import-stat-label\">成功数量</div>\r\n </el-col>\r\n </el-row>\r\n </el-col>\r\n <el-col :span=\"6\" class=\"j-import-confirm-col\">\r\n <el-button\r\n type=\"primary\"\r\n size=\"small\"\r\n :loading=\"submitting\"\r\n :disabled=\"!renderData.length\"\r\n @click=\"handleConfirm\"\r\n >\r\n 确认导入\r\n </el-button>\r\n </el-col>\r\n </el-row>\r\n\r\n <!-- 数据表格 -->\r\n <el-table :data=\"renderData\" border size=\"small\" max-height=\"360\" class=\"j-import-data-table\">\r\n <el-table-column\r\n v-for=\"col in dataColumns\"\r\n :key=\"col.prop\"\r\n :prop=\"col.prop\"\r\n :label=\"col.label\"\r\n :min-width=\"120\"\r\n show-overflow-tooltip\r\n />\r\n <el-table-column label=\"状态\" width=\"110\" align=\"center\" fixed=\"right\">\r\n <template #default=\"{ row }\">\r\n <span v-if=\"row._status === -1\" class=\"j-import-status-fail\">\r\n {{ row._error || '创建失败' }}\r\n </span>\r\n <span v-else>{{ statusMap[row._status] }}</span>\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"操作\" width=\"80\" align=\"center\" fixed=\"right\">\r\n <template #default=\"{ $index, row }\">\r\n <el-button\r\n v-if=\"row._status === 0\"\r\n size=\"small\"\r\n @click=\"handleDel($index)\"\r\n >\r\n 删除\r\n </el-button>\r\n </template>\r\n </el-table-column>\r\n </el-table>\r\n\r\n <template #footer>\r\n <el-button @click=\"handleClose\">关闭</el-button>\r\n </template>\r\n </el-dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed } from 'vue'\r\nimport { ElMessage, ElDialog, ElCard, ElDivider, ElUpload, ElButton, ElLink, ElRow, ElCol, ElTable, ElTableColumn } from 'element-plus'\r\nimport type { UploadFile } from 'element-plus'\r\nimport * as XLSX from 'xlsx'\r\nimport type { JImportExcelProps } from './types'\r\n\r\ndefineOptions({ name: 'JImportExcel' })\r\n\r\nconst props = withDefaults(defineProps<JImportExcelProps>(), {\r\n excludeFields: () => ['id', 'ctime', 'mtime'],\r\n title: 'Excel 批量导入',\r\n})\r\n\r\nconst emit = defineEmits<{\r\n success: []\r\n}>()\r\n\r\nconst visible = defineModel<boolean>({ default: false })\r\nconst submitting = ref(false)\r\nconst fieldMap = ref<Record<string, string>>({})\r\nconst renderData = ref<Record<string, any>[]>([])\r\nconst stats = ref({ total: 0, success: 0, fail: 0 })\r\n\r\nconst statusMap: Record<number, string> = {\r\n 0: '待创建',\r\n 1: '创建成功',\r\n 2: '创建中',\r\n [-1]: '创建失败',\r\n}\r\n\r\n/** 过滤后的表头列 */\r\nconst dataColumns = computed(() => {\r\n return Object.entries(fieldMap.value)\r\n .filter(([key]) => !props.excludeFields.includes(key))\r\n .map(([key, label]) => ({ id: key, label, prop: key }))\r\n})\r\n\r\n/** 弹窗打开时获取字段列表 */\r\nconst handleOpen = async () => {\r\n try {\r\n const res = await props.getFieldListApi()\r\n fieldMap.value = res.data.tableFieldsInfo ?? {}\r\n } catch {\r\n ElMessage.error('获取字段列表失败')\r\n }\r\n}\r\n\r\n/** 文件上传解析 */\r\nconst handleFileChange = (uploadFile: UploadFile) => {\r\n const raw = uploadFile.raw\r\n if (!raw) return\r\n\r\n const validTypes = [\r\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n 'application/vnd.ms-excel',\r\n ]\r\n if (!validTypes.includes(raw.type) && !raw.name.match(/\\.xlsx?$/i)) {\r\n ElMessage.warning('请上传 .xlsx 或 .xls 格式文件')\r\n return\r\n }\r\n\r\n const reader = new FileReader()\r\n reader.onload = (e) => {\r\n try {\r\n const workbook = XLSX.read(e.target!.result, { type: 'binary' })\r\n const wsName = workbook.SheetNames[0] as string\r\n const ws = workbook.Sheets[wsName]!\r\n const rows = XLSX.utils.sheet_to_json(ws, {\r\n header: 1,\r\n defval: '',\r\n }) as any[][]\r\n\r\n const dataRows = rows.slice(1).filter((row) => row.some((cell) => cell !== ''))\r\n\r\n if (!dataRows.length) {\r\n ElMessage.warning('文件内容为空')\r\n return\r\n }\r\n\r\n // 按后端字段顺序一一映射,空单元格由 defval 补 '',避免后续列顶上来\r\n const list: Record<string, any>[] = dataRows.map((row) => {\r\n const item: Record<string, any> = { _status: 0, _error: '' }\r\n dataColumns.value.forEach((col, index) => {\r\n item[col.prop] = row[index] !== undefined ? row[index] : ''\r\n })\r\n return item\r\n })\r\n\r\n renderData.value = list\r\n stats.value = { total: list.length, success: 0, fail: 0 }\r\n } catch {\r\n ElMessage.error('解析文件失败,请检查文件格式')\r\n }\r\n }\r\n reader.readAsBinaryString(raw)\r\n}\r\n\r\n/** 删除行 */\r\nconst handleDel = (idx: number) => {\r\n renderData.value.splice(idx, 1)\r\n stats.value.total = renderData.value.length\r\n}\r\n\r\n/** 确认导入 */\r\nconst handleConfirm = async () => {\r\n const data = renderData.value\r\n .filter((row) => row._status === 0)\r\n .map(({ _status, _error, ...rest }) => rest)\r\n\r\n if (!data.length) {\r\n ElMessage.warning('没有可导入的数据')\r\n return\r\n }\r\n\r\n submitting.value = true\r\n try {\r\n const res = await props.importApi(data)\r\n if (res.code === 1) {\r\n // 全部成功\r\n renderData.value.forEach((row) => {\r\n if (row._status === 0) row._status = 1\r\n })\r\n stats.value.success = renderData.value.filter((r) => r._status === 1).length\r\n ElMessage.success('导入成功')\r\n emit('success')\r\n } else {\r\n ElMessage.error(res.msg || '导入失败')\r\n }\r\n } catch {\r\n ElMessage.error('导入失败,请重试')\r\n } finally {\r\n submitting.value = false\r\n }\r\n}\r\n\r\n/** 下载导入模板 */\r\nconst handleDownloadTemplate = () => {\r\n try {\r\n const wb = XLSX.utils.book_new()\r\n const headers = dataColumns.value.map((col) => col.label)\r\n const tr: Record<string, string> = {}\r\n headers.forEach((h) => (tr[h] = ''))\r\n const ws = XLSX.utils.json_to_sheet([tr])\r\n XLSX.utils.book_append_sheet(wb, ws, '模板')\r\n XLSX.writeFile(wb, '导入模板.xlsx')\r\n } catch {\r\n ElMessage.error('模板下载失败')\r\n }\r\n}\r\n\r\nconst handleClose = () => {\r\n if (!submitting.value) {\r\n visible.value = false\r\n renderData.value = []\r\n stats.value = { total: 0, success: 0, fail: 0 }\r\n }\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.j-import-upload-card {\r\n margin-bottom: 16px;\r\n}\r\n.j-import-upload-card-title {\r\n font-size: 14px;\r\n color: #606266;\r\n}\r\n.j-import-upload-row {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n}\r\n.j-import-no-wrap {\r\n white-space: nowrap;\r\n}\r\n.j-import-stats-row {\r\n margin: 12px 0;\r\n}\r\n.j-import-stats-cols {\r\n text-align: center;\r\n line-height: 1.5;\r\n}\r\n.j-import-stat-item {\r\n padding: 0 8px;\r\n}\r\n.j-import-stat-num {\r\n font-size: 20px;\r\n}\r\n.j-import-stat-label {\r\n font-size: 12px;\r\n color: #909399;\r\n}\r\n.j-import-confirm-col {\r\n text-align: right;\r\n padding-top: 10px;\r\n}\r\n.j-import-data-table {\r\n margin-top: 10px;\r\n}\r\n.j-import-status-fail {\r\n color: #f56c6c;\r\n font-size: 12px;\r\n}\r\n</style>\r\n","<template>\r\n <!-- 有子菜单:渲染 el-sub-menu -->\r\n <el-sub-menu\r\n v-if=\"menuItem.children && menuItem.children.length > 0\"\r\n :index=\"menuItem.path\"\r\n :class=\"[`j-sidebar__depth-${depth}`]\"\r\n >\r\n <template #title>\r\n <JIconRender v-if=\"menuItem.icon && depth === 0\" :icon=\"menuItem.icon\" />\r\n <span class=\"j-sidebar__menu-item-title\">{{ menuItem.title || menuItem.name }}</span>\r\n </template>\r\n <!-- 递归渲染子菜单 -->\r\n <JSideMenuItem\r\n v-for=\"child in menuItem.children\"\r\n :key=\"child.path\"\r\n :menu-item=\"child\"\r\n :is-collapse=\"isCollapse\"\r\n :depth=\"depth + 1\"\r\n @menu-click=\"(item) => emit('menu-click', item)\"\r\n />\r\n </el-sub-menu>\r\n\r\n <!-- 无子菜单:渲染 el-menu-item -->\r\n <el-menu-item\r\n v-else\r\n :index=\"menuItem.path\"\r\n :class=\"[`j-sidebar__depth-${depth}`]\"\r\n @click=\"handleClick\"\r\n >\r\n <JIconRender v-if=\"menuItem.icon && depth === 0\" :icon=\"menuItem.icon\" />\r\n <template #title>\r\n <span>{{ menuItem.title || menuItem.name }}</span>\r\n </template>\r\n </el-menu-item>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport type { SidebarMenuItem } from './types'\r\nimport { ElSubMenu, ElMenuItem } from 'element-plus'\r\nimport { JIconRender } from '../JIconRender'\r\n\r\ndefineOptions({\r\n name: 'JSideMenuItem'\r\n})\r\n\r\ninterface Props {\r\n menuItem: SidebarMenuItem\r\n isCollapse?: boolean\r\n depth?: number\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), { depth: 0 })\r\n\r\nconst emit = defineEmits<{\r\n 'menu-click': [item: SidebarMenuItem]\r\n}>()\r\n\r\nconst handleClick = () => {\r\n emit('menu-click', props.menuItem)\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.j-sidebar__menu-item-title {\r\n padding: 0 10px;\r\n}\r\n\r\n/* 二级菜单:灰色标题,作为分类标签 */\r\n.j-sidebar__depth-1 > :deep(.el-sub-menu__title) {\r\n color: #909399;\r\n font-size: 13px;\r\n}\r\n\r\n/* 二级叶子菜单(无子项)也用灰色 */\r\n:deep(.j-sidebar__depth-1.el-menu-item) {\r\n color: #909399;\r\n font-size: 13px;\r\n}\r\n\r\n/* 三级菜单:文字稍大 */\r\n:deep(.j-sidebar__depth-2.el-menu-item) {\r\n font-size: 15px;\r\n}\r\n</style>\r\n","<template>\r\n <div\r\n :class=\"['j-sidebar', innerCollapsed ? 'j-sidebar--collapsed' : 'j-sidebar--expanded']\"\r\n :style=\"{ width: innerCollapsed ? `${collapsedWidth}px` : `${expandedWidth}px` }\"\r\n >\r\n <!-- Logo 区域 -->\r\n <div class=\"j-sidebar__logo\">\r\n <slot name=\"logo\" :collapsed=\"innerCollapsed\">\r\n <h2 class=\"j-sidebar__title\">\r\n {{ innerCollapsed ? (collapsedTitle || title?.charAt(0) || '') : title }}\r\n </h2>\r\n </slot>\r\n </div>\r\n\r\n <!-- 菜单区域 -->\r\n <div class=\"j-sidebar__menu-wrapper\">\r\n <el-menu\r\n :default-active=\"activeMenu\"\r\n class=\"j-sidebar__menu\"\r\n :router=\"router\"\r\n :collapse=\"innerCollapsed\"\r\n :collapse-transition=\"false\"\r\n >\r\n <JSideMenuItem\r\n v-for=\"route in menus\"\r\n :key=\"route.path\"\r\n :menu-item=\"route\"\r\n :is-collapse=\"innerCollapsed\"\r\n @menu-click=\"(item) => emit('menu-click', item)\"\r\n />\r\n </el-menu>\r\n </div>\r\n\r\n <!-- 底部折叠按钮 -->\r\n <div class=\"j-sidebar__footer\">\r\n <slot name=\"footer\" :collapsed=\"innerCollapsed\" :toggle=\"toggleCollapse\">\r\n <button\r\n class=\"j-sidebar__collapse-btn\"\r\n @click=\"toggleCollapse\"\r\n >\r\n <JIconRender :icon=\"innerCollapsed ? 'mdi:chevron-right' : 'mdi:chevron-left'\" />\r\n </button>\r\n </slot>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, watch } from 'vue'\r\nimport { ElMenu } from 'element-plus'\r\nimport type { SidebarMenuItem } from './types'\r\nimport JSideMenuItem from './JSideMenuItem.vue'\r\nimport { JIconRender } from '../JIconRender'\r\n\r\ndefineOptions({\r\n name: 'JSidebar'\r\n})\r\n\r\ninterface Props {\r\n menus: SidebarMenuItem[]\r\n activeMenu?: string\r\n title?: string\r\n collapsedTitle?: string\r\n collapsed?: boolean\r\n collapsedWidth?: number\r\n expandedWidth?: number\r\n router?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n activeMenu: '',\r\n title: '',\r\n collapsedTitle: '',\r\n collapsed: false,\r\n collapsedWidth: 80,\r\n expandedWidth: 200,\r\n router: true,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:collapsed': [value: boolean]\r\n 'menu-click': [item: SidebarMenuItem]\r\n}>()\r\n\r\nconst innerCollapsed = ref(props.collapsed)\r\n\r\nwatch(() => props.collapsed, (val) => {\r\n innerCollapsed.value = val\r\n})\r\n\r\nconst toggleCollapse = () => {\r\n innerCollapsed.value = !innerCollapsed.value\r\n emit('update:collapsed', innerCollapsed.value)\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.j-sidebar {\r\n position: relative;\r\n background-color: $color-white;\r\n box-shadow: 2px 0 6px rgba(0, 21, 41, 0.08);\r\n overflow-x: hidden;\r\n transition: width 0.3s ease-in-out;\r\n flex-shrink: 0;\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n}\r\n\r\n.j-sidebar__logo {\r\n padding: 0 $spacing-md;\r\n display: flex;\r\n align-items: center;\r\n height: 50px;\r\n flex-shrink: 0;\r\n}\r\n\r\n\r\n.j-sidebar__title {\r\n margin: 0;\r\n font-size: $font-size-lg;\r\n font-weight: bold;\r\n color: $color-primary;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n}\r\n\r\n.j-sidebar__menu-wrapper {\r\n flex: 1;\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n}\r\n\r\n.j-sidebar__menu {\r\n border: none;\r\n width: 100%;\r\n}\r\n\r\n.j-sidebar__footer {\r\n flex-shrink: 0;\r\n padding: $spacing-sm;\r\n display: flex;\r\n}\r\n\r\n// 折叠状态:覆盖 el-menu 样式,图标+文字上下排列\r\n.j-sidebar--collapsed {\r\n :deep(.el-menu--collapse) {\r\n width: 100%;\r\n\r\n .el-menu-item,\r\n .el-sub-menu__title {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n height: auto;\r\n line-height: normal;\r\n padding: $spacing-sm 0 !important;\r\n\r\n .el-icon,\r\n .iconify {\r\n margin: 0;\r\n }\r\n\r\n span {\r\n display: block !important;\r\n visibility: visible !important;\r\n overflow: visible !important;\r\n width: auto !important;\r\n height: auto !important;\r\n font-size: $font-size-xs;\r\n margin-top: $spacing-xs;\r\n }\r\n }\r\n\r\n // 隐藏子菜单展开箭头\r\n .el-sub-menu__icon-arrow {\r\n display: none;\r\n }\r\n }\r\n}\r\n\r\n.j-sidebar__collapse-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: $spacing-sm;\r\n border: none;\r\n border-radius: $border-radius-base;\r\n background-color: transparent;\r\n color: $color-text-secondary;\r\n cursor: pointer;\r\n transition: $transition-fast;\r\n\r\n &:hover {\r\n background-color: $color-bg-base;\r\n color: $color-primary;\r\n }\r\n\r\n}\r\n</style>\r\n","<template>\n <div class=\"j-admin-layout\" :style=\"layoutStyle\">\n <JSidebar\n v-if=\"sideMenus.length > 0\"\n v-model:collapsed=\"innerCollapsed\"\n :menus=\"sideMenus\"\n :active-menu=\"activeMenu\"\n :title=\"title\"\n :collapsed-title=\"collapsedTitle\"\n :collapsed-width=\"sidebarCollapsedWidth\"\n :expanded-width=\"sidebarExpandedWidth\"\n @menu-click=\"handleSideMenuClick\"\n >\n <template v-if=\"$slots.sidebarFooter\" #footer=\"{ collapsed: sidebarCollapsed, toggle }\">\n <slot name=\"sidebarFooter\" :collapsed=\"sidebarCollapsed\" :toggle=\"toggle\" />\n </template>\n </JSidebar>\n\n <div class=\"j-admin-layout__right-panel\">\n <div class=\"j-admin-layout__header\">\n <div class=\"j-admin-layout__header-left\">\n <div v-if=\"sideMenus.length === 0\" class=\"j-admin-layout__logo\">\n <slot name=\"logo\">\n <h2>{{ logoTitle || title }}</h2>\n </slot>\n </div>\n\n <el-menu\n mode=\"horizontal\"\n :default-active=\"activeTopMenu\"\n class=\"j-admin-layout__top-menu\"\n @select=\"handleTopMenuSelect\"\n >\n <el-menu-item\n v-for=\"menu in topMenus\"\n :key=\"menu.path\"\n :index=\"menu.path\"\n >\n <JIconRender v-if=\"menu.icon\" :icon=\"menu.icon\" class=\"j-admin-layout__top-menu-icon\" />\n <span>{{ menu.title || menu.name }}</span>\n </el-menu-item>\n </el-menu>\n </div>\n\n <div class=\"j-admin-layout__header-right\">\n <slot name=\"headerRight\" :username=\"username\">\n <el-dropdown v-if=\"showProfile || showLogout\">\n <span class=\"j-admin-layout__user\">\n {{ username }}\n <el-icon>\n <ArrowDown />\n </el-icon>\n </span>\n <template #dropdown>\n <el-dropdown-menu>\n <el-dropdown-item v-if=\"showProfile\" @click=\"emit('profile')\">\n {{ profileText }}\n </el-dropdown-item>\n <el-dropdown-item v-if=\"showLogout\" @click=\"emit('logout')\">\n {{ logoutText }}\n </el-dropdown-item>\n </el-dropdown-menu>\n </template>\n </el-dropdown>\n </slot>\n </div>\n </div>\n\n <div class=\"j-admin-layout__content-container\">\n <slot name=\"tabs\" />\n <div\n :class=\"[\n 'j-admin-layout__content',\n { 'j-admin-layout__content--scrollbar-hidden': hideContentScrollbar }\n ]\"\n >\n <slot />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { ElMenu, ElMenuItem, ElDropdown, ElDropdownMenu, ElDropdownItem, ElIcon } from 'element-plus'\nimport { ArrowDown } from '@element-plus/icons-vue'\nimport { JSidebar, type SidebarMenuItem } from '../JSidebar'\nimport { JIconRender } from '../JIconRender'\nimport type { AdminLayoutMenuItem } from './types'\n\ndefineOptions({\n name: 'JAdminLayout'\n})\n\ninterface Props {\n topMenus: AdminLayoutMenuItem[]\n sideMenus: AdminLayoutMenuItem[]\n activeTopMenu?: string\n activeMenu?: string\n title?: string\n logoTitle?: string\n collapsedTitle?: string\n collapsed?: boolean\n username?: string\n profileText?: string\n logoutText?: string\n sidebarCollapsedWidth?: number\n sidebarExpandedWidth?: number\n headerHeight?: string\n contentPadding?: string\n contentBackground?: string\n headerBackground?: string\n showProfile?: boolean\n showLogout?: boolean\n hideContentScrollbar?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n activeTopMenu: '',\n activeMenu: '',\n title: '',\n logoTitle: '',\n collapsedTitle: '',\n collapsed: false,\n username: '',\n profileText: '个人资料',\n logoutText: '退出登录',\n sidebarCollapsedWidth: 80,\n sidebarExpandedWidth: 200,\n headerHeight: '50px',\n contentPadding: '10px',\n contentBackground: '#f0f2f5',\n headerBackground: '#ffffff',\n showProfile: true,\n showLogout: true,\n hideContentScrollbar: false,\n})\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean]\n 'top-menu-select': [path: string]\n 'side-menu-click': [item: SidebarMenuItem]\n profile: []\n logout: []\n}>()\n\nconst innerCollapsed = computed({\n get: () => props.collapsed,\n set: value => emit('update:collapsed', value),\n})\n\nconst layoutStyle = computed(() => ({\n '--j-admin-layout-header-height': props.headerHeight,\n '--j-admin-layout-content-padding': props.contentPadding,\n '--j-admin-layout-content-bg': props.contentBackground,\n '--j-admin-layout-header-bg': props.headerBackground,\n}))\n\nconst handleTopMenuSelect = (path: string) => {\n emit('top-menu-select', path)\n}\n\nconst handleSideMenuClick = (item: SidebarMenuItem) => {\n emit('side-menu-click', item)\n}\n</script>\n\n<style scoped lang=\"scss\">\n.j-admin-layout {\n width: 100vw;\n height: 100vh;\n display: flex;\n flex-direction: row;\n overflow: hidden;\n}\n\n.j-admin-layout__right-panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background-color: var(--j-admin-layout-content-bg);\n}\n\n.j-admin-layout__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n background-color: var(--j-admin-layout-header-bg);\n box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);\n height: var(--j-admin-layout-header-height);\n flex-shrink: 0;\n z-index: 100;\n}\n\n.j-admin-layout__header-left {\n display: flex;\n align-items: center;\n flex: 1;\n height: 100%;\n min-width: 0;\n}\n\n.j-admin-layout__logo {\n padding: 0 $spacing-md;\n display: flex;\n align-items: center;\n height: var(--j-admin-layout-header-height);\n flex-shrink: 0;\n}\n\n.j-admin-layout__logo h2 {\n margin: 0;\n font-size: $font-size-lg;\n font-weight: bold;\n color: $color-primary;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.j-admin-layout__top-menu {\n flex: 1;\n height: var(--j-admin-layout-header-height);\n border-bottom: none;\n min-width: 0;\n}\n\n.j-admin-layout__top-menu-icon {\n margin-right: $spacing-xs;\n}\n\n.j-admin-layout__header-right {\n display: flex;\n align-items: center;\n gap: $spacing-md;\n padding-right: $spacing-md;\n flex-shrink: 0;\n}\n\n.j-admin-layout__user {\n cursor: pointer;\n display: flex;\n align-items: center;\n color: $color-text-regular;\n}\n\n.j-admin-layout__user:hover {\n color: $color-primary;\n}\n\n.j-admin-layout__content-container {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n background-color: var(--j-admin-layout-content-bg);\n}\n\n.j-admin-layout__content {\n padding: var(--j-admin-layout-content-padding);\n flex: 1;\n overflow: auto;\n}\n\n.j-admin-layout__content--scrollbar-hidden {\n scrollbar-width: none;\n -ms-overflow-style: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n}\n</style>\n","/**\r\n * 递归转换值(处理嵌套对象和数组)\r\n */\r\nfunction deepTransformValue(value: any, transformer: (obj: Record<string, any>) => Record<string, any>): any {\r\n if (Array.isArray(value)) {\r\n return value.map((item) => deepTransformValue(item, transformer))\r\n }\r\n if (value !== null && typeof value === 'object' && !(value instanceof Date)) {\r\n return transformer(value)\r\n }\r\n return value\r\n}\r\n\r\n/**\r\n * 将对象的 key 从小驼峰转为下划线格式(支持深度嵌套)\r\n * @param obj 需要转换的对象\r\n * @param excludeKeys 不需要转换的 key 数组(可选)\r\n */\r\nexport function toSnakeCase<T extends Record<string, any>>(\r\n obj: T,\r\n excludeKeys: string[] = []\r\n): Record<string, any> {\r\n return Object.fromEntries(\r\n Object.entries(obj).map(([key, value]) => {\r\n const newValue = deepTransformValue(value, (v) => toSnakeCase(v, excludeKeys))\r\n if (excludeKeys.includes(key)) {\r\n return [key, newValue]\r\n }\r\n const snakeKey = key.replace(/([A-Z])/g, '_$1').toLowerCase()\r\n return [snakeKey, newValue]\r\n })\r\n )\r\n}\r\n\r\n/**\r\n * 将对象的 key 从下划线格式转为小驼峰(支持深度嵌套)\r\n * @param obj 需要转换的对象\r\n * @param excludeKeys 不需要转换的 key 数组(可选)\r\n */\r\nexport function toCamelCase<T extends Record<string, any>>(\r\n obj: T,\r\n excludeKeys: string[] = []\r\n): Record<string, any> {\r\n return Object.fromEntries(\r\n Object.entries(obj).map(([key, value]) => {\r\n const newValue = deepTransformValue(value, (v) => toCamelCase(v, excludeKeys))\r\n if (excludeKeys.includes(key)) {\r\n return [key, newValue]\r\n }\r\n const camelKey = key.replace(/_([a-z])/g, (_, char) => char.toUpperCase())\r\n return [camelKey, newValue]\r\n })\r\n )\r\n}\r\n\r\n/**\r\n * 从对象中提取指定的 key\r\n * @param obj 源对象\r\n * @param keys 要提取的 key 数组\r\n */\r\nexport function pick<T extends Record<string, any>, K extends keyof T>(\r\n obj: T,\r\n keys: K[]\r\n): Pick<T, K> {\r\n const result = {} as Pick<T, K>\r\n for (const key of keys) {\r\n if (key in obj) {\r\n result[key] = obj[key]\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * 从对象中排除指定的 key\r\n * @param obj 源对象\r\n * @param keys 要排除的 key 数组\r\n */\r\nexport function omit<T extends Record<string, any>, K extends keyof T>(\r\n obj: T,\r\n keys: K[]\r\n): Omit<T, K> {\r\n const result = { ...obj }\r\n for (const key of keys) {\r\n delete result[key]\r\n }\r\n return result as Omit<T, K>\r\n}\r\n\r\n/**\r\n * 深拷贝对象\r\n * @param obj 需要拷贝的对象\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n if (obj === null || typeof obj !== 'object') return obj\r\n if (obj instanceof Date) return new Date(obj.getTime()) as unknown as T\r\n if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags) as unknown as T\r\n if (Array.isArray(obj)) return obj.map((item) => deepClone(item)) as unknown as T\r\n const cloned = {} as Record<string, any>\r\n for (const key of Object.keys(obj)) {\r\n cloned[key] = deepClone((obj as Record<string, any>)[key])\r\n }\r\n return cloned as T\r\n}\r\n\r\n/**\r\n * 过滤对象中的空值(null、undefined、空字符串)\r\n * @param obj 需要过滤的对象\r\n * @param deep 是否递归过滤嵌套对象,默认 false\r\n */\r\nexport function filterEmpty<T extends Record<string, any>>(\r\n obj: T,\r\n deep = false\r\n): Partial<T> {\r\n const result = {} as Record<string, any>\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (value === null || value === undefined || value === '') continue\r\n if (deep && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)) {\r\n const filtered = filterEmpty(value, true)\r\n if (Object.keys(filtered).length > 0) {\r\n result[key] = filtered\r\n }\r\n } else {\r\n result[key] = value\r\n }\r\n }\r\n return result as Partial<T>\r\n}\r\n\r\n/**\r\n * 将嵌套对象扁平化为单层对象\r\n * @param obj 需要扁平化的对象\r\n * @param prefix key 前缀,默认为空\r\n * @param separator 分隔符,默认为 '.'\r\n * @example flatten({ a: { b: 1, c: { d: 2 } } }) => { 'a.b': 1, 'a.c.d': 2 }\r\n */\r\nexport function flatten(\r\n obj: Record<string, any>,\r\n prefix = '',\r\n separator = '.'\r\n): Record<string, any> {\r\n const result: Record<string, any> = {}\r\n for (const [key, value] of Object.entries(obj)) {\r\n const newKey = prefix ? `${prefix}${separator}${key}` : key\r\n if (value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)) {\r\n Object.assign(result, flatten(value, newKey, separator))\r\n } else {\r\n result[newKey] = value\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * 将扁平化的对象还原为嵌套对象\r\n * @param obj 扁平化的对象\r\n * @param separator 分隔符,默认为 '.'\r\n * @example unflatten({ 'a.b': 1, 'a.c.d': 2 }) => { a: { b: 1, c: { d: 2 } } }\r\n */\r\nexport function unflatten(\r\n obj: Record<string, any>,\r\n separator = '.'\r\n): Record<string, any> {\r\n const result: Record<string, any> = {}\r\n for (const [key, value] of Object.entries(obj)) {\r\n const parts = key.split(separator)\r\n let current = result\r\n for (let i = 0; i < parts.length - 1; i++) {\r\n const k = parts[i] as string\r\n if (!(k in current)) {\r\n current[k] = {}\r\n }\r\n current = current[k]\r\n }\r\n current[parts[parts.length - 1] as string] = value\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * 将 { key: label } 对象转换为 el-table-column 所需的表头数组\r\n * @param fieldMap 字段映射对象\r\n * @example toTableColumns({ id: '主键', name: '名称' }) => [{ id: 'id', label: '主键', prop: 'id' }, ...]\r\n */\r\nexport function toTableColumns(fieldMap: Record<string, string>) {\r\n return Object.entries(fieldMap).map(([key, label]) => ({\r\n id: key,\r\n label,\r\n prop: key,\r\n }))\r\n}\r\n","import type { RouteRecordRaw } from 'vue-router'\r\nimport type { BackendRoute } from './types'\r\n\r\ntype ViewModules = Record<string, () => Promise<unknown>>\r\n\r\ninterface RouteTreeNode extends BackendRoute {\r\n children?: RouteTreeNode[]\r\n}\r\n\r\nexport function getComponentImport(componentPath: string, viewModules: ViewModules): (() => Promise<unknown>) | null {\r\n if (!componentPath) return null\r\n\r\n let normalizedPath = componentPath.replace(/^@\\//, '')\r\n if (!normalizedPath.startsWith('views/')) normalizedPath = `views/${normalizedPath}`\r\n if (!normalizedPath.endsWith('.vue')) normalizedPath = `${normalizedPath}.vue`\r\n\r\n const fullPath = `/src/${normalizedPath}`\r\n\r\n return (viewModules[fullPath] ?? viewModules['/src/views/common/NotFound.vue'] ?? null) as (() => Promise<unknown>) | null\r\n}\r\n\r\nexport function buildRouteTree(routes: BackendRoute[]): RouteTreeNode[] {\r\n const routeMap = new Map<string, RouteTreeNode>()\r\n const rootRoutes: RouteTreeNode[] = []\r\n\r\n routes.forEach(route => routeMap.set(route.name, { ...route, children: [] }))\r\n\r\n routes.forEach(route => {\r\n const currentRoute = routeMap.get(route.name)!\r\n if (!route.parent_name) {\r\n rootRoutes.push(currentRoute)\r\n } else {\r\n const parentRoute = routeMap.get(route.parent_name)\r\n if (parentRoute) {\r\n parentRoute.children ??= []\r\n parentRoute.children.push(currentRoute)\r\n } else {\r\n rootRoutes.push(currentRoute)\r\n }\r\n }\r\n })\r\n return rootRoutes\r\n}\r\n\r\nexport function transformBackendRoutes(\r\n backendRoutes: RouteTreeNode[],\r\n viewModules: ViewModules,\r\n projectName?: string\r\n): RouteRecordRaw[] {\r\n return backendRoutes\r\n .filter(route => !projectName || !route.project || route.project === projectName)\r\n .map(route => {\r\n const routeConfig: Partial<RouteRecordRaw> = {\r\n path: route.path,\r\n name: route.name,\r\n meta: {\r\n requiresAuth: route.requiresAuth === 1,\r\n title: route.title,\r\n permissions: route.permissions\r\n ? route.permissions.split(',').map(p => p.trim()).filter(Boolean)\r\n : [],\r\n params: route.params\r\n ? route.params.split('&').map(p => p.trim()).filter(Boolean)\r\n : [],\r\n },\r\n }\r\n\r\n const component = getComponentImport(route.component, viewModules)\r\n if (component) routeConfig.component = component as RouteRecordRaw['component']\r\n\r\n if (route.redirect) routeConfig.redirect = route.redirect\r\n\r\n if (route.children?.length) {\r\n routeConfig.children = transformBackendRoutes(route.children, viewModules, projectName)\r\n }\r\n\r\n return routeConfig as RouteRecordRaw\r\n })\r\n}\r\n\r\nexport function findFirstAllowedRoute(\r\n backendRoutes: BackendRoute[],\r\n routePermissions: string[],\r\n layoutRouteName: string,\r\n projectName?: string\r\n): BackendRoute | undefined {\r\n const routeMap = new Map<string, BackendRoute>()\r\n backendRoutes.forEach(route => routeMap.set(route.name, route))\r\n\r\n const isDescendantOfLayout = (route: BackendRoute): boolean => {\r\n let parentName = route.parent_name\r\n const visited = new Set<string>()\r\n\r\n while (parentName) {\r\n if (parentName === layoutRouteName) return true\r\n if (visited.has(parentName)) return false\r\n\r\n visited.add(parentName)\r\n const parentRoute = routeMap.get(parentName)\r\n if (!parentRoute) return false\r\n parentName = parentRoute.parent_name\r\n }\r\n\r\n return false\r\n }\r\n\r\n return backendRoutes\r\n .filter(route =>\r\n route.name !== layoutRouteName &&\r\n route.is_show === 1 &&\r\n route.component &&\r\n routePermissions.includes(route.code) &&\r\n isDescendantOfLayout(route) &&\r\n (!projectName || !route.project || route.project === projectName)\r\n )\r\n .sort((a, b) => a.sorts - b.sorts)[0]\r\n}\r\n","import type { NavigationGuardNext, Router } from 'vue-router'\r\nimport NProgress from 'nprogress'\r\nimport 'nprogress/nprogress.css'\r\nimport { ElMessage } from 'element-plus'\r\nimport type { RouterGuardOptions } from './types'\r\nimport { buildRouteTree, transformBackendRoutes } from './helpers'\r\n\r\nNProgress.configure({ showSpinner: false })\r\n\r\nconst isDev = import.meta.env.DEV\r\nconst log = (...args: unknown[]) => { if (isDev) console.log('[Router]', ...args) }\r\nconst warn = (...args: unknown[]) => { if (isDev) console.warn('[Router]', ...args) }\r\nconst logError = (...args: unknown[]) => { console.error('[Router]', ...args) }\r\n\r\nexport function createRouterGuard(router: Router, options: RouterGuardOptions) {\r\n const {\r\n getRouteStore,\r\n getPermissionStore,\r\n getUserStore,\r\n isAuthenticated,\r\n viewModules,\r\n homeComponent,\r\n notFoundComponent,\r\n projectName,\r\n layoutRouteName = 'Layout',\r\n publicPaths = ['/login', '/register'],\r\n loginRouteName = 'login',\r\n forbiddenRouteName = 'Forbidden',\r\n homeRouteName = 'Home',\r\n homeRoutePath = 'home',\r\n homeTitle = '\\u9996\\u9875',\r\n noPermissionMessage = '\\u6682\\u65e0\\u6743\\u9650',\r\n } = options\r\n\r\n let hasAddedRoutes = false\r\n\r\n function addDynamicRoutes(backendRoutes: ReturnType<typeof getRouteStore>['backendRoutes']) {\r\n const treeRoutes = buildRouteTree(backendRoutes)\r\n const layoutRoute = treeRoutes.find(route => route.name === layoutRouteName)\r\n const childRoutes = layoutRoute?.children\r\n ? transformBackendRoutes(layoutRoute.children, viewModules, projectName)\r\n : []\r\n\r\n childRoutes.forEach(route => {\r\n if (route.name && router.hasRoute(route.name)) return\r\n router.addRoute(layoutRouteName, route)\r\n log(`Add route: ${String(route.name)} -> ${route.path}`)\r\n })\r\n\r\n if (!router.hasRoute(homeRouteName)) {\r\n router.addRoute(layoutRouteName, {\r\n path: homeRoutePath,\r\n name: homeRouteName,\r\n component: homeComponent as never,\r\n meta: { title: homeTitle },\r\n })\r\n }\r\n\r\n if (!router.hasRoute('NotFound')) {\r\n router.addRoute({\r\n path: '/:pathMatch(.*)*',\r\n name: 'NotFound',\r\n component: notFoundComponent as never,\r\n })\r\n }\r\n\r\n log(`Dynamic routes added: ${childRoutes.length}`)\r\n }\r\n\r\n function redirectToHomeOrContinue(\r\n toName: ReturnType<Router['resolve']>['name'],\r\n next: NavigationGuardNext\r\n ) {\r\n if (toName === homeRouteName) {\r\n next()\r\n return\r\n }\r\n\r\n if (router.hasRoute(homeRouteName)) {\r\n next({ name: homeRouteName, replace: true })\r\n } else {\r\n next()\r\n }\r\n }\r\n\r\n router.beforeEach(async (to, _from, next) => {\r\n NProgress.start()\r\n\r\n if (isAuthenticated() && !hasAddedRoutes) {\r\n try {\r\n const routeStore = getRouteStore()\r\n const permissionStore = getPermissionStore()\r\n\r\n await routeStore.initRoutes()\r\n await permissionStore.loadUserPermissions()\r\n\r\n addDynamicRoutes(routeStore.backendRoutes)\r\n hasAddedRoutes = true\r\n\r\n if (to.path === '/' || to.path === '') {\r\n redirectToHomeOrContinue(to.name, next)\r\n return\r\n }\r\n\r\n if (to.name === layoutRouteName) {\r\n redirectToHomeOrContinue(to.name, next)\r\n return\r\n }\r\n\r\n const currentRoute = routeStore.backendRoutes.find(route => route.name === to.name)\r\n if (currentRoute && !permissionStore.routePermissions.includes(currentRoute.code)) {\r\n warn('No route permission:', to.path)\r\n next({ name: forbiddenRouteName, replace: true })\r\n return\r\n }\r\n\r\n next({\r\n path: to.path,\r\n query: to.query,\r\n hash: to.hash,\r\n replace: true,\r\n })\r\n return\r\n } catch (err) {\r\n logError('Failed to load route permissions:', err)\r\n hasAddedRoutes = false\r\n await getUserStore().logout()\r\n next({ name: loginRouteName, replace: true })\r\n return\r\n }\r\n }\r\n\r\n if (publicPaths.includes(to.path)) {\r\n if (isAuthenticated()) {\r\n next({ path: '/', replace: true })\r\n } else {\r\n next()\r\n }\r\n return\r\n }\r\n\r\n if (!isAuthenticated()) {\r\n next({ name: loginRouteName, replace: true })\r\n return\r\n }\r\n\r\n const permissionStore = getPermissionStore()\r\n const routeStore = getRouteStore()\r\n\r\n if (to.name === homeRouteName) {\r\n next()\r\n return\r\n }\r\n\r\n if (permissionStore.routePermissions.length === 0) {\r\n if (to.path !== '/') {\r\n ElMessage.warning(noPermissionMessage)\r\n next({ path: '/', replace: true })\r\n } else {\r\n redirectToHomeOrContinue(to.name, next)\r\n }\r\n return\r\n }\r\n\r\n if (to.path === '/') {\r\n redirectToHomeOrContinue(to.name, next)\r\n return\r\n }\r\n\r\n if (to.name === layoutRouteName) {\r\n redirectToHomeOrContinue(to.name, next)\r\n return\r\n }\r\n\r\n const currentRoute = routeStore.backendRoutes.find(route => route.name === to.name)\r\n if (currentRoute && !permissionStore.routePermissions.includes(currentRoute.code)) {\r\n warn('No route permission:', to.path)\r\n next({ name: forbiddenRouteName, replace: true })\r\n return\r\n }\r\n\r\n next()\r\n })\r\n\r\n router.afterEach(() => NProgress.done())\r\n\r\n return {\r\n resetRouterState: () => { hasAddedRoutes = false },\r\n }\r\n}\r\n","import type { App } from 'vue'\r\nimport { JButton } from './components/JButton'\r\nimport { JUploadImg } from './components/JUploadImg'\r\nimport { JIconRender } from './components/JIconRender'\r\nimport { JSearchHeader } from './components/JSearchHeader'\r\nimport { JImportExcel } from './components/JImportExcel'\r\nimport { JSidebar, JSideMenuItem } from './components/JSidebar'\r\nimport { JAdminLayout } from './components/JAdminLayout'\r\n\r\n// 组件列表,新增组件后在此处注册\r\nconst components = [JButton, JUploadImg, JIconRender, JSearchHeader, JImportExcel, JSidebar, JSideMenuItem, JAdminLayout]\r\n\r\n// 全量安装插件(app.use(JgyComponents))\r\nconst install = (app: App) => {\r\n components.forEach((component) => {\r\n app.component(component.name ?? component.__name ?? '', component)\r\n })\r\n}\r\n\r\n// 默认导出插件对象\r\nexport default { install }\r\n\r\n// 按需导出各组件\r\nexport { JButton, JUploadImg, JIconRender, JSearchHeader, JImportExcel, JSidebar, JSideMenuItem, JAdminLayout }\r\n\r\n// 导出工具方法\r\nexport { toSnakeCase, toCamelCase, pick, omit, deepClone, filterEmpty, flatten, unflatten, toTableColumns } from './utils'\r\n\r\n// 导出路由工具\r\nexport { createRouterGuard, buildRouteTree, transformBackendRoutes, findFirstAllowedRoute, getComponentImport } from './router'\r\nexport type { BackendRoute, RouteStoreAdapter, PermissionStoreAdapter, UserStoreAdapter, RouterGuardOptions } from './router'\r\n\r\n// 导出类型\r\nexport type { ButtonType, ButtonSize } from './components/JButton'\r\nexport type { JUploadImgProps, JUploadImgEmits, ImageItem } from './components/JUploadImg'\r\nexport type { JIconRenderProps } from './components/JIconRender'\r\nexport type { JSearchHeaderProps } from './components/JSearchHeader'\r\nexport type { JImportExcelProps, ApiFn } from './components/JImportExcel'\r\nexport type { SidebarMenuItem, JSidebarProps, JSideMenuItemProps } from './components/JSidebar'\r\nexport type { AdminLayoutMenuItem, JAdminLayoutProps } from './components/JAdminLayout'\r\n"],"names":["props","__props","emit","__emit","handleClick","event","_createElementBlock","_openBlock","_hoisted_2","$slots","_hoisted_3","_renderSlot","_ctx","imageUrl","ref","showPreview","showTipText","handlePreviewSingle","handleRemoveSingle","ElMessage","imageList","uploading","initImageList","urls","url","index","watch","val","handleDragEnd","emitMultipleUpdate","handleRemove","handleFileChange","uploadFile","file","error","item","_hoisted_1","_createVNode","_unref","draggable","$event","_withCtx","element","_createElementVNode","ElImage","img","_withModifiers","ElIcon","Delete","_createBlock","ElUpload","Loading","Plus","_Fragment","_hoisted_5","_hoisted_6","ZoomIn","ElImageViewer","_hoisted_7","_hoisted_8","_toDisplayString","_mergeProps","$attrs","formItemsRef","expanded","isAnimated","itemCount","collapsedHeight","shouldCollapse","computed","measureItems","items","lastVisibleItem","wrapperRect","lastVisibleRect","toggleExpand","el","onEnd","observer","onMounted","onBeforeUnmount","ElCard","ElForm","_normalizeClass","ElButton","Search","_cache","Refresh","_createTextVNode","ArrowDown","visible","_useModel","submitting","fieldMap","renderData","stats","statusMap","dataColumns","key","label","handleOpen","res","raw","reader","e","workbook","XLSX","wsName","ws","dataRows","row","cell","list","col","handleDel","idx","handleConfirm","data","_status","_error","rest","r","handleDownloadTemplate","wb","headers","tr","h","handleClose","ElDialog","ElDivider","ElLink","ElRow","ElCol","_hoisted_4","ElTable","_renderList","ElTableColumn","$index","ElSubMenu","JIconRender","child","_component_JSideMenuItem","ElMenuItem","innerCollapsed","toggleCollapse","_normalizeStyle","_a","ElMenu","route","JSideMenuItem","value","layoutStyle","handleTopMenuSelect","path","handleSideMenuClick","JSidebar","sidebarCollapsed","toggle","menu","ElDropdown","ElDropdownMenu","ElDropdownItem","deepTransformValue","transformer","toSnakeCase","obj","excludeKeys","newValue","v","toCamelCase","_","char","pick","keys","result","omit","deepClone","cloned","filterEmpty","deep","filtered","flatten","prefix","separator","newKey","unflatten","parts","current","i","k","toTableColumns","getComponentImport","componentPath","viewModules","normalizedPath","fullPath","buildRouteTree","routes","routeMap","rootRoutes","currentRoute","parentRoute","transformBackendRoutes","backendRoutes","projectName","routeConfig","p","component","findFirstAllowedRoute","routePermissions","layoutRouteName","isDescendantOfLayout","parentName","visited","a","b","NProgress","log","args","warn","logError","createRouterGuard","router","options","getRouteStore","getPermissionStore","getUserStore","isAuthenticated","homeComponent","notFoundComponent","publicPaths","loginRouteName","forbiddenRouteName","homeRouteName","homeRoutePath","homeTitle","noPermissionMessage","hasAddedRoutes","addDynamicRoutes","layoutRoute","childRoutes","redirectToHomeOrContinue","toName","next","to","_from","routeStore","permissionStore","err","components","JButton","JUploadImg","JSearchHeader","JImportExcel","JAdminLayout","install","app"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/components/JButton/JButton.vue","../src/components/JUploadImg/JUploadImg.vue","../src/components/JIconRender/JIconRender.vue","../src/components/JSearchHeader/JSearchHeader.vue","../src/components/JImportExcel/JImportExcel.vue","../src/components/JSidebar/JSideMenuItem.vue","../src/components/JSidebar/JSidebar.vue","../src/components/JAdminLayout/JAdminLayout.vue","../src/components/JProductDetail/JProductDetailDialog.vue","../src/components/JProductDetail/JSkuLink.vue","../src/components/JProductDetail/useProductDetailDialog.ts","../src/components/JSearchInputDialog/JSearchInputDialog.vue","../src/utils/transform.ts","../src/router/helpers.ts","../src/router/guards.ts","../src/index.ts"],"sourcesContent":["<template>\r\n <button\r\n class=\"j-button\"\r\n :class=\"[\r\n `j-button--${type}`,\r\n `j-button--${size}`,\r\n {\r\n 'j-button--plain': plain,\r\n 'j-button--round': round,\r\n 'j-button--disabled': disabled,\r\n 'j-button--loading': loading,\r\n },\r\n ]\"\r\n :disabled=\"disabled || loading\"\r\n @click=\"handleClick\"\r\n >\r\n <span v-if=\"loading\" class=\"j-button__loading-icon\" />\r\n <span v-if=\"$slots.default\" class=\"j-button__text\">\r\n <slot />\r\n </span>\r\n </button>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport type { ButtonType, ButtonSize } from './types'\r\n\r\ninterface Props {\r\n type?: ButtonType\r\n size?: ButtonSize\r\n plain?: boolean\r\n round?: boolean\r\n disabled?: boolean\r\n loading?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n type: 'default',\r\n size: 'medium',\r\n plain: false,\r\n round: false,\r\n disabled: false,\r\n loading: false,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n click: [event: MouseEvent]\r\n}>()\r\n\r\nfunction handleClick(event: MouseEvent) {\r\n if (!props.disabled && !props.loading) {\r\n emit('click', event)\r\n }\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.j-button {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: $spacing-xs;\r\n padding: 8px 16px;\r\n font-size: $font-size-base;\r\n font-weight: 400;\r\n line-height: 1;\r\n white-space: nowrap;\r\n cursor: pointer;\r\n border: 1px solid $color-border;\r\n border-radius: $border-radius-base;\r\n background-color: $color-white;\r\n color: $color-text-regular;\r\n transition: $transition-fast;\r\n outline: none;\r\n user-select: none;\r\n\r\n &:hover {\r\n color: $color-primary;\r\n border-color: $color-primary;\r\n background-color: color.adjust($color-primary, $lightness: 40%);\r\n }\r\n\r\n // 尺寸\r\n &--small {\r\n padding: 5px 12px;\r\n font-size: $font-size-xs;\r\n }\r\n\r\n &--medium {\r\n padding: 8px 16px;\r\n font-size: $font-size-base;\r\n }\r\n\r\n &--large {\r\n padding: 12px 20px;\r\n font-size: $font-size-md;\r\n }\r\n\r\n // 类型\r\n &--primary {\r\n background-color: $color-primary;\r\n border-color: $color-primary;\r\n color: $color-white;\r\n &:hover {\r\n background-color: color.adjust($color-primary, $lightness: 10%);\r\n border-color: color.adjust($color-primary, $lightness: 10%);\r\n color: $color-white;\r\n }\r\n }\r\n\r\n &--success {\r\n background-color: $color-success;\r\n border-color: $color-success;\r\n color: $color-white;\r\n &:hover {\r\n background-color: color.adjust($color-success, $lightness: 10%);\r\n border-color: color.adjust($color-success, $lightness: 10%);\r\n color: $color-white;\r\n }\r\n }\r\n\r\n &--danger {\r\n background-color: $color-danger;\r\n border-color: $color-danger;\r\n color: $color-white;\r\n &:hover {\r\n background-color: color.adjust($color-danger, $lightness: 10%);\r\n border-color: color.adjust($color-danger, $lightness: 10%);\r\n color: $color-white;\r\n }\r\n }\r\n\r\n &--warning {\r\n background-color: $color-warning;\r\n border-color: $color-warning;\r\n color: $color-white;\r\n &:hover {\r\n background-color: color.adjust($color-warning, $lightness: 10%);\r\n border-color: color.adjust($color-warning, $lightness: 10%);\r\n color: $color-white;\r\n }\r\n }\r\n\r\n // 朴素按钮\r\n &--plain {\r\n &.j-button--primary {\r\n background-color: color.adjust($color-primary, $lightness: 40%);\r\n color: $color-primary;\r\n &:hover {\r\n background-color: $color-primary;\r\n color: $color-white;\r\n }\r\n }\r\n }\r\n\r\n // 圆角\r\n &--round {\r\n border-radius: $border-radius-round;\r\n }\r\n\r\n // 禁用\r\n &--disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n pointer-events: none;\r\n }\r\n\r\n // 加载\r\n &--loading {\r\n opacity: 0.7;\r\n cursor: not-allowed;\r\n pointer-events: none;\r\n }\r\n\r\n &__loading-icon {\r\n display: inline-block;\r\n width: 14px;\r\n height: 14px;\r\n border: 2px solid currentColor;\r\n border-top-color: transparent;\r\n border-radius: 50%;\r\n animation: j-spin 0.6s linear infinite;\r\n }\r\n\r\n @keyframes j-spin {\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n }\r\n}\r\n</style>\r\n","<template>\r\n <div class=\"j-upload-img-container\">\r\n <!-- 多图模式 -->\r\n <template v-if=\"multiple\">\r\n <div class=\"images-wrapper\">\r\n <draggable\r\n v-model=\"imageList\"\r\n class=\"images-list\"\r\n item-key=\"uid\"\r\n :animation=\"200\"\r\n :disabled=\"disabled\"\r\n @end=\"handleDragEnd\"\r\n >\r\n <template #item=\"{ element, index }\">\r\n <div class=\"image-item\">\r\n <el-image\r\n :src=\"element.url\"\r\n :preview-src-list=\"imageList.map(img => img.url)\"\r\n :initial-index=\"index\"\r\n fit=\"cover\"\r\n class=\"image-preview\"\r\n :preview-teleported=\"true\"\r\n :hide-on-click-modal=\"true\"\r\n />\r\n <div v-if=\"!disabled\" class=\"delete-btn\" @click.stop=\"handleRemove(index)\">\r\n <el-icon class=\"icon-delete\">\r\n <Delete />\r\n </el-icon>\r\n </div>\r\n </div>\r\n </template>\r\n </draggable>\r\n\r\n <!-- 多图上传按钮 -->\r\n <el-upload\r\n v-if=\"!disabled && (!limit || imageList.length < limit)\"\r\n class=\"image-uploader\"\r\n :auto-upload=\"false\"\r\n :show-file-list=\"false\"\r\n :on-change=\"handleFileChange\"\r\n :disabled=\"uploading\"\r\n list-type=\"picture-card\"\r\n :accept=\"accept\"\r\n >\r\n <el-icon v-if=\"!uploading\" class=\"uploader-icon\">\r\n <Plus />\r\n </el-icon>\r\n <el-icon v-else class=\"uploader-icon is-loading\">\r\n <Loading />\r\n </el-icon>\r\n </el-upload>\r\n </div>\r\n </template>\r\n\r\n <!-- 单图模式 -->\r\n <template v-else>\r\n <!-- 已有图片:独立展示,hover 显示操作遮罩 -->\r\n <div v-if=\"imageUrl\" class=\"image-item single-image-item\">\r\n <el-image\r\n :src=\"imageUrl\"\r\n fit=\"cover\"\r\n class=\"image-preview\"\r\n />\r\n <div class=\"image-actions\">\r\n <el-icon class=\"action-icon\" @click.stop=\"handlePreviewSingle\">\r\n <ZoomIn />\r\n </el-icon>\r\n <el-icon v-if=\"!disabled\" class=\"action-icon\" @click.stop=\"handleRemoveSingle\">\r\n <Delete />\r\n </el-icon>\r\n </div>\r\n </div>\r\n\r\n <!-- 无图片:显示上传按钮 -->\r\n <el-upload\r\n v-else\r\n class=\"image-uploader\"\r\n :auto-upload=\"false\"\r\n :show-file-list=\"false\"\r\n :on-change=\"handleFileChange\"\r\n :disabled=\"disabled || uploading\"\r\n :accept=\"accept\"\r\n list-type=\"picture-card\"\r\n >\r\n <el-icon class=\"uploader-icon\">\r\n <Plus v-if=\"!uploading\" />\r\n <Loading v-else class=\"is-loading\" />\r\n </el-icon>\r\n </el-upload>\r\n\r\n <!-- 大图预览 -->\r\n <el-image-viewer\r\n v-if=\"showPreview\"\r\n :url-list=\"[imageUrl]\"\r\n :teleported=\"true\"\r\n @close=\"showPreview = false\"\r\n />\r\n </template>\r\n\r\n <div v-if=\"showTipText\" class=\"upload-tip\">\r\n <span>{{ tip }}</span>\r\n <span v-if=\"multiple && limit\"> (最多 {{ limit }} 张)</span>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, watch } from 'vue'\r\nimport { ElMessage, ElImage, ElIcon, ElUpload, ElImageViewer } from 'element-plus'\r\nimport type { UploadFile } from 'element-plus'\r\nimport { Plus, Loading, Delete, ZoomIn } from '@element-plus/icons-vue'\r\nimport draggable from 'vuedraggable'\r\nimport type { ImageItem } from './types'\r\n\r\ndefineOptions({\r\n name: 'JUploadImg'\r\n})\r\n\r\nconst props = withDefaults(defineProps<{\r\n modelValue?: string | string[]\r\n disabled?: boolean\r\n multiple?: boolean\r\n limit?: number\r\n maxSize?: number\r\n accept?: string\r\n tip?: string\r\n showTip?: boolean\r\n /** 自定义上传函数,接收 File 返回图片 URL */\r\n uploadFn?: (file: File) => Promise<string>\r\n}>(), {\r\n modelValue: '',\r\n disabled: false,\r\n multiple: false,\r\n limit: 9,\r\n maxSize: 2,\r\n accept: 'image/jpeg,image/png,image/jpg,image/gif',\r\n tip: '只能上传jpg/png/gif格式的图片,且不超过2MB',\r\n showTip: true,\r\n uploadFn: undefined\r\n})\r\n\r\nconst emit = defineEmits<{\r\n (e: 'update:modelValue', value: string | string[]): void\r\n (e: 'success', url: string): void\r\n (e: 'error', error: any): void\r\n}>()\r\n\r\n// 单图模式\r\nconst imageUrl = ref<string>('')\r\nconst showPreview = ref(false)\r\nconst showTipText = props.showTip\r\n\r\nconst handlePreviewSingle = () => {\r\n showPreview.value = true\r\n}\r\n\r\nconst handleRemoveSingle = () => {\r\n imageUrl.value = ''\r\n emit('update:modelValue', '')\r\n ElMessage.success('删除成功')\r\n}\r\n\r\n// 多图模式\r\nconst imageList = ref<ImageItem[]>([])\r\nconst uploading = ref(false)\r\n\r\n// 初始化图片列表(多图模式)\r\nconst initImageList = (urls: string[]) => {\r\n imageList.value = urls.map((url, index) => ({\r\n uid: Date.now() + index,\r\n url\r\n }))\r\n}\r\n\r\n// 监听外部值变化\r\nwatch(() => props.modelValue, (val) => {\r\n if (props.multiple) {\r\n if (Array.isArray(val) && val.length > 0) {\r\n initImageList(val)\r\n } else {\r\n imageList.value = []\r\n }\r\n } else {\r\n if (typeof val === 'string') {\r\n imageUrl.value = val\r\n } else {\r\n imageUrl.value = ''\r\n }\r\n }\r\n}, { immediate: true })\r\n\r\n// 拖拽结束(多图模式)\r\nconst handleDragEnd = () => {\r\n emitMultipleUpdate()\r\n}\r\n\r\n// 删除图片(多图模式)\r\nconst handleRemove = (index: number) => {\r\n imageList.value.splice(index, 1)\r\n emitMultipleUpdate()\r\n ElMessage.success('删除成功')\r\n}\r\n\r\n// 文件改变时触发\r\nconst handleFileChange = async (uploadFile: UploadFile) => {\r\n const file = uploadFile.raw as File\r\n\r\n if (!file) {\r\n ElMessage.error('文件不存在,请重试')\r\n return\r\n }\r\n\r\n if (file.size > props.maxSize * 1024 * 1024) {\r\n ElMessage.error(`图片大小不能超过 ${props.maxSize}MB`)\r\n return\r\n }\r\n\r\n if (!props.uploadFn) {\r\n ElMessage.error('未配置上传函数 (uploadFn)')\r\n return\r\n }\r\n\r\n try {\r\n uploading.value = true\r\n const url = await props.uploadFn(file)\r\n\r\n if (props.multiple) {\r\n imageList.value.push({ uid: Date.now(), url })\r\n emitMultipleUpdate()\r\n } else {\r\n imageUrl.value = url\r\n emit('update:modelValue', url)\r\n }\r\n\r\n emit('success', url)\r\n ElMessage.success('上传成功')\r\n } catch (error) {\r\n console.error('上传出错:', error)\r\n ElMessage.error('上传失败,请重试')\r\n emit('error', error)\r\n } finally {\r\n uploading.value = false\r\n }\r\n}\r\n\r\n// 触发多图更新\r\nconst emitMultipleUpdate = () => {\r\n const urls = imageList.value.map(item => item.url)\r\n emit('update:modelValue', urls)\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.j-upload-img-container {\r\n display: inline-block;\r\n}\r\n\r\n/* 多图模式样式 */\r\n.images-wrapper {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n align-items: flex-start;\r\n}\r\n\r\n.images-list {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n}\r\n\r\n.image-item {\r\n position: relative;\r\n width: 74px;\r\n height: 74px;\r\n border: 1px solid var(--el-border-color);\r\n border-radius: 6px;\r\n overflow: hidden;\r\n cursor: move;\r\n}\r\n\r\n.image-preview {\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n.delete-btn {\r\n position: absolute;\r\n top: 2px;\r\n right: 2px;\r\n width: 20px;\r\n height: 20px;\r\n background-color: rgba(0, 0, 0, 0.6);\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n opacity: 0;\r\n transition: opacity 0.3s;\r\n cursor: pointer;\r\n z-index: 1;\r\n}\r\n\r\n.image-item:hover .delete-btn {\r\n opacity: 1;\r\n}\r\n\r\n.delete-btn:hover {\r\n background-color: rgba(0, 0, 0, 0.8);\r\n}\r\n\r\n.icon-delete {\r\n font-size: 12px;\r\n color: #fff;\r\n}\r\n\r\n/* 单图和多图共用样式 */\r\n.image-uploader {\r\n display: inline-block;\r\n vertical-align: top;\r\n}\r\n\r\n.image-uploader :deep(.el-upload) {\r\n border: 1px dashed var(--el-border-color);\r\n border-radius: 6px;\r\n cursor: pointer;\r\n position: relative;\r\n overflow: hidden;\r\n transition: var(--el-transition-duration-fast);\r\n width: 74px !important;\r\n height: 74px !important;\r\n}\r\n\r\n.image-uploader :deep(.el-upload:hover) {\r\n border-color: var(--el-color-primary);\r\n}\r\n\r\n.uploader-icon {\r\n font-size: 20px;\r\n color: #8c939d;\r\n width: 74px;\r\n height: 74px;\r\n text-align: center;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.single-image-item {\r\n cursor: default;\r\n}\r\n\r\n.image-actions {\r\n position: absolute;\r\n inset: 0;\r\n background-color: rgba(0, 0, 0, 0.5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 12px;\r\n opacity: 0;\r\n transition: opacity 0.3s;\r\n}\r\n\r\n.single-image-item:hover .image-actions,\r\n.image-item:hover .image-actions {\r\n opacity: 1;\r\n}\r\n\r\n.action-icon {\r\n font-size: 18px;\r\n color: #fff;\r\n cursor: pointer;\r\n transition: transform 0.2s;\r\n}\r\n\r\n.action-icon:hover {\r\n transform: scale(1.2);\r\n}\r\n\r\n.upload-tip {\r\n margin-top: 8px;\r\n font-size: 12px;\r\n color: #909399;\r\n line-height: 1.5;\r\n}\r\n</style>\r\n","<template>\r\n <Icon v-if=\"icon\" :icon=\"icon\" :width=\"size\" :height=\"size\" v-bind=\"$attrs\" />\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { Icon } from '@iconify/vue'\r\n\r\ndefineOptions({\r\n name: 'JIconRender'\r\n})\r\n\r\nwithDefaults(defineProps<{\r\n icon: string\r\n size?: string | number\r\n}>(), {\r\n size: 24,\r\n})\r\n</script>\r\n","<template>\r\n <el-card shadow=\"never\" class=\"j-search-header-card\">\r\n <el-form inline class=\"search-form\">\r\n <div\r\n ref=\"formItemsRef\"\r\n class=\"form-items-wrapper\"\r\n :class=\"{ 'is-animated': isAnimated }\"\r\n >\r\n <slot />\r\n </div>\r\n </el-form>\r\n\r\n <div class=\"action-bar\" :style=\"{ marginTop: expanded ? '0px' : '10px' }\">\r\n <div class=\"action-left\">\r\n <el-button v-if=\"showAdd\" type=\"primary\" :icon=\"Plus\" @click=\"emit('add')\">\r\n {{ addText }}\r\n </el-button>\r\n <el-button\r\n v-if=\"showBatchDelete\"\r\n type=\"danger\"\r\n :icon=\"Delete\"\r\n :disabled=\"selectedCount === 0\"\r\n @click=\"emit('batchDelete')\"\r\n >\r\n 批量删除{{ selectedCount ? `(${selectedCount})` : '' }}\r\n </el-button>\r\n <el-button v-if=\"showSearch\" type=\"primary\" :icon=\"Search\" @click=\"emit('search')\">搜索</el-button>\r\n <el-button v-if=\"showReset\" :icon=\"Refresh\" @click=\"emit('reset')\">重置</el-button>\r\n <slot name=\"actions\" />\r\n </div>\r\n <el-button\r\n v-if=\"shouldCollapse\"\r\n link\r\n type=\"primary\"\r\n @click=\"toggleExpand\"\r\n >\r\n {{ expanded ? '收起' : '展开' }}\r\n <el-icon class=\"toggle-icon\" :class=\"{ 'is-expanded': expanded }\">\r\n <ArrowDown />\r\n </el-icon>\r\n </el-button>\r\n </div>\r\n </el-card>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed, onMounted, onBeforeUnmount } from 'vue'\r\nimport { ElCard, ElForm, ElButton, ElIcon } from 'element-plus'\r\nimport { Search, Refresh, Plus, Delete, ArrowDown } from '@element-plus/icons-vue'\r\n\r\ndefineOptions({\r\n name: 'JSearchHeader'\r\n})\r\n\r\nconst props = withDefaults(defineProps<{\r\n selectedCount?: number\r\n addText?: string\r\n defaultVisible?: number\r\n showAdd?: boolean\r\n showBatchDelete?: boolean\r\n showSearch?: boolean\r\n showReset?: boolean\r\n}>(), {\r\n selectedCount: 0,\r\n addText: '新增',\r\n defaultVisible: 5,\r\n showAdd: true,\r\n showBatchDelete: true,\r\n showSearch: true,\r\n showReset: true\r\n})\r\n\r\nconst emit = defineEmits<{\r\n search: []\r\n reset: []\r\n add: []\r\n batchDelete: []\r\n}>()\r\n\r\nconst formItemsRef = ref<HTMLElement>()\r\nconst expanded = ref(false)\r\nconst isAnimated = ref(false)\r\nconst itemCount = ref(0)\r\nconst collapsedHeight = ref(0)\r\n\r\nconst shouldCollapse = computed(() => itemCount.value > props.defaultVisible)\r\n\r\nconst measureItems = () => {\r\n if (!formItemsRef.value) return\r\n const items = Array.from(formItemsRef.value.children) as HTMLElement[]\r\n itemCount.value = items.length\r\n\r\n const lastVisibleItem = items[props.defaultVisible - 1]\r\n if (lastVisibleItem && formItemsRef.value) {\r\n const wrapperRect = formItemsRef.value.getBoundingClientRect()\r\n const lastVisibleRect = lastVisibleItem.getBoundingClientRect()\r\n collapsedHeight.value = lastVisibleRect.bottom - wrapperRect.top\r\n }\r\n}\r\n\r\nconst toggleExpand = () => {\r\n const el = formItemsRef.value\r\n if (!el) return\r\n\r\n if (!expanded.value) {\r\n expanded.value = true\r\n el.style.maxHeight = el.scrollHeight + 'px'\r\n const onEnd = () => {\r\n el.style.maxHeight = 'none'\r\n el.removeEventListener('transitionend', onEnd)\r\n }\r\n el.addEventListener('transitionend', onEnd)\r\n } else {\r\n measureItems()\r\n expanded.value = false\r\n el.style.maxHeight = el.scrollHeight + 'px'\r\n el.offsetHeight\r\n el.style.maxHeight = collapsedHeight.value + 'px'\r\n }\r\n}\r\n\r\nlet observer: MutationObserver | null = null\r\n\r\nonMounted(() => {\r\n measureItems()\r\n if (shouldCollapse.value && formItemsRef.value) {\r\n formItemsRef.value.style.maxHeight = collapsedHeight.value + 'px'\r\n }\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(() => {\r\n isAnimated.value = true\r\n })\r\n })\r\n if (formItemsRef.value) {\r\n observer = new MutationObserver(() => {\r\n measureItems()\r\n if (shouldCollapse.value && !expanded.value && formItemsRef.value) {\r\n formItemsRef.value.style.maxHeight = collapsedHeight.value + 'px'\r\n }\r\n })\r\n observer.observe(formItemsRef.value, { childList: true })\r\n }\r\n})\r\n\r\nonBeforeUnmount(() => {\r\n observer?.disconnect()\r\n})\r\n</script>\r\n\r\n<style scoped>\r\n.j-search-header-card :deep(.el-card__body) {\r\n padding: 16px 20px 12px;\r\n}\r\n\r\n.search-form {\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n gap: 0;\r\n}\r\n\r\n.form-items-wrapper {\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: center;\r\n overflow: hidden;\r\n}\r\n\r\n.form-items-wrapper.is-animated {\r\n transition: max-height 0.3s ease-in-out;\r\n}\r\n\r\n.form-items-wrapper :deep(.el-form-item) {\r\n margin-bottom: 10px;\r\n margin-right: 16px;\r\n}\r\n\r\n.action-bar {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding-top: 10px;\r\n border-top: 1px solid #ebeef5;\r\n}\r\n\r\n.action-left {\r\n display: flex;\r\n gap: 8px;\r\n}\r\n\r\n.toggle-icon {\r\n margin-left: 2px;\r\n transition: transform 0.25s;\r\n}\r\n\r\n.toggle-icon.is-expanded {\r\n transform: rotate(180deg);\r\n}\r\n</style>\r\n","<template>\r\n <el-dialog\r\n v-model=\"visible\"\r\n :title=\"props.title\"\r\n width=\"900px\"\r\n :close-on-click-modal=\"false\"\r\n @open=\"handleOpen\"\r\n @close=\"handleClose\"\r\n >\r\n <!-- 上传区域 -->\r\n <el-card shadow=\"never\" class=\"j-import-upload-card\">\r\n <div class=\"j-import-upload-card-title\">导入 EXCEL</div>\r\n <el-divider style=\"margin: 10px 0\" />\r\n <div class=\"j-import-upload-row\">\r\n <el-upload\r\n accept=\".xlsx,.xls\"\r\n :auto-upload=\"false\"\r\n :show-file-list=\"false\"\r\n :on-change=\"handleFileChange\"\r\n >\r\n <el-button size=\"small\">点击上传</el-button>\r\n </el-upload>\r\n <el-link\r\n v-if=\"dataColumns.length\"\r\n type=\"primary\"\r\n class=\"j-import-no-wrap\"\r\n @click=\"handleDownloadTemplate\"\r\n >\r\n 下载导入模板.xlsx\r\n </el-link>\r\n </div>\r\n </el-card>\r\n\r\n <!-- 统计信息 + 确认导入 -->\r\n <el-row class=\"j-import-stats-row\" :gutter=\"20\" align=\"middle\">\r\n <el-col :span=\"18\">\r\n <el-row class=\"j-import-stats-cols\">\r\n <el-col :span=\"4\" class=\"j-import-stat-item\">\r\n <div class=\"j-import-stat-num\">{{ stats.total }}</div>\r\n <div class=\"j-import-stat-label\">导入数量</div>\r\n </el-col>\r\n <el-col :span=\"4\" class=\"j-import-stat-item\">\r\n <div class=\"j-import-stat-num\">{{ stats.fail }}</div>\r\n <div class=\"j-import-stat-label\">失败数量</div>\r\n </el-col>\r\n <el-col :span=\"4\" class=\"j-import-stat-item\">\r\n <div class=\"j-import-stat-num\">{{ stats.success }}</div>\r\n <div class=\"j-import-stat-label\">成功数量</div>\r\n </el-col>\r\n </el-row>\r\n </el-col>\r\n <el-col :span=\"6\" class=\"j-import-confirm-col\">\r\n <el-button\r\n type=\"primary\"\r\n size=\"small\"\r\n :loading=\"submitting\"\r\n :disabled=\"!renderData.length\"\r\n @click=\"handleConfirm\"\r\n >\r\n 确认导入\r\n </el-button>\r\n </el-col>\r\n </el-row>\r\n\r\n <!-- 数据表格 -->\r\n <el-table :data=\"renderData\" border size=\"small\" max-height=\"360\" class=\"j-import-data-table\">\r\n <el-table-column\r\n v-for=\"col in dataColumns\"\r\n :key=\"col.prop\"\r\n :prop=\"col.prop\"\r\n :label=\"col.label\"\r\n :min-width=\"120\"\r\n show-overflow-tooltip\r\n />\r\n <el-table-column label=\"状态\" width=\"110\" align=\"center\" fixed=\"right\">\r\n <template #default=\"{ row }\">\r\n <span v-if=\"row._status === -1\" class=\"j-import-status-fail\">\r\n {{ row._error || '创建失败' }}\r\n </span>\r\n <span v-else>{{ statusMap[row._status] }}</span>\r\n </template>\r\n </el-table-column>\r\n <el-table-column label=\"操作\" width=\"80\" align=\"center\" fixed=\"right\">\r\n <template #default=\"{ $index, row }\">\r\n <el-button\r\n v-if=\"row._status === 0\"\r\n size=\"small\"\r\n @click=\"handleDel($index)\"\r\n >\r\n 删除\r\n </el-button>\r\n </template>\r\n </el-table-column>\r\n </el-table>\r\n\r\n <template #footer>\r\n <el-button @click=\"handleClose\">关闭</el-button>\r\n </template>\r\n </el-dialog>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, computed } from 'vue'\r\nimport { ElMessage, ElDialog, ElCard, ElDivider, ElUpload, ElButton, ElLink, ElRow, ElCol, ElTable, ElTableColumn } from 'element-plus'\r\nimport type { UploadFile } from 'element-plus'\r\nimport * as XLSX from 'xlsx'\r\nimport type { JImportExcelProps } from './types'\r\n\r\ndefineOptions({ name: 'JImportExcel' })\r\n\r\nconst props = withDefaults(defineProps<JImportExcelProps>(), {\r\n excludeFields: () => ['id', 'ctime', 'mtime'],\r\n title: 'Excel 批量导入',\r\n})\r\n\r\nconst emit = defineEmits<{\r\n success: []\r\n}>()\r\n\r\nconst visible = defineModel<boolean>({ default: false })\r\nconst submitting = ref(false)\r\nconst fieldMap = ref<Record<string, string>>({})\r\nconst renderData = ref<Record<string, any>[]>([])\r\nconst stats = ref({ total: 0, success: 0, fail: 0 })\r\n\r\nconst statusMap: Record<number, string> = {\r\n 0: '待创建',\r\n 1: '创建成功',\r\n 2: '创建中',\r\n [-1]: '创建失败',\r\n}\r\n\r\n/** 过滤后的表头列 */\r\nconst dataColumns = computed(() => {\r\n return Object.entries(fieldMap.value)\r\n .filter(([key]) => !props.excludeFields.includes(key))\r\n .map(([key, label]) => ({ id: key, label, prop: key }))\r\n})\r\n\r\n/** 弹窗打开时获取字段列表 */\r\nconst handleOpen = async () => {\r\n try {\r\n const res = await props.getFieldListApi()\r\n fieldMap.value = res.data.tableFieldsInfo ?? {}\r\n } catch {\r\n ElMessage.error('获取字段列表失败')\r\n }\r\n}\r\n\r\n/** 文件上传解析 */\r\nconst handleFileChange = (uploadFile: UploadFile) => {\r\n const raw = uploadFile.raw\r\n if (!raw) return\r\n\r\n const validTypes = [\r\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\r\n 'application/vnd.ms-excel',\r\n ]\r\n if (!validTypes.includes(raw.type) && !raw.name.match(/\\.xlsx?$/i)) {\r\n ElMessage.warning('请上传 .xlsx 或 .xls 格式文件')\r\n return\r\n }\r\n\r\n const reader = new FileReader()\r\n reader.onload = (e) => {\r\n try {\r\n const workbook = XLSX.read(e.target!.result, { type: 'binary' })\r\n const wsName = workbook.SheetNames[0] as string\r\n const ws = workbook.Sheets[wsName]!\r\n const rows = XLSX.utils.sheet_to_json(ws, {\r\n header: 1,\r\n defval: '',\r\n }) as any[][]\r\n\r\n const dataRows = rows.slice(1).filter((row) => row.some((cell) => cell !== ''))\r\n\r\n if (!dataRows.length) {\r\n ElMessage.warning('文件内容为空')\r\n return\r\n }\r\n\r\n // 按后端字段顺序一一映射,空单元格由 defval 补 '',避免后续列顶上来\r\n const list: Record<string, any>[] = dataRows.map((row) => {\r\n const item: Record<string, any> = { _status: 0, _error: '' }\r\n dataColumns.value.forEach((col, index) => {\r\n item[col.prop] = row[index] !== undefined ? row[index] : ''\r\n })\r\n return item\r\n })\r\n\r\n renderData.value = list\r\n stats.value = { total: list.length, success: 0, fail: 0 }\r\n } catch {\r\n ElMessage.error('解析文件失败,请检查文件格式')\r\n }\r\n }\r\n reader.readAsBinaryString(raw)\r\n}\r\n\r\n/** 删除行 */\r\nconst handleDel = (idx: number) => {\r\n renderData.value.splice(idx, 1)\r\n stats.value.total = renderData.value.length\r\n}\r\n\r\n/** 确认导入 */\r\nconst handleConfirm = async () => {\r\n const data = renderData.value\r\n .filter((row) => row._status === 0)\r\n .map(({ _status, _error, ...rest }) => rest)\r\n\r\n if (!data.length) {\r\n ElMessage.warning('没有可导入的数据')\r\n return\r\n }\r\n\r\n submitting.value = true\r\n try {\r\n const res = await props.importApi(data)\r\n if (res.code === 1) {\r\n // 全部成功\r\n renderData.value.forEach((row) => {\r\n if (row._status === 0) row._status = 1\r\n })\r\n stats.value.success = renderData.value.filter((r) => r._status === 1).length\r\n ElMessage.success('导入成功')\r\n emit('success')\r\n } else {\r\n ElMessage.error(res.msg || '导入失败')\r\n }\r\n } catch {\r\n ElMessage.error('导入失败,请重试')\r\n } finally {\r\n submitting.value = false\r\n }\r\n}\r\n\r\n/** 下载导入模板 */\r\nconst handleDownloadTemplate = () => {\r\n try {\r\n const wb = XLSX.utils.book_new()\r\n const headers = dataColumns.value.map((col) => col.label)\r\n const tr: Record<string, string> = {}\r\n headers.forEach((h) => (tr[h] = ''))\r\n const ws = XLSX.utils.json_to_sheet([tr])\r\n XLSX.utils.book_append_sheet(wb, ws, '模板')\r\n XLSX.writeFile(wb, '导入模板.xlsx')\r\n } catch {\r\n ElMessage.error('模板下载失败')\r\n }\r\n}\r\n\r\nconst handleClose = () => {\r\n if (!submitting.value) {\r\n visible.value = false\r\n renderData.value = []\r\n stats.value = { total: 0, success: 0, fail: 0 }\r\n }\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.j-import-upload-card {\r\n margin-bottom: 16px;\r\n}\r\n.j-import-upload-card-title {\r\n font-size: 14px;\r\n color: #606266;\r\n}\r\n.j-import-upload-row {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n}\r\n.j-import-no-wrap {\r\n white-space: nowrap;\r\n}\r\n.j-import-stats-row {\r\n margin: 12px 0;\r\n}\r\n.j-import-stats-cols {\r\n text-align: center;\r\n line-height: 1.5;\r\n}\r\n.j-import-stat-item {\r\n padding: 0 8px;\r\n}\r\n.j-import-stat-num {\r\n font-size: 20px;\r\n}\r\n.j-import-stat-label {\r\n font-size: 12px;\r\n color: #909399;\r\n}\r\n.j-import-confirm-col {\r\n text-align: right;\r\n padding-top: 10px;\r\n}\r\n.j-import-data-table {\r\n margin-top: 10px;\r\n}\r\n.j-import-status-fail {\r\n color: #f56c6c;\r\n font-size: 12px;\r\n}\r\n</style>\r\n","<template>\r\n <!-- 有子菜单:渲染 el-sub-menu -->\r\n <el-sub-menu\r\n v-if=\"menuItem.children && menuItem.children.length > 0\"\r\n :index=\"menuItem.path\"\r\n :class=\"[`j-sidebar__depth-${depth}`]\"\r\n >\r\n <template #title>\r\n <JIconRender v-if=\"menuItem.icon && depth === 0\" :icon=\"menuItem.icon\" />\r\n <span class=\"j-sidebar__menu-item-title\">{{ menuItem.title || menuItem.name }}</span>\r\n </template>\r\n <!-- 递归渲染子菜单 -->\r\n <JSideMenuItem\r\n v-for=\"child in menuItem.children\"\r\n :key=\"child.path\"\r\n :menu-item=\"child\"\r\n :is-collapse=\"isCollapse\"\r\n :depth=\"depth + 1\"\r\n @menu-click=\"(item) => emit('menu-click', item)\"\r\n />\r\n </el-sub-menu>\r\n\r\n <!-- 无子菜单:渲染 el-menu-item -->\r\n <el-menu-item\r\n v-else\r\n :index=\"menuItem.path\"\r\n :class=\"[`j-sidebar__depth-${depth}`]\"\r\n @click=\"handleClick\"\r\n >\r\n <JIconRender v-if=\"menuItem.icon && depth === 0\" :icon=\"menuItem.icon\" />\r\n <template #title>\r\n <span>{{ menuItem.title || menuItem.name }}</span>\r\n </template>\r\n </el-menu-item>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport type { SidebarMenuItem } from './types'\r\nimport { ElSubMenu, ElMenuItem } from 'element-plus'\r\nimport { JIconRender } from '../JIconRender'\r\n\r\ndefineOptions({\r\n name: 'JSideMenuItem'\r\n})\r\n\r\ninterface Props {\r\n menuItem: SidebarMenuItem\r\n isCollapse?: boolean\r\n depth?: number\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), { depth: 0 })\r\n\r\nconst emit = defineEmits<{\r\n 'menu-click': [item: SidebarMenuItem]\r\n}>()\r\n\r\nconst handleClick = () => {\r\n emit('menu-click', props.menuItem)\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.j-sidebar__menu-item-title {\r\n padding: 0 10px;\r\n}\r\n\r\n/* 二级菜单:灰色标题,作为分类标签 */\r\n.j-sidebar__depth-1 > :deep(.el-sub-menu__title) {\r\n color: #909399;\r\n font-size: 13px;\r\n}\r\n\r\n/* 二级叶子菜单(无子项)也用灰色 */\r\n:deep(.j-sidebar__depth-1.el-menu-item) {\r\n color: #909399;\r\n font-size: 13px;\r\n}\r\n\r\n/* 三级菜单:文字稍大 */\r\n:deep(.j-sidebar__depth-2.el-menu-item) {\r\n font-size: 15px;\r\n}\r\n</style>\r\n","<template>\r\n <div\r\n :class=\"['j-sidebar', innerCollapsed ? 'j-sidebar--collapsed' : 'j-sidebar--expanded']\"\r\n :style=\"{ width: innerCollapsed ? `${collapsedWidth}px` : `${expandedWidth}px` }\"\r\n >\r\n <!-- Logo 区域 -->\r\n <div class=\"j-sidebar__logo\">\r\n <slot name=\"logo\" :collapsed=\"innerCollapsed\">\r\n <h2 class=\"j-sidebar__title\">\r\n {{ innerCollapsed ? (collapsedTitle || title?.charAt(0) || '') : title }}\r\n </h2>\r\n </slot>\r\n </div>\r\n\r\n <!-- 菜单区域 -->\r\n <div class=\"j-sidebar__menu-wrapper\">\r\n <el-menu\r\n :default-active=\"activeMenu\"\r\n class=\"j-sidebar__menu\"\r\n :router=\"router\"\r\n :collapse=\"innerCollapsed\"\r\n :collapse-transition=\"false\"\r\n >\r\n <JSideMenuItem\r\n v-for=\"route in menus\"\r\n :key=\"route.path\"\r\n :menu-item=\"route\"\r\n :is-collapse=\"innerCollapsed\"\r\n @menu-click=\"(item) => emit('menu-click', item)\"\r\n />\r\n </el-menu>\r\n </div>\r\n\r\n <!-- 底部折叠按钮 -->\r\n <div class=\"j-sidebar__footer\">\r\n <slot name=\"footer\" :collapsed=\"innerCollapsed\" :toggle=\"toggleCollapse\">\r\n <button\r\n class=\"j-sidebar__collapse-btn\"\r\n @click=\"toggleCollapse\"\r\n >\r\n <JIconRender :icon=\"innerCollapsed ? 'mdi:chevron-right' : 'mdi:chevron-left'\" />\r\n </button>\r\n </slot>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, watch } from 'vue'\r\nimport { ElMenu } from 'element-plus'\r\nimport type { SidebarMenuItem } from './types'\r\nimport JSideMenuItem from './JSideMenuItem.vue'\r\nimport { JIconRender } from '../JIconRender'\r\n\r\ndefineOptions({\r\n name: 'JSidebar'\r\n})\r\n\r\ninterface Props {\r\n menus: SidebarMenuItem[]\r\n activeMenu?: string\r\n title?: string\r\n collapsedTitle?: string\r\n collapsed?: boolean\r\n collapsedWidth?: number\r\n expandedWidth?: number\r\n router?: boolean\r\n}\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n activeMenu: '',\r\n title: '',\r\n collapsedTitle: '',\r\n collapsed: false,\r\n collapsedWidth: 80,\r\n expandedWidth: 200,\r\n router: true,\r\n})\r\n\r\nconst emit = defineEmits<{\r\n 'update:collapsed': [value: boolean]\r\n 'menu-click': [item: SidebarMenuItem]\r\n}>()\r\n\r\nconst innerCollapsed = ref(props.collapsed)\r\n\r\nwatch(() => props.collapsed, (val) => {\r\n innerCollapsed.value = val\r\n})\r\n\r\nconst toggleCollapse = () => {\r\n innerCollapsed.value = !innerCollapsed.value\r\n emit('update:collapsed', innerCollapsed.value)\r\n}\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.j-sidebar {\r\n position: relative;\r\n background-color: $color-white;\r\n box-shadow: 2px 0 6px rgba(0, 21, 41, 0.08);\r\n overflow-x: hidden;\r\n transition: width 0.3s ease-in-out;\r\n flex-shrink: 0;\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n}\r\n\r\n.j-sidebar__logo {\r\n padding: 0 $spacing-md;\r\n display: flex;\r\n align-items: center;\r\n height: 50px;\r\n flex-shrink: 0;\r\n}\r\n\r\n\r\n.j-sidebar__title {\r\n margin: 0;\r\n font-size: $font-size-lg;\r\n font-weight: bold;\r\n color: $color-primary;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n}\r\n\r\n.j-sidebar__menu-wrapper {\r\n flex: 1;\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n}\r\n\r\n.j-sidebar__menu {\r\n border: none;\r\n width: 100%;\r\n}\r\n\r\n.j-sidebar__footer {\r\n flex-shrink: 0;\r\n padding: $spacing-sm;\r\n display: flex;\r\n}\r\n\r\n// 折叠状态:覆盖 el-menu 样式,图标+文字上下排列\r\n.j-sidebar--collapsed {\r\n :deep(.el-menu--collapse) {\r\n width: 100%;\r\n\r\n .el-menu-item,\r\n .el-sub-menu__title {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n height: auto;\r\n line-height: normal;\r\n padding: $spacing-sm 0 !important;\r\n\r\n .el-icon,\r\n .iconify {\r\n margin: 0;\r\n }\r\n\r\n span {\r\n display: block !important;\r\n visibility: visible !important;\r\n overflow: visible !important;\r\n width: auto !important;\r\n height: auto !important;\r\n font-size: $font-size-xs;\r\n margin-top: $spacing-xs;\r\n }\r\n }\r\n\r\n // 隐藏子菜单展开箭头\r\n .el-sub-menu__icon-arrow {\r\n display: none;\r\n }\r\n }\r\n}\r\n\r\n.j-sidebar__collapse-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: $spacing-sm;\r\n border: none;\r\n border-radius: $border-radius-base;\r\n background-color: transparent;\r\n color: $color-text-secondary;\r\n cursor: pointer;\r\n transition: $transition-fast;\r\n\r\n &:hover {\r\n background-color: $color-bg-base;\r\n color: $color-primary;\r\n }\r\n\r\n}\r\n</style>\r\n","<template>\n <div class=\"j-admin-layout\" :style=\"layoutStyle\">\n <JSidebar\n v-if=\"sideMenus.length > 0\"\n v-model:collapsed=\"innerCollapsed\"\n :menus=\"sideMenus\"\n :active-menu=\"activeMenu\"\n :title=\"title\"\n :collapsed-title=\"collapsedTitle\"\n :collapsed-width=\"sidebarCollapsedWidth\"\n :expanded-width=\"sidebarExpandedWidth\"\n @menu-click=\"handleSideMenuClick\"\n >\n <template v-if=\"$slots.sidebarFooter\" #footer=\"{ collapsed: sidebarCollapsed, toggle }\">\n <slot name=\"sidebarFooter\" :collapsed=\"sidebarCollapsed\" :toggle=\"toggle\" />\n </template>\n </JSidebar>\n\n <div class=\"j-admin-layout__right-panel\">\n <div class=\"j-admin-layout__header\">\n <div class=\"j-admin-layout__header-left\">\n <div v-if=\"sideMenus.length === 0\" class=\"j-admin-layout__logo\">\n <slot name=\"logo\">\n <h2>{{ logoTitle || title }}</h2>\n </slot>\n </div>\n\n <el-menu\n mode=\"horizontal\"\n :default-active=\"activeTopMenu\"\n class=\"j-admin-layout__top-menu\"\n @select=\"handleTopMenuSelect\"\n >\n <el-menu-item\n v-for=\"menu in topMenus\"\n :key=\"menu.path\"\n :index=\"menu.path\"\n >\n <JIconRender v-if=\"menu.icon\" :icon=\"menu.icon\" class=\"j-admin-layout__top-menu-icon\" />\n <span>{{ menu.title || menu.name }}</span>\n </el-menu-item>\n </el-menu>\n </div>\n\n <div class=\"j-admin-layout__header-right\">\n <slot name=\"headerRight\" :username=\"username\">\n <el-dropdown v-if=\"showProfile || showLogout\">\n <span class=\"j-admin-layout__user\">\n {{ username }}\n <el-icon>\n <ArrowDown />\n </el-icon>\n </span>\n <template #dropdown>\n <el-dropdown-menu>\n <el-dropdown-item v-if=\"showProfile\" @click=\"emit('profile')\">\n {{ profileText }}\n </el-dropdown-item>\n <el-dropdown-item v-if=\"showLogout\" @click=\"emit('logout')\">\n {{ logoutText }}\n </el-dropdown-item>\n </el-dropdown-menu>\n </template>\n </el-dropdown>\n </slot>\n </div>\n </div>\n\n <div class=\"j-admin-layout__content-container\">\n <slot name=\"tabs\" />\n <div\n :class=\"[\n 'j-admin-layout__content',\n { 'j-admin-layout__content--scrollbar-hidden': hideContentScrollbar }\n ]\"\n >\n <slot />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\nimport { ElMenu, ElMenuItem, ElDropdown, ElDropdownMenu, ElDropdownItem, ElIcon } from 'element-plus'\nimport { ArrowDown } from '@element-plus/icons-vue'\nimport { JSidebar, type SidebarMenuItem } from '../JSidebar'\nimport { JIconRender } from '../JIconRender'\nimport type { AdminLayoutMenuItem } from './types'\n\ndefineOptions({\n name: 'JAdminLayout'\n})\n\ninterface Props {\n topMenus: AdminLayoutMenuItem[]\n sideMenus: AdminLayoutMenuItem[]\n activeTopMenu?: string\n activeMenu?: string\n title?: string\n logoTitle?: string\n collapsedTitle?: string\n collapsed?: boolean\n username?: string\n profileText?: string\n logoutText?: string\n sidebarCollapsedWidth?: number\n sidebarExpandedWidth?: number\n headerHeight?: string\n contentPadding?: string\n contentBackground?: string\n headerBackground?: string\n showProfile?: boolean\n showLogout?: boolean\n hideContentScrollbar?: boolean\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n activeTopMenu: '',\n activeMenu: '',\n title: '',\n logoTitle: '',\n collapsedTitle: '',\n collapsed: false,\n username: '',\n profileText: '个人资料',\n logoutText: '退出登录',\n sidebarCollapsedWidth: 80,\n sidebarExpandedWidth: 200,\n headerHeight: '50px',\n contentPadding: '10px',\n contentBackground: '#f0f2f5',\n headerBackground: '#ffffff',\n showProfile: true,\n showLogout: true,\n hideContentScrollbar: false,\n})\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean]\n 'top-menu-select': [path: string]\n 'side-menu-click': [item: SidebarMenuItem]\n profile: []\n logout: []\n}>()\n\nconst innerCollapsed = computed({\n get: () => props.collapsed,\n set: value => emit('update:collapsed', value),\n})\n\nconst layoutStyle = computed(() => ({\n '--j-admin-layout-header-height': props.headerHeight,\n '--j-admin-layout-content-padding': props.contentPadding,\n '--j-admin-layout-content-bg': props.contentBackground,\n '--j-admin-layout-header-bg': props.headerBackground,\n}))\n\nconst handleTopMenuSelect = (path: string) => {\n emit('top-menu-select', path)\n}\n\nconst handleSideMenuClick = (item: SidebarMenuItem) => {\n emit('side-menu-click', item)\n}\n</script>\n\n<style scoped lang=\"scss\">\n.j-admin-layout {\n width: 100vw;\n height: 100vh;\n display: flex;\n flex-direction: row;\n overflow: hidden;\n}\n\n.j-admin-layout__right-panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background-color: var(--j-admin-layout-content-bg);\n}\n\n.j-admin-layout__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n background-color: var(--j-admin-layout-header-bg);\n box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);\n height: var(--j-admin-layout-header-height);\n flex-shrink: 0;\n z-index: 100;\n}\n\n.j-admin-layout__header-left {\n display: flex;\n align-items: center;\n flex: 1;\n height: 100%;\n min-width: 0;\n}\n\n.j-admin-layout__logo {\n padding: 0 $spacing-md;\n display: flex;\n align-items: center;\n height: var(--j-admin-layout-header-height);\n flex-shrink: 0;\n}\n\n.j-admin-layout__logo h2 {\n margin: 0;\n font-size: $font-size-lg;\n font-weight: bold;\n color: $color-primary;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.j-admin-layout__top-menu {\n flex: 1;\n height: var(--j-admin-layout-header-height);\n border-bottom: none;\n min-width: 0;\n}\n\n.j-admin-layout__top-menu-icon {\n margin-right: $spacing-xs;\n}\n\n.j-admin-layout__header-right {\n display: flex;\n align-items: center;\n gap: $spacing-md;\n padding-right: $spacing-md;\n flex-shrink: 0;\n}\n\n.j-admin-layout__user {\n cursor: pointer;\n display: flex;\n align-items: center;\n color: $color-text-regular;\n}\n\n.j-admin-layout__user:hover {\n color: $color-primary;\n}\n\n.j-admin-layout__content-container {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n background-color: var(--j-admin-layout-content-bg);\n}\n\n.j-admin-layout__content {\n padding: var(--j-admin-layout-content-padding);\n flex: 1;\n overflow: auto;\n}\n\n.j-admin-layout__content--scrollbar-hidden {\n scrollbar-width: none;\n -ms-overflow-style: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n}\n</style>\n","<template>\n <el-dialog\n :model-value=\"visible\"\n title=\"查看产品\"\n width=\"1200px\"\n top=\"4vh\"\n :close-on-click-modal=\"false\"\n @update:model-value=\"(v: boolean) => emit('update:visible', v)\"\n >\n <div v-loading=\"loading\" class=\"pdd-body\">\n <template v-if=\"detail\">\n <!-- ===== 基本信息 ===== -->\n <div class=\"pdd-title\">基本信息</div>\n <el-descriptions :column=\"3\" border size=\"small\">\n <el-descriptions-item :label=\"isSpu ? '中文款式' : '中文品名'\">{{ fmt(nameCn) }}</el-descriptions-item>\n <el-descriptions-item :label=\"isSpu ? '英文款式' : '英文品名'\">{{ fmt(nameEn) }}</el-descriptions-item>\n <el-descriptions-item :label=\"isSpu ? 'SPU' : 'SKU'\">{{ fmt(mainCode) }}</el-descriptions-item>\n <el-descriptions-item label=\"产品类型\">{{ productTypeLabel }}</el-descriptions-item>\n <el-descriptions-item label=\"采购公司\">{{ fmt(peNames) }}</el-descriptions-item>\n <el-descriptions-item label=\"状态\">{{ fmt(statusName) }}</el-descriptions-item>\n <el-descriptions-item label=\"品类\">{{ fmt(basic.category_path_name || basic.category_name) }}</el-descriptions-item>\n <el-descriptions-item label=\"品牌\">{{ fmt(brandName) }}</el-descriptions-item>\n <el-descriptions-item label=\"单位\">{{ fmt(unitName) }}</el-descriptions-item>\n <el-descriptions-item label=\"产品标签\">\n <template v-if=\"tagList.length\">\n <el-tag\n v-for=\"t in tagList\"\n :key=\"t.code\"\n size=\"small\"\n class=\"pdd-tag\"\n :style=\"t.color ? { backgroundColor: t.color, borderColor: t.color, color: '#fff' } : {}\"\n >{{ t.name }}</el-tag>\n </template>\n <template v-else>—</template>\n </el-descriptions-item>\n <el-descriptions-item label=\"材质\">{{ fmt(basic.material) }}</el-descriptions-item>\n <el-descriptions-item label=\"型号\">{{ fmt(basic.product_model) }}</el-descriptions-item>\n <el-descriptions-item label=\"开发员\">{{ fmt(basic.develop_leader_name || basic.develop_user) }}</el-descriptions-item>\n <el-descriptions-item label=\"采购员\">{{ fmt(basic.purchase_leader_name || basic.purchase_user) }}</el-descriptions-item>\n <el-descriptions-item label=\"产品运营\">{{ fmt(basic.sales_leader_name || basic.sales_user) }}</el-descriptions-item>\n <el-descriptions-item v-if=\"!isSpu\" label=\"关联SPU\">{{ fmt(basic.spu_code) }}</el-descriptions-item>\n <el-descriptions-item v-if=\"!isSpu\" label=\"产品属性\" :span=\"2\">{{ fmt(skuAttrText) }}</el-descriptions-item>\n <el-descriptions-item label=\"附件\" :span=\"3\">\n <template v-if=\"basicAttachments.length\">\n <a\n v-for=\"(f, i) in basicAttachments\"\n :key=\"i\"\n :href=\"f.url\"\n target=\"_blank\"\n class=\"pdd-file\"\n >{{ f.name }}</a>\n </template>\n <template v-else>—</template>\n </el-descriptions-item>\n <el-descriptions-item label=\"详细描述\" :span=\"3\">\n <div v-if=\"hasDesc\" class=\"pdd-rich\" v-html=\"basic.product_desc\"></div>\n <template v-else>—</template>\n </el-descriptions-item>\n </el-descriptions>\n\n <!-- ===== 产品组成(组合产品 20) ===== -->\n <template v-if=\"productType === '20'\">\n <div class=\"pdd-title\">产品组成</div>\n <el-descriptions :column=\"3\" border size=\"small\">\n <el-descriptions-item label=\"单位加工费\">\n {{ bindSku.unit_process_cost != null && bindSku.unit_process_cost !== '' ? `${bindSku.unit_process_cost} ${bindSku.unit_process_currency_code || ''}` : '—' }}\n </el-descriptions-item>\n <el-descriptions-item label=\"加工备注\" :span=\"2\">{{ fmt(bindSku.unit_process_remark) }}</el-descriptions-item>\n </el-descriptions>\n <el-table :data=\"bindSkuList\" border size=\"small\" class=\"pdd-table\">\n <el-table-column label=\"图片\" width=\"70\" align=\"center\">\n <template #default=\"{ row }\">\n <el-image\n v-if=\"row.image || row.product_image\"\n :src=\"row.image || row.product_image\"\n :preview-src-list=\"[row.image || row.product_image]\"\n preview-teleported\n fit=\"cover\"\n class=\"pdd-thumb\"\n />\n <span v-else>—</span>\n </template>\n </el-table-column>\n <el-table-column label=\"品名\" prop=\"product_name\" min-width=\"140\" show-overflow-tooltip />\n <el-table-column label=\"SKU\" prop=\"sku_code\" min-width=\"120\" show-overflow-tooltip />\n <el-table-column label=\"单位\" min-width=\"70\">\n <template #default=\"{ row }\">{{ fmt(row.unit || row.unit_name) }}</template>\n </el-table-column>\n <el-table-column label=\"数量\" min-width=\"70\">\n <template #default=\"{ row }\">{{ fmt(row.quantity ?? row.sku_quantity) }}</template>\n </el-table-column>\n <el-table-column label=\"品类\" prop=\"category_path_name\" min-width=\"120\" show-overflow-tooltip />\n <el-table-column label=\"型号\" min-width=\"90\">\n <template #default=\"{ row }\">{{ fmt(row.model_no || row.product_model) }}</template>\n </el-table-column>\n <el-table-column label=\"材质\" prop=\"material\" min-width=\"90\" show-overflow-tooltip />\n <el-table-column label=\"单品尺寸\" min-width=\"140\">\n <template #default=\"{ row }\">{{ dimText(row.spec_info?.length, row.spec_info?.width, row.spec_info?.height, row.spec_info?.height_unit || 'cm') }}</template>\n </el-table-column>\n <el-table-column label=\"净重\" min-width=\"80\">\n <template #default=\"{ row }\">{{ weightText(row.spec_info?.net_weight ?? row.net_weight, row.spec_info?.product_unit) }}</template>\n </el-table-column>\n <el-table-column label=\"毛重\" min-width=\"80\">\n <template #default=\"{ row }\">{{ weightText(row.spec_info?.gross_weight ?? row.gross_weight, row.spec_info?.product_unit) }}</template>\n </el-table-column>\n </el-table>\n </template>\n\n <!-- ===== 款式属性(多属性产品 30) ===== -->\n <template v-if=\"isSpu\">\n <div class=\"pdd-title\">款式属性</div>\n <el-table :data=\"styleAttrs\" border size=\"small\" class=\"pdd-table\">\n <el-table-column label=\"属性\" prop=\"attr_name\" width=\"160\" />\n <el-table-column label=\"属性值\">\n <template #default=\"{ row }\">\n <el-tag v-for=\"c in row.childs || []\" :key=\"c.attr_value_code\" size=\"small\" class=\"pdd-tag\">\n {{ c.attr_value_name }}\n </el-tag>\n </template>\n </el-table-column>\n </el-table>\n <div class=\"pdd-subtitle\">关联产品信息</div>\n <el-table :data=\"skuVariants\" border size=\"small\" class=\"pdd-table\">\n <el-table-column label=\"图片\" width=\"70\" align=\"center\">\n <template #default=\"{ row }\">\n <el-image\n v-if=\"row.main_image\"\n :src=\"row.main_image\"\n :preview-src-list=\"[row.main_image]\"\n preview-teleported\n fit=\"cover\"\n class=\"pdd-thumb\"\n />\n <span v-else>—</span>\n </template>\n </el-table-column>\n <el-table-column label=\"SKU\" prop=\"sku_code\" min-width=\"130\" show-overflow-tooltip />\n <el-table-column label=\"中文品名\" prop=\"product_name\" min-width=\"150\" show-overflow-tooltip />\n <el-table-column label=\"英文品名\" min-width=\"150\" show-overflow-tooltip>\n <template #default=\"{ row }\">{{ fmt(row.product_name_en || row.product_en_name) }}</template>\n </el-table-column>\n <el-table-column\n v-for=\"attr in styleAttrs\"\n :key=\"attr.attr_code\"\n :label=\"attr.attr_name\"\n min-width=\"100\"\n >\n <template #default=\"{ row }\">{{ variantAttrText(row, attr) }}</template>\n </el-table-column>\n </el-table>\n </template>\n\n <!-- ===== 规格信息 ===== -->\n <div class=\"pdd-title\">规格信息</div>\n <el-descriptions :column=\"3\" border size=\"small\">\n <el-descriptions-item label=\"单品毛重\">{{ weightText(spec.gross_weight, spec.gross_weight_unit) }}</el-descriptions-item>\n <el-descriptions-item label=\"单品净重\">{{ weightText(spec.net_weight, spec.net_weight_unit) }}</el-descriptions-item>\n <el-descriptions-item label=\"包装重\">{{ weightText(spec.tare_weight, spec.tare_weight_unit) }}</el-descriptions-item>\n <el-descriptions-item label=\"单品尺寸\">{{ dimText(spec.length, spec.width, spec.height) }}</el-descriptions-item>\n <el-descriptions-item label=\"包装尺寸\" :span=\"2\">{{ dimText(spec.tare_length, spec.tare_width, spec.tare_height) }}</el-descriptions-item>\n </el-descriptions>\n <template v-if=\"specBoxList.length\">\n <div class=\"pdd-subtitle\">装箱规格</div>\n <el-table :data=\"specBoxList\" border size=\"small\" class=\"pdd-table\">\n <el-table-column type=\"index\" label=\"序号\" width=\"60\" align=\"center\" />\n <el-table-column label=\"箱规名称\" prop=\"box_name\" min-width=\"130\" show-overflow-tooltip />\n <el-table-column label=\"单箱数量\" min-width=\"90\">\n <template #default=\"{ row }\">{{ row.box_quantity != null ? `${row.box_quantity} pcs` : '—' }}</template>\n </el-table-column>\n <el-table-column label=\"单箱重量\" min-width=\"100\">\n <template #default=\"{ row }\">{{ weightText(row.one_box_weight, row.one_box_unit) }}</template>\n </el-table-column>\n <el-table-column label=\"箱子重量\" min-width=\"100\">\n <template #default=\"{ row }\">{{ weightText(row.box_weight, row.box_unit) }}</template>\n </el-table-column>\n <el-table-column label=\"外箱尺寸\" min-width=\"150\">\n <template #default=\"{ row }\">{{ dimText(row.box_length, row.box_width, row.box_height) }}</template>\n </el-table-column>\n <el-table-column label=\"首选\" width=\"70\" align=\"center\">\n <template #default=\"{ row }\">\n <el-tag v-if=\"Number(row.is_preferred) === 1\" size=\"small\" type=\"success\">首选</el-tag>\n <span v-else>—</span>\n </template>\n </el-table-column>\n </el-table>\n </template>\n\n <!-- ===== 采购信息(单品/组合产品) ===== -->\n <template v-if=\"!isSpu\">\n <div class=\"pdd-title\">采购信息</div>\n <el-descriptions :column=\"3\" border size=\"small\">\n <el-descriptions-item label=\"采购成本\">{{ fmt(purchase.purchase_cost) }}</el-descriptions-item>\n <el-descriptions-item label=\"采购交期\">{{ purchase.delivery_day != null && purchase.delivery_day !== '' ? `${purchase.delivery_day} 天` : '—' }}</el-descriptions-item>\n <el-descriptions-item label=\"采购税率\">{{ purchase.tax_rate != null && purchase.tax_rate !== '' ? `${purchase.tax_rate} %` : '—' }}</el-descriptions-item>\n <el-descriptions-item label=\"采购备注\" :span=\"3\">{{ fmt(purchase.purchase_remark) }}</el-descriptions-item>\n </el-descriptions>\n <template v-if=\"supplierList.length\">\n <div class=\"pdd-subtitle\">报价信息</div>\n <div v-for=\"(sup, si) in supplierList\" :key=\"si\" class=\"pdd-supplier\">\n <div class=\"pdd-supplier-head\">\n <span class=\"pdd-supplier-name\">{{ sup.supplier_name || sup.supplier_code || '—' }}</span>\n <el-tag v-if=\"Number(sup.is_preferred) === 1\" size=\"small\" type=\"success\">首选</el-tag>\n <span class=\"pdd-supplier-meta\">预计交期:{{ sup.delivery_day != null && sup.delivery_day !== '' ? `${sup.delivery_day} 天` : '—' }}</span>\n <span class=\"pdd-supplier-meta\">报价备注:{{ fmt(sup.purchase_remark ?? sup.remark) }}</span>\n </div>\n <el-table :data=\"supplierQuoteRows(sup)\" border size=\"small\">\n <el-table-column label=\"币种\" prop=\"currency\" width=\"80\" />\n <el-table-column label=\"含税\" width=\"70\" align=\"center\">\n <template #default=\"{ row }\">{{ Number(row.is_tax) === 1 ? '是' : '否' }}</template>\n </el-table-column>\n <el-table-column label=\"税率\" width=\"80\">\n <template #default=\"{ row }\">{{ row.tax_rate != null && row.tax_rate !== '' ? `${row.tax_rate} %` : '—' }}</template>\n </el-table-column>\n <el-table-column label=\"采购数量 ≥\" min-width=\"100\">\n <template #default=\"{ row }\">{{ fmt(row.purchase_quantity) }}</template>\n </el-table-column>\n <el-table-column label=\"单价\" min-width=\"100\">\n <template #default=\"{ row }\">{{ fmt(row.purchase_price) }}</template>\n </el-table-column>\n <el-table-column label=\"含税单价\" min-width=\"100\">\n <template #default=\"{ row }\">{{ fmt(row.purchase_price_tax) }}</template>\n </el-table-column>\n </el-table>\n </div>\n </template>\n </template>\n\n <!-- ===== 产品图片(单品/组合产品) ===== -->\n <template v-if=\"!isSpu\">\n <div class=\"pdd-title\">产品图片</div>\n <el-descriptions :column=\"1\" border size=\"small\">\n <el-descriptions-item label=\"主图\">\n <el-image\n v-if=\"mainImage\"\n :src=\"mainImage\"\n :preview-src-list=\"[mainImage]\"\n preview-teleported\n fit=\"cover\"\n class=\"pdd-img\"\n />\n <span v-else>—</span>\n </el-descriptions-item>\n <el-descriptions-item label=\"尺寸图\">\n <template v-if=\"sizeImages.length\">\n <el-image\n v-for=\"(img, i) in sizeImages\"\n :key=\"i\"\n :src=\"img\"\n :preview-src-list=\"sizeImages\"\n :initial-index=\"i\"\n preview-teleported\n fit=\"cover\"\n class=\"pdd-img\"\n />\n </template>\n <span v-else>—</span>\n </el-descriptions-item>\n <el-descriptions-item label=\"卖点图\">\n <template v-if=\"sellingPointImages.length\">\n <el-image\n v-for=\"(img, i) in sellingPointImages\"\n :key=\"i\"\n :src=\"img\"\n :preview-src-list=\"sellingPointImages\"\n :initial-index=\"i\"\n preview-teleported\n fit=\"cover\"\n class=\"pdd-img\"\n />\n </template>\n <span v-else>—</span>\n </el-descriptions-item>\n </el-descriptions>\n </template>\n\n <!-- ===== 申报信息 ===== -->\n <div class=\"pdd-title\">申报信息</div>\n <el-descriptions :column=\"3\" border size=\"small\">\n <el-descriptions-item label=\"中文申报名\">{{ fmt(declaration.declaration_name) }}</el-descriptions-item>\n <el-descriptions-item label=\"英文申报名\">{{ fmt(declaration.declaration_name_en) }}</el-descriptions-item>\n <el-descriptions-item label=\"中文材质\">{{ fmt(declaration.material) }}</el-descriptions-item>\n <el-descriptions-item label=\"英文材质\">{{ fmt(declaration.material_en) }}</el-descriptions-item>\n <el-descriptions-item label=\"中文用途\">{{ fmt(declaration.use) }}</el-descriptions-item>\n <el-descriptions-item label=\"英文用途\">{{ fmt(declaration.use_en) }}</el-descriptions-item>\n <el-descriptions-item label=\"中文功能\">{{ fmt(declaration.usage) }}</el-descriptions-item>\n <el-descriptions-item label=\"英文功能\">{{ fmt(declaration.usage_en) }}</el-descriptions-item>\n <el-descriptions-item label=\"申报价值\">\n {{ declaration.declaration_value != null && declaration.declaration_value !== '' ? `${declaration.declaration_value} ${declaration.declaration_currency_code || ''}` : '—' }}\n </el-descriptions-item>\n <el-descriptions-item label=\"海关编码\">{{ fmt(declaration.hs_code) }}</el-descriptions-item>\n <el-descriptions-item label=\"报关型号\">{{ fmt(declaration.declaration_model) }}</el-descriptions-item>\n <el-descriptions-item label=\"原产地\">{{ fmt(declaration.country_of_origin) }}</el-descriptions-item>\n <el-descriptions-item label=\"境内货源地\">{{ fmt(declaration.domestic_source_location) }}</el-descriptions-item>\n <el-descriptions-item label=\"申报单位\" :span=\"2\">{{ fmt(declarationUnitName) }}</el-descriptions-item>\n </el-descriptions>\n\n <!-- ===== 质检项 ===== -->\n <div class=\"pdd-title\">质检项</div>\n <el-descriptions :column=\"3\" border size=\"small\">\n <el-descriptions-item label=\"质检方式\">{{ qcMethodLabel }}</el-descriptions-item>\n <el-descriptions-item label=\"模板\" :span=\"2\">{{ fmt(qc.template_name || qc.template_id || qc.qc_temp_id) }}</el-descriptions-item>\n <el-descriptions-item label=\"图片\" :span=\"3\">\n <template v-if=\"qcImages.length\">\n <el-image\n v-for=\"(img, i) in qcImages\"\n :key=\"i\"\n :src=\"img\"\n :preview-src-list=\"qcImages\"\n :initial-index=\"i\"\n preview-teleported\n fit=\"cover\"\n class=\"pdd-img\"\n />\n </template>\n <span v-else>—</span>\n </el-descriptions-item>\n <el-descriptions-item label=\"附件\" :span=\"3\">\n <template v-if=\"qcAttachments.length\">\n <a\n v-for=\"(f, i) in qcAttachments\"\n :key=\"i\"\n :href=\"f.url\"\n target=\"_blank\"\n class=\"pdd-file\"\n >{{ f.name }}</a>\n </template>\n <span v-else>—</span>\n </el-descriptions-item>\n </el-descriptions>\n <template v-if=\"qcCustomList.length\">\n <div class=\"pdd-subtitle\">自定义质检项</div>\n <el-table :data=\"qcCustomList\" border size=\"small\" class=\"pdd-table\">\n <el-table-column type=\"index\" label=\"序号\" width=\"60\" align=\"center\" />\n <el-table-column label=\"质检项\" prop=\"qc_item\" min-width=\"150\" show-overflow-tooltip />\n <el-table-column label=\"质检内容\" prop=\"qc_content\" min-width=\"250\" show-overflow-tooltip />\n </el-table>\n </template>\n\n <!-- ===== 自定义属性 ===== -->\n <template v-if=\"customAttrList.length\">\n <div class=\"pdd-title\">自定义属性</div>\n <el-table :data=\"customAttrList\" border size=\"small\" class=\"pdd-table\">\n <el-table-column label=\"属性名称\" prop=\"attr_name\" width=\"200\" show-overflow-tooltip />\n <el-table-column label=\"属性值\">\n <template #default=\"{ row }\">{{ customAttrValueText(row) }}</template>\n </el-table-column>\n </el-table>\n </template>\n </template>\n <el-empty v-else-if=\"!loading\" description=\"暂无数据\" />\n </div>\n <template #footer>\n <el-button @click=\"emit('update:visible', false)\">关闭</el-button>\n </template>\n </el-dialog>\n</template>\n\n<script lang=\"ts\">\n/**\n * JProductDetailDialog —— 产品详情弹窗(只读)\n *\n * 与项目解耦:request 由宿主通过 prop 注入(传入各 *_front 项目 `@/api` 的默认导出),\n * token / operator / baseURL 均由宿主的 request 拦截器处理。接口路径内置。\n *\n * 前置条件(宿主项目):\n * 1. 已安装 element-plus(peerDependency)\n * 2. vite proxy 已配置 `/bis-app` 转发到后端\n * 3. 后端提供同一套 bis 产品详情接口\n *\n * 用法:\n * import request from '@/api'\n * <JProductDetailDialog v-model:visible=\"visible\" :code=\"row.sku_code\" :request=\"request\" />\n * <JProductDetailDialog v-model:visible=\"visible\" type=\"spu\" :code=\"row.spu_code\" :request=\"request\" />\n * 可选::id=\"row.id\"\n */\nimport { ref } from 'vue'\nimport type {\n JProductRequestFn,\n JProductRequestConfig,\n JProductDetailDialogProps,\n} from './types'\n\n// ---- 字典(模块级缓存:整个应用只请求一次,多个实例共享)----\nconst brandDict = ref<any[]>([])\nconst unitDict = ref<any[]>([])\nconst saleDict = ref<any[]>([])\nconst companyDict = ref<any[]>([])\nconst tagDict = ref<any[]>([])\nconst customAttrDict = ref<any[]>([])\n\nlet dictsLoaded = false\nlet dictsPromise: Promise<void> | null = null\n\nconst loadDicts = (request: JProductRequestFn): Promise<void> => {\n const post = (url: string, data: any): Promise<any> =>\n request({ url, method: 'post', data } as JProductRequestConfig)\n if (dictsLoaded) return Promise.resolve()\n if (dictsPromise) return dictsPromise\n dictsPromise = Promise.all([\n post('/bis-app/comm/productAttrValue/getAll', { pageSize: 999 }).then((res) => {\n if (res.code === 1) {\n brandDict.value = res.data?.brand || []\n unitDict.value = res.data?.unit || []\n saleDict.value = res.data?.sale || []\n }\n }).catch(() => { /* 展示走 _name 字段兜底,字典失败不阻断 */ }),\n post('/bis-app/comm/company/list', { pageSize: 999, subject_type: 'purchase' }).then((res) => {\n if (res.code === 1) companyDict.value = res.data?.list || res.data || []\n }).catch(() => { /* ignore */ }),\n post('/bis-app/comm/tagCategoryValue/list', { tag_code: 'PRODUCT_TAG', pageIndex: 1, pageSize: 999 }).then((res) => {\n if (res.code === 1) tagDict.value = res.data?.list || res.data || []\n }).catch(() => { /* ignore */ }),\n post('/bis-app/comm/customAttr/list', { pageIndex: 1, pageSize: 999 }).then((res) => {\n if (res.code === 1) customAttrDict.value = res.data?.list || res.data || []\n }).catch(() => { /* ignore */ }),\n ]).then(() => { dictsLoaded = true }).finally(() => { dictsPromise = null })\n return dictsPromise\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, watch } from 'vue'\nimport {\n ElDialog,\n ElDescriptions,\n ElDescriptionsItem,\n ElTag,\n ElTable,\n ElTableColumn,\n ElImage,\n ElEmpty,\n ElButton,\n ElMessage,\n vLoading,\n} from 'element-plus'\n// 类型已在上方 <script> 中统一 import(双 script 同作用域,避免 Duplicate identifier)\n\ndefineOptions({\n name: 'JProductDetailDialog',\n directives: { loading: vLoading },\n})\n\nconst props = withDefaults(defineProps<JProductDetailDialogProps>(), {\n visible: false,\n code: '',\n type: 'sku',\n id: undefined,\n})\n\nconst emit = defineEmits<{ 'update:visible': [boolean] }>()\n\nconst post = (url: string, data: any): Promise<any> =>\n props.request({ url, method: 'post', data } as JProductRequestConfig)\n\nconst loading = ref(false)\nconst detail = ref<any>(null)\n\n// ---- 请求:弹窗打开时并行加载字典(缓存)+ 详情 ----\nconst fetchDetail = async () => {\n if (!props.code && props.id === undefined) return\n detail.value = null\n loadDicts(props.request)\n const url = props.type === 'spu' ? '/bis-app/comm/spu/doDetail' : '/bis-app/comm/sku/doDetail'\n const params = props.type === 'spu'\n ? { id: props.id, spu_code: props.code }\n : { id: props.id, sku_code: props.code }\n loading.value = true\n try {\n const res = await post(url, params)\n if (res.code === 1 && res.data) {\n detail.value = res.data\n } else {\n ElMessage.error(res.msg || '获取详情失败')\n }\n } catch {\n ElMessage.error('获取详情失败')\n } finally {\n loading.value = false\n }\n}\n\nwatch(() => props.visible, (val) => {\n if (val) fetchDetail()\n})\n\n// ---- 数据分区(兼容详情接口嵌套结构与列表接口扁平结构)----\nconst basic = computed(() => detail.value?.basic_info ?? detail.value ?? {})\nconst spec = computed(() => detail.value?.spec_info ?? {})\nconst images = computed(() => detail.value?.images_info ?? detail.value?.image_info ?? {})\nconst purchase = computed(() => detail.value?.purchase_info ?? {})\nconst declaration = computed(() => detail.value?.declaration_info ?? {})\nconst qc = computed(() => detail.value?.qc_info ?? {})\nconst bindSku = computed(() => detail.value?.bind_sku_info ?? {})\nconst spuBindSku = computed(() => detail.value?.spu_bind_sku ?? {})\n\n// 装箱规格与供应商报价:详情接口在顶层,兼容嵌套位置\nconst specBoxList = computed<any[]>(() => detail.value?.spec_box_info ?? spec.value.spec_box_info ?? [])\nconst supplierList = computed<any[]>(() => detail.value?.sku_supplier ?? purchase.value.supplier_list ?? [])\n\nconst productType = computed(() => String(basic.value.product_type ?? (props.type === 'spu' ? '30' : '10')))\nconst isSpu = computed(() => productType.value === '30')\nconst productTypeLabel = computed(() => ({ '10': '单品', '20': '组合产品', '30': '多属性产品' } as Record<string, string>)[productType.value] || productType.value)\n\nconst nameCn = computed(() => (isSpu.value ? (basic.value.spu_name || basic.value.product_name) : basic.value.product_name))\nconst nameEn = computed(() => (isSpu.value ? (basic.value.spu_name_en || basic.value.product_name_en) : basic.value.product_name_en))\nconst mainCode = computed(() => (isSpu.value ? basic.value.spu_code : basic.value.sku_code))\n\n// ---- 归一化工具 ----\nconst normalizeStringArray = (v: any): string[] => {\n if (v == null || v === '') return []\n if (Array.isArray(v)) return v.map(String).filter(Boolean)\n if (typeof v === 'string') {\n const s = v.trim()\n if (!s) return []\n if (s.startsWith('[')) {\n try {\n const arr = JSON.parse(s)\n return Array.isArray(arr) ? arr.map(String).filter(Boolean) : []\n } catch { /* fallthrough */ }\n }\n return s.split(',').map((x) => x.trim()).filter(Boolean)\n }\n return [String(v)]\n}\n\nconst normalizeAttachments = (v: any): { name: string; url: string }[] => {\n let list: any[] = []\n if (Array.isArray(v)) list = v\n else if (typeof v === 'string' && v.trim()) {\n try {\n const arr = JSON.parse(v)\n list = Array.isArray(arr) ? arr : [v]\n } catch { list = [v] }\n }\n return list\n .map((it) => {\n if (typeof it === 'string') return { name: it.split('/').pop() || it, url: it }\n const url = it?.url || it?.file_url || it?.path || ''\n return { name: it?.name || it?.file_name || url.split('/').pop() || '附件', url }\n })\n .filter((f) => f.url)\n}\n\nconst fmt = (v: any) => (v == null || v === '' ? '—' : v)\nconst weightText = (v: any, unit?: string) => (v == null || v === '' ? '—' : `${v} ${unit || ''}`.trim())\nconst dimText = (l: any, w: any, h: any, unit = 'cm') => {\n if ([l, w, h].every((x) => x == null || x === '')) return '—'\n const p = (x: any) => (x == null || x === '' ? '—' : x)\n return `${p(l)} × ${p(w)} × ${p(h)} ${unit}`\n}\n\n// ---- 字段展示(优先详情返回的 _name 字段,字典映射兜底)----\nconst dictName = (list: any[], id: any): string => {\n if (id == null || id === '') return ''\n const hit = list.find((x) => String(x.id) === String(id))\n return hit?.attr_value_name || ''\n}\n\nconst brandName = computed(() => basic.value.brand_name || dictName(brandDict.value, basic.value.brand_id))\nconst unitName = computed(() => basic.value.unit_name || dictName(unitDict.value, basic.value.unit_id))\nconst statusName = computed(() =>\n basic.value.sale_status_name || basic.value.status_name || dictName(saleDict.value, basic.value.status)\n)\nconst declarationUnitName = computed(() =>\n declaration.value.declaration_unit_name || dictName(unitDict.value, declaration.value.declaration_unit_id) || declaration.value.declaration_unit_id\n)\n\nconst peNames = computed(() => {\n if (basic.value.pe_code_name) return basic.value.pe_code_name\n const codes = normalizeStringArray(basic.value.pe_codes)\n if (!codes.length) return ''\n return codes\n .map((c) => companyDict.value.find((x) => String(x.company_code) === String(c))?.company_name || c)\n .join('、')\n})\n\nconst tagList = computed(() =>\n normalizeStringArray(basic.value.tags).map((code) => {\n const hit = tagDict.value.find((t) => String(t.tag_value_code) === String(code))\n return { code, name: hit?.tag_value_name || code, color: hit?.tag_color || '' }\n })\n)\n\nconst skuAttrText = computed(() => {\n const attr = basic.value.sku_attr\n if (!attr || typeof attr !== 'object' || Array.isArray(attr)) return ''\n return Object.entries(attr).map(([k, v]) => `${k}: ${v}`).join(';')\n})\n\nconst basicAttachments = computed(() => normalizeAttachments(basic.value.att_files))\nconst hasDesc = computed(() => {\n const html = basic.value.product_desc || ''\n return String(html).replace(/<[^>]*>/g, '').trim().length > 0 || /<img/i.test(String(html))\n})\n\n// 图片\nconst mainImage = computed(() => images.value.main_image || detail.value?.product_image || '')\nconst sizeImages = computed(() => normalizeStringArray(images.value.size_images ?? detail.value?.size_images))\nconst sellingPointImages = computed(() => normalizeStringArray(images.value.selling_point_images))\n\n// 质检\nconst qcMethodLabel = computed(() =>\n ({ spot: '抽检', full: '全检', exempt: '免检' } as Record<string, string>)[qc.value.qc_method] || fmt(qc.value.qc_method)\n)\nconst qcImages = computed(() => normalizeStringArray(qc.value.images))\nconst qcAttachments = computed(() => normalizeAttachments(qc.value.att_files))\nconst qcCustomList = computed<any[]>(() => (Array.isArray(qc.value.qc_content) ? qc.value.qc_content : []))\n\n// 自定义属性\n// 详情里每行只有 custom_attr_id + 值(id),属性名和选项名需按 custom_attr_id 去字典匹配。\n// 字典项字段名与表单 allCustomAttrs 保持一致的多路兜底。\nconst dictAttrId = (item: any): string =>\n String(item.custom_attr_id ?? item.id ?? item.attr_id ?? item.attr_code ?? '').trim()\n\n// 解析字典项的选项列表 → [{id, name}](对齐表单 parseCustomAttrOptions)\nconst parseAttrOptions = (raw: any): { id: string; name: string }[] => {\n const list = Array.isArray(raw) ? raw : (raw != null && raw !== '' ? [raw] : [])\n const out: { id: string; name: string }[] = []\n for (const item of list) {\n if (typeof item === 'string') {\n item.split(/[,,、\\n]/).map((s) => s.trim()).filter(Boolean).forEach((name) => out.push({ id: '', name }))\n } else if (item && typeof item === 'object') {\n const name = String(item.attr_value ?? item.value ?? item.label ?? item.attr_value_name ?? item.name ?? '').trim()\n const id = String(item.id ?? item.attr_value_id ?? item.value_id ?? '')\n if (name) out.push({ id, name })\n }\n }\n return out\n}\n\n// custom_attr_id → 字典项\nconst customAttrDictMap = computed(() => {\n const m = new Map<string, any>()\n for (const d of customAttrDict.value) {\n const id = dictAttrId(d)\n if (id) m.set(id, d)\n }\n return m\n})\n\nconst customAttrList = computed<any[]>(() => {\n const info = detail.value?.custom_attr_info\n const list = info?.list ?? info\n const rows = Array.isArray(list) ? list : []\n return rows.map((row) => {\n const id = dictAttrId(row)\n const def = customAttrDictMap.value.get(id)\n return {\n ...row,\n custom_attr_id: id,\n // 属性名:详情自带优先,否则取字典\n attr_name: row.attr_name || def?.attr_name || id,\n options: parseAttrOptions(def?.attr_value ?? def?.options ?? row.options ?? row.attr_value),\n }\n })\n})\n\nconst customAttrValueText = (row: any): string => {\n const values = normalizeStringArray(row.custom_attr_value_id ?? row.custom_attr_value)\n if (!values.length) return '—'\n const options: any[] = row.options || []\n return values\n .map((v) => options.find((o) => (o.id && String(o.id) === String(v)) || String(o.name) === String(v))?.name || v)\n .join('、')\n}\n\n// 组合产品\nconst bindSkuList = computed<any[]>(() => bindSku.value.bind_sku_list ?? [])\n\n// SPU 款式属性 / SKU 变体\nconst styleAttrs = computed<any[]>(() => spuBindSku.value.sku_attr ?? [])\nconst skuVariants = computed<any[]>(() => spuBindSku.value.sku_list ?? [])\nconst variantAttrText = (row: any, attr: any): string => {\n const code = row.sku_attr?.[attr.attr_code]\n if (code == null || code === '') return '—'\n const child = (attr.childs || []).find((c: any) => String(c.attr_value_code) === String(code))\n return child?.attr_value_name || String(code)\n}\n\n// 供应商报价:币种组 × 阶梯 摊平成行\nconst supplierQuoteRows = (sup: any): any[] => {\n const rows: any[] = []\n for (const q of sup.supplier_quote || []) {\n for (const item of q.quote_list || []) {\n rows.push({\n currency: q.quote_currency_code,\n is_tax: q.is_tax,\n tax_rate: q.tax_rate,\n ...item,\n })\n }\n }\n return rows\n}\n</script>\n\n<style scoped>\n.pdd-body {\n min-height: 200px;\n max-height: 72vh;\n overflow-y: auto;\n padding-right: 4px;\n}\n\n.pdd-title {\n font-size: 15px;\n font-weight: 600;\n color: #303133;\n margin: 18px 0 10px;\n padding-left: 8px;\n border-left: 3px solid #409eff;\n}\n\n.pdd-title:first-child {\n margin-top: 0;\n}\n\n.pdd-subtitle {\n font-size: 13px;\n font-weight: 600;\n color: #606266;\n margin: 12px 0 8px;\n}\n\n.pdd-table {\n margin-bottom: 4px;\n}\n\n.pdd-tag {\n margin-right: 6px;\n margin-bottom: 2px;\n}\n\n.pdd-file {\n display: inline-block;\n margin-right: 14px;\n color: #409eff;\n text-decoration: none;\n}\n\n.pdd-file:hover {\n text-decoration: underline;\n}\n\n.pdd-img {\n width: 80px;\n height: 80px;\n margin-right: 8px;\n border-radius: 4px;\n border: 1px solid #e4e7ed;\n vertical-align: top;\n}\n\n.pdd-thumb {\n width: 40px;\n height: 40px;\n border-radius: 4px;\n}\n\n.pdd-rich {\n max-height: 300px;\n overflow-y: auto;\n}\n\n.pdd-rich :deep(img) {\n max-width: 100%;\n}\n\n.pdd-supplier {\n margin-bottom: 12px;\n border: 1px solid #e4e7ed;\n border-radius: 4px;\n padding: 10px;\n}\n\n.pdd-supplier-head {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 8px;\n font-size: 13px;\n}\n\n.pdd-supplier-name {\n font-weight: 600;\n color: #303133;\n}\n\n.pdd-supplier-meta {\n color: #909399;\n}\n</style>\n","<template>\n <span\n v-if=\"hasCode\"\n class=\"j-sku-link\"\n @click.stop=\"handleClick\"\n >{{ displayText }}</span>\n <span v-else class=\"j-sku-link-empty\">{{ emptyText }}</span>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\ndefineOptions({ name: 'JSkuLink' })\n\nconst props = withDefaults(defineProps<{\n code?: string | null\n emptyText?: string\n}>(), {\n emptyText: '-',\n})\n\nconst emit = defineEmits<{\n open: [code: string]\n}>()\n\nconst displayText = computed(() => {\n const value = String(props.code ?? '').trim()\n return value || props.emptyText\n})\n\nconst hasCode = computed(() => {\n const value = String(props.code ?? '').trim()\n return value !== '' && value !== '-'\n})\n\nconst handleClick = () => {\n if (!hasCode.value) return\n emit('open', String(props.code).trim())\n}\n</script>\n\n<style scoped>\n.j-sku-link {\n color: #409eff;\n font-weight: 700;\n cursor: pointer;\n}\n\n.j-sku-link:hover {\n text-decoration: underline;\n}\n\n.j-sku-link-empty {\n color: inherit;\n font-weight: inherit;\n}\n</style>\n","import { ref } from 'vue'\n\n/**\n * 产品详情弹窗状态管理。\n *\n * 用法:\n * const { productDetailDialogVisible, productDetailDialogCode, openProductDetailDialog }\n * = useProductDetailDialog()\n * // <JSkuLink :code=\"row.sku_code\" @open=\"openProductDetailDialog\" />\n * // <JProductDetailDialog v-model:visible=\"productDetailDialogVisible\"\n * // :code=\"productDetailDialogCode\" :request=\"request\" />\n */\nexport function useProductDetailDialog() {\n const productDetailDialogVisible = ref(false)\n const productDetailDialogCode = ref('')\n\n const openProductDetailDialog = (code: string) => {\n const sku = String(code ?? '').trim()\n if (!sku || sku === '-') return\n productDetailDialogCode.value = sku\n productDetailDialogVisible.value = true\n }\n\n return {\n productDetailDialogVisible,\n productDetailDialogCode,\n openProductDetailDialog,\n }\n}\n","<!--\r\n JSearchInputDialog - 关键词搜索复合控件\r\n\r\n 结构:\r\n [ 类型下拉 ] + [ 关键词输入框 ] + [ 批量输入按钮 ]\r\n │\r\n └─ 点右侧按钮 → Dialog + textarea 批量编辑\r\n\r\n 主流程:\r\n 1. 父组件传入 options(如 SKU / 品名),v-model:type + v-model:keyword 双向绑定\r\n 2. 用户左侧选类型,中间手输关键词;或点右侧 icon 打开弹窗批量粘贴\r\n 3. 弹窗确定:textarea 文本规范化 → 写回 keyword → emit('confirm')\r\n 4. 输入框回车:emit('search')\r\n 5. 父组件用 { [type]: keyword } 拼请求(也可调用 expose 的 toParams)\r\n\r\n 示例请求结果:type='sku', keyword='sku1,sku2' → { sku: 'sku1,sku2' }\r\n-->\r\n<template>\r\n <div class=\"j-search-input-dialog\" :style=\"{ width: width }\">\r\n <!-- 主输入区:前置类型 + 关键词 + 右侧批量入口 -->\r\n <el-input\r\n v-model=\"keyword\"\r\n :placeholder=\"placeholder\"\r\n clearable\r\n class=\"j-search-input-dialog__input\"\r\n @keyup.enter=\"emit('search')\"\r\n >\r\n <!-- 左侧:搜索字段类型(SKU / 品名 / 自定义) -->\r\n <template #prepend>\r\n <el-select\r\n v-model=\"type\"\r\n :style=\"{ width: selectWidth }\"\r\n :disabled=\"!options.length\"\r\n >\r\n <el-option\r\n v-for=\"item in options\"\r\n :key=\"item.value\"\r\n :label=\"item.label\"\r\n :value=\"item.value\"\r\n />\r\n </el-select>\r\n </template>\r\n <!-- 右侧:打开批量输入弹窗 -->\r\n <template #append>\r\n <el-button :icon=\"Memo\" :title=\"dialogTitleText\" @click=\"openDialog\" />\r\n </template>\r\n </el-input>\r\n\r\n <!-- 批量输入弹窗:textarea 编辑多值,确定后合并回主输入框 -->\r\n <el-dialog\r\n v-model=\"dialogVisible\"\r\n :title=\"dialogTitleText\"\r\n :width=\"dialogWidth\"\r\n append-to-body\r\n destroy-on-close\r\n :close-on-click-modal=\"false\"\r\n @closed=\"handleDialogClosed\"\r\n >\r\n <el-input\r\n v-model=\"textareaValue\"\r\n type=\"textarea\"\r\n :rows=\"rows\"\r\n :placeholder=\"textareaPlaceholder\"\r\n resize=\"vertical\"\r\n />\r\n <template #footer>\r\n <el-button @click=\"dialogVisible = false\">取消</el-button>\r\n <el-button type=\"primary\" @click=\"handleConfirm\">确定</el-button>\r\n </template>\r\n </el-dialog>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, ref, watch } from 'vue'\r\nimport { Memo } from '@element-plus/icons-vue'\r\nimport type { JSearchInputDialogProps, SearchInputModel, SearchInputOption } from './types'\r\n\r\ndefineOptions({\r\n name: 'JSearchInputDialog',\r\n})\r\n\r\nconst props = withDefaults(defineProps<JSearchInputDialogProps>(), {\r\n options: () => [],\r\n placeholder: '请输入关键词',\r\n width: '320px',\r\n selectWidth: '100px',\r\n separator: ',',\r\n dialogTitle: '',\r\n dialogWidth: '480px',\r\n rows: 8,\r\n textareaPlaceholder: '支持换行、逗号、空格分隔,确定后自动合并',\r\n clearOnTypeChange: false,\r\n})\r\n\r\n/**\r\n * 双向绑定:\r\n * - type:当前选中的搜索字段类型(对应 options[].value)\r\n * - keyword:最终要参与搜索的关键词字符串(可多值,如 sku1,sku2)\r\n *\r\n * 父组件:\r\n * v-model:type=\"filters.keywordType\"\r\n * v-model:keyword=\"filters.keyword\"\r\n */\r\nconst type = defineModel<string>('type', { default: '' })\r\nconst keyword = defineModel<string>('keyword', { default: '' })\r\n\r\nconst emit = defineEmits<{\r\n /** 弹窗点「确定」并写回 keyword 后触发;父级常用来立刻 handleSearch */\r\n confirm: [payload: SearchInputModel]\r\n /** 主输入框回车触发;父级常用来 handleSearch */\r\n search: []\r\n}>()\r\n\r\n/** 批量输入弹窗显隐 */\r\nconst dialogVisible = ref(false)\r\n/** 弹窗内 textarea 的临时编辑值(确定前不影响外部 keyword) */\r\nconst textareaValue = ref('')\r\n\r\n/** 当前 type 对应的 option(用于取 label 拼弹窗标题) */\r\nconst currentOption = computed(() =>\r\n (props.options as SearchInputOption[]).find((item) => item.value === type.value),\r\n)\r\n\r\n/** 弹窗标题:优先用 props.dialogTitle,否则「批量输入{label}」 */\r\nconst dialogTitleText = computed(() => {\r\n if (props.dialogTitle) return props.dialogTitle\r\n const label = currentOption.value?.label || '关键词'\r\n return `批量输入${label}`\r\n})\r\n\r\n/**\r\n * 规范化批量文本 → 统一分隔符拼接的字符串\r\n * 流程:拆分(换行/逗号/分号/空白)→ trim → 去空 → 去重(保序)→ join(separator)\r\n * 例:'sku1\\nsku2, sku2 sku3' + separator=',' → 'sku1,sku2,sku3'\r\n */\r\nconst normalizeKeywords = (raw: string): string => {\r\n if (!raw) return ''\r\n const parts = raw\r\n .split(/[\\n\\r,,;;\\s\\t]+/)\r\n .map((item) => item.trim())\r\n .filter(Boolean)\r\n\r\n const unique: string[] = []\r\n const seen = new Set<string>()\r\n for (const part of parts) {\r\n if (seen.has(part)) continue\r\n seen.add(part)\r\n unique.push(part)\r\n }\r\n\r\n return unique.join(props.separator)\r\n}\r\n\r\n/**\r\n * 主输入框 keyword → textarea 多行回显\r\n * 打开弹窗前调用,方便用户在已有值上继续编辑\r\n * 例:'sku1,sku2' → 'sku1\\nsku2'\r\n */\r\nconst keywordToTextarea = (value: string): string => {\r\n if (!value) return ''\r\n return value\r\n .split(/[\\n\\r,,;;\\s\\t.]+/)\r\n .map((item) => item.trim())\r\n .filter(Boolean)\r\n .join('\\n')\r\n}\r\n\r\n/**\r\n * 打开批量输入弹窗\r\n * 1. 把当前 keyword 拆成多行填入 textarea\r\n * 2. 显示 dialog\r\n */\r\nconst openDialog = () => {\r\n textareaValue.value = keywordToTextarea(keyword.value)\r\n dialogVisible.value = true\r\n}\r\n\r\n/**\r\n * 弹窗点「确定」\r\n * 1. 规范化 textarea → 写回 keyword(同步到父组件 v-model)\r\n * 2. 关闭弹窗\r\n * 3. emit confirm,父组件可据此触发搜索\r\n * 注意:组件本身不发请求,只负责回写数据\r\n */\r\nconst handleConfirm = () => {\r\n keyword.value = normalizeKeywords(textareaValue.value)\r\n dialogVisible.value = false\r\n emit('confirm', {\r\n type: type.value,\r\n keyword: keyword.value,\r\n })\r\n}\r\n\r\n/**\r\n * 弹窗完全关闭后清理临时 textarea\r\n * 取消 / 确定关闭都会走这里;取消时不会改外部 keyword\r\n */\r\nconst handleDialogClosed = () => {\r\n textareaValue.value = ''\r\n}\r\n\r\n// 初始化:父组件未传 type 时,默认选中 options 第一项\r\nif (!type.value && props.options?.length) {\r\n type.value = props.options[0]?.value || ''\r\n}\r\n\r\n/**\r\n * 监听类型切换\r\n * 仅当 clearOnTypeChange=true 时,切换左侧类型会清空 keyword\r\n */\r\nwatch(type, (next, prev) => {\r\n if (!props.clearOnTypeChange) return\r\n if (next === prev) return\r\n keyword.value = ''\r\n})\r\n\r\n/**\r\n * 重置(供父组件 ref 调用)\r\n * @param defaultType 指定重置后的类型;不传则用 options[0]\r\n * 会清空 keyword\r\n */\r\nconst reset = (defaultType?: string) => {\r\n type.value = defaultType || props.options?.[0]?.value || ''\r\n keyword.value = ''\r\n}\r\n\r\n/**\r\n * 拼请求参数(供父组件 ref 调用)\r\n * 有 keyword 时返回 { [type]: keyword },否则 {}\r\n * 例:{ sku: 'sku1,sku2' }\r\n */\r\nconst toParams = (): Record<string, string> => {\r\n if (!keyword.value || !type.value) return {}\r\n return { [type.value]: keyword.value }\r\n}\r\n\r\n/**\r\n * 对外暴露,父组件通过 ref 调用:\r\n * - reset() 重置类型和关键词\r\n * - toParams() 直接拿请求参数对象\r\n * - openDialog() 程序化打开批量弹窗\r\n */\r\ndefineExpose({\r\n reset,\r\n toParams,\r\n openDialog,\r\n})\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n/* 让前置 select 贴合 el-input 的 prepend 区域,去掉多余边框/阴影 */\r\n.j-search-input-dialog {\r\n display: inline-block;\r\n vertical-align: middle;\r\n\r\n :deep(.el-input-group__prepend) {\r\n background-color: var(--el-fill-color-blank);\r\n padding: 0;\r\n }\r\n\r\n :deep(.el-input-group__prepend .el-select) {\r\n margin: 0;\r\n }\r\n\r\n :deep(.el-input-group__prepend .el-select .el-select__wrapper) {\r\n box-shadow: none !important;\r\n border: none;\r\n background: transparent;\r\n }\r\n}\r\n</style>\r\n","/**\r\n * 递归转换值(处理嵌套对象和数组)\r\n */\r\nfunction deepTransformValue(value: any, transformer: (obj: Record<string, any>) => Record<string, any>): any {\r\n if (Array.isArray(value)) {\r\n return value.map((item) => deepTransformValue(item, transformer))\r\n }\r\n if (value !== null && typeof value === 'object' && !(value instanceof Date)) {\r\n return transformer(value)\r\n }\r\n return value\r\n}\r\n\r\n/**\r\n * 将对象的 key 从小驼峰转为下划线格式(支持深度嵌套)\r\n * @param obj 需要转换的对象\r\n * @param excludeKeys 不需要转换的 key 数组(可选)\r\n */\r\nexport function toSnakeCase<T extends Record<string, any>>(\r\n obj: T,\r\n excludeKeys: string[] = []\r\n): Record<string, any> {\r\n return Object.fromEntries(\r\n Object.entries(obj).map(([key, value]) => {\r\n const newValue = deepTransformValue(value, (v) => toSnakeCase(v, excludeKeys))\r\n if (excludeKeys.includes(key)) {\r\n return [key, newValue]\r\n }\r\n const snakeKey = key.replace(/([A-Z])/g, '_$1').toLowerCase()\r\n return [snakeKey, newValue]\r\n })\r\n )\r\n}\r\n\r\n/**\r\n * 将对象的 key 从下划线格式转为小驼峰(支持深度嵌套)\r\n * @param obj 需要转换的对象\r\n * @param excludeKeys 不需要转换的 key 数组(可选)\r\n */\r\nexport function toCamelCase<T extends Record<string, any>>(\r\n obj: T,\r\n excludeKeys: string[] = []\r\n): Record<string, any> {\r\n return Object.fromEntries(\r\n Object.entries(obj).map(([key, value]) => {\r\n const newValue = deepTransformValue(value, (v) => toCamelCase(v, excludeKeys))\r\n if (excludeKeys.includes(key)) {\r\n return [key, newValue]\r\n }\r\n const camelKey = key.replace(/_([a-z])/g, (_, char) => char.toUpperCase())\r\n return [camelKey, newValue]\r\n })\r\n )\r\n}\r\n\r\n/**\r\n * 从对象中提取指定的 key\r\n * @param obj 源对象\r\n * @param keys 要提取的 key 数组\r\n */\r\nexport function pick<T extends Record<string, any>, K extends keyof T>(\r\n obj: T,\r\n keys: K[]\r\n): Pick<T, K> {\r\n const result = {} as Pick<T, K>\r\n for (const key of keys) {\r\n if (key in obj) {\r\n result[key] = obj[key]\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * 从对象中排除指定的 key\r\n * @param obj 源对象\r\n * @param keys 要排除的 key 数组\r\n */\r\nexport function omit<T extends Record<string, any>, K extends keyof T>(\r\n obj: T,\r\n keys: K[]\r\n): Omit<T, K> {\r\n const result = { ...obj }\r\n for (const key of keys) {\r\n delete result[key]\r\n }\r\n return result as Omit<T, K>\r\n}\r\n\r\n/**\r\n * 深拷贝对象\r\n * @param obj 需要拷贝的对象\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n if (obj === null || typeof obj !== 'object') return obj\r\n if (obj instanceof Date) return new Date(obj.getTime()) as unknown as T\r\n if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags) as unknown as T\r\n if (Array.isArray(obj)) return obj.map((item) => deepClone(item)) as unknown as T\r\n const cloned = {} as Record<string, any>\r\n for (const key of Object.keys(obj)) {\r\n cloned[key] = deepClone((obj as Record<string, any>)[key])\r\n }\r\n return cloned as T\r\n}\r\n\r\n/**\r\n * 过滤对象中的空值(null、undefined、空字符串)\r\n * @param obj 需要过滤的对象\r\n * @param deep 是否递归过滤嵌套对象,默认 false\r\n */\r\nexport function filterEmpty<T extends Record<string, any>>(\r\n obj: T,\r\n deep = false\r\n): Partial<T> {\r\n const result = {} as Record<string, any>\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (value === null || value === undefined || value === '') continue\r\n if (deep && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)) {\r\n const filtered = filterEmpty(value, true)\r\n if (Object.keys(filtered).length > 0) {\r\n result[key] = filtered\r\n }\r\n } else {\r\n result[key] = value\r\n }\r\n }\r\n return result as Partial<T>\r\n}\r\n\r\n/**\r\n * 将嵌套对象扁平化为单层对象\r\n * @param obj 需要扁平化的对象\r\n * @param prefix key 前缀,默认为空\r\n * @param separator 分隔符,默认为 '.'\r\n * @example flatten({ a: { b: 1, c: { d: 2 } } }) => { 'a.b': 1, 'a.c.d': 2 }\r\n */\r\nexport function flatten(\r\n obj: Record<string, any>,\r\n prefix = '',\r\n separator = '.'\r\n): Record<string, any> {\r\n const result: Record<string, any> = {}\r\n for (const [key, value] of Object.entries(obj)) {\r\n const newKey = prefix ? `${prefix}${separator}${key}` : key\r\n if (value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)) {\r\n Object.assign(result, flatten(value, newKey, separator))\r\n } else {\r\n result[newKey] = value\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * 将扁平化的对象还原为嵌套对象\r\n * @param obj 扁平化的对象\r\n * @param separator 分隔符,默认为 '.'\r\n * @example unflatten({ 'a.b': 1, 'a.c.d': 2 }) => { a: { b: 1, c: { d: 2 } } }\r\n */\r\nexport function unflatten(\r\n obj: Record<string, any>,\r\n separator = '.'\r\n): Record<string, any> {\r\n const result: Record<string, any> = {}\r\n for (const [key, value] of Object.entries(obj)) {\r\n const parts = key.split(separator)\r\n let current = result\r\n for (let i = 0; i < parts.length - 1; i++) {\r\n const k = parts[i] as string\r\n if (!(k in current)) {\r\n current[k] = {}\r\n }\r\n current = current[k]\r\n }\r\n current[parts[parts.length - 1] as string] = value\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * 将 { key: label } 对象转换为 el-table-column 所需的表头数组\r\n * @param fieldMap 字段映射对象\r\n * @example toTableColumns({ id: '主键', name: '名称' }) => [{ id: 'id', label: '主键', prop: 'id' }, ...]\r\n */\r\nexport function toTableColumns(fieldMap: Record<string, string>) {\r\n return Object.entries(fieldMap).map(([key, label]) => ({\r\n id: key,\r\n label,\r\n prop: key,\r\n }))\r\n}\r\n","import type { RouteRecordRaw } from 'vue-router'\r\nimport type { BackendRoute } from './types'\r\n\r\ntype ViewModules = Record<string, () => Promise<unknown>>\r\n\r\ninterface RouteTreeNode extends BackendRoute {\r\n children?: RouteTreeNode[]\r\n}\r\n\r\nexport function getComponentImport(componentPath: string, viewModules: ViewModules): (() => Promise<unknown>) | null {\r\n if (!componentPath) return null\r\n\r\n let normalizedPath = componentPath.replace(/^@\\//, '')\r\n if (!normalizedPath.startsWith('views/')) normalizedPath = `views/${normalizedPath}`\r\n if (!normalizedPath.endsWith('.vue')) normalizedPath = `${normalizedPath}.vue`\r\n\r\n const fullPath = `/src/${normalizedPath}`\r\n\r\n return (viewModules[fullPath] ?? viewModules['/src/views/common/NotFound.vue'] ?? null) as (() => Promise<unknown>) | null\r\n}\r\n\r\nexport function buildRouteTree(routes: BackendRoute[]): RouteTreeNode[] {\r\n const routeMap = new Map<string, RouteTreeNode>()\r\n const rootRoutes: RouteTreeNode[] = []\r\n\r\n routes.forEach(route => routeMap.set(route.name, { ...route, children: [] }))\r\n\r\n routes.forEach(route => {\r\n const currentRoute = routeMap.get(route.name)!\r\n if (!route.parent_name) {\r\n rootRoutes.push(currentRoute)\r\n } else {\r\n const parentRoute = routeMap.get(route.parent_name)\r\n if (parentRoute) {\r\n parentRoute.children ??= []\r\n parentRoute.children.push(currentRoute)\r\n } else {\r\n rootRoutes.push(currentRoute)\r\n }\r\n }\r\n })\r\n return rootRoutes\r\n}\r\n\r\nexport function transformBackendRoutes(\r\n backendRoutes: RouteTreeNode[],\r\n viewModules: ViewModules,\r\n projectName?: string\r\n): RouteRecordRaw[] {\r\n return backendRoutes\r\n .filter(route => !projectName || !route.project || route.project === projectName)\r\n .map(route => {\r\n const routeConfig: Partial<RouteRecordRaw> = {\r\n path: route.path,\r\n name: route.name,\r\n meta: {\r\n requiresAuth: route.requiresAuth === 1,\r\n title: route.title,\r\n permissions: route.permissions\r\n ? route.permissions.split(',').map(p => p.trim()).filter(Boolean)\r\n : [],\r\n params: route.params\r\n ? route.params.split('&').map(p => p.trim()).filter(Boolean)\r\n : [],\r\n },\r\n }\r\n\r\n const component = getComponentImport(route.component, viewModules)\r\n if (component) routeConfig.component = component as RouteRecordRaw['component']\r\n\r\n if (route.redirect) routeConfig.redirect = route.redirect\r\n\r\n if (route.children?.length) {\r\n routeConfig.children = transformBackendRoutes(route.children, viewModules, projectName)\r\n }\r\n\r\n return routeConfig as RouteRecordRaw\r\n })\r\n}\r\n\r\nexport function findFirstAllowedRoute(\r\n backendRoutes: BackendRoute[],\r\n routePermissions: string[],\r\n layoutRouteName: string,\r\n projectName?: string\r\n): BackendRoute | undefined {\r\n const routeMap = new Map<string, BackendRoute>()\r\n backendRoutes.forEach(route => routeMap.set(route.name, route))\r\n\r\n const isDescendantOfLayout = (route: BackendRoute): boolean => {\r\n let parentName = route.parent_name\r\n const visited = new Set<string>()\r\n\r\n while (parentName) {\r\n if (parentName === layoutRouteName) return true\r\n if (visited.has(parentName)) return false\r\n\r\n visited.add(parentName)\r\n const parentRoute = routeMap.get(parentName)\r\n if (!parentRoute) return false\r\n parentName = parentRoute.parent_name\r\n }\r\n\r\n return false\r\n }\r\n\r\n return backendRoutes\r\n .filter(route =>\r\n route.name !== layoutRouteName &&\r\n route.is_show === 1 &&\r\n route.component &&\r\n routePermissions.includes(route.code) &&\r\n isDescendantOfLayout(route) &&\r\n (!projectName || !route.project || route.project === projectName)\r\n )\r\n .sort((a, b) => a.sorts - b.sorts)[0]\r\n}\r\n","import type { NavigationGuardNext, Router } from 'vue-router'\r\nimport NProgress from 'nprogress'\r\nimport 'nprogress/nprogress.css'\r\nimport { ElMessage } from 'element-plus'\r\nimport type { RouterGuardOptions } from './types'\r\nimport { buildRouteTree, transformBackendRoutes } from './helpers'\r\n\r\nNProgress.configure({ showSpinner: false })\r\n\r\nconst isDev = import.meta.env.DEV\r\nconst log = (...args: unknown[]) => { if (isDev) console.log('[Router]', ...args) }\r\nconst warn = (...args: unknown[]) => { if (isDev) console.warn('[Router]', ...args) }\r\nconst logError = (...args: unknown[]) => { console.error('[Router]', ...args) }\r\n\r\nexport function createRouterGuard(router: Router, options: RouterGuardOptions) {\r\n const {\r\n getRouteStore,\r\n getPermissionStore,\r\n getUserStore,\r\n isAuthenticated,\r\n viewModules,\r\n homeComponent,\r\n notFoundComponent,\r\n projectName,\r\n layoutRouteName = 'Layout',\r\n publicPaths = ['/login', '/register'],\r\n loginRouteName = 'login',\r\n forbiddenRouteName = 'Forbidden',\r\n homeRouteName = 'Home',\r\n homeRoutePath = 'home',\r\n homeTitle = '\\u9996\\u9875',\r\n noPermissionMessage = '\\u6682\\u65e0\\u6743\\u9650',\r\n } = options\r\n\r\n let hasAddedRoutes = false\r\n\r\n function addDynamicRoutes(backendRoutes: ReturnType<typeof getRouteStore>['backendRoutes']) {\r\n const treeRoutes = buildRouteTree(backendRoutes)\r\n const layoutRoute = treeRoutes.find(route => route.name === layoutRouteName)\r\n const childRoutes = layoutRoute?.children\r\n ? transformBackendRoutes(layoutRoute.children, viewModules, projectName)\r\n : []\r\n\r\n childRoutes.forEach(route => {\r\n if (route.name && router.hasRoute(route.name)) return\r\n router.addRoute(layoutRouteName, route)\r\n log(`Add route: ${String(route.name)} -> ${route.path}`)\r\n })\r\n\r\n if (!router.hasRoute(homeRouteName)) {\r\n router.addRoute(layoutRouteName, {\r\n path: homeRoutePath,\r\n name: homeRouteName,\r\n component: homeComponent as never,\r\n meta: { title: homeTitle },\r\n })\r\n }\r\n\r\n if (!router.hasRoute('NotFound')) {\r\n router.addRoute({\r\n path: '/:pathMatch(.*)*',\r\n name: 'NotFound',\r\n component: notFoundComponent as never,\r\n })\r\n }\r\n\r\n log(`Dynamic routes added: ${childRoutes.length}`)\r\n }\r\n\r\n function redirectToHomeOrContinue(\r\n toName: ReturnType<Router['resolve']>['name'],\r\n next: NavigationGuardNext\r\n ) {\r\n if (toName === homeRouteName) {\r\n next()\r\n return\r\n }\r\n\r\n if (router.hasRoute(homeRouteName)) {\r\n next({ name: homeRouteName, replace: true })\r\n } else {\r\n next()\r\n }\r\n }\r\n\r\n router.beforeEach(async (to, _from, next) => {\r\n NProgress.start()\r\n\r\n if (isAuthenticated() && !hasAddedRoutes) {\r\n try {\r\n const routeStore = getRouteStore()\r\n const permissionStore = getPermissionStore()\r\n\r\n await routeStore.initRoutes()\r\n await permissionStore.loadUserPermissions()\r\n\r\n addDynamicRoutes(routeStore.backendRoutes)\r\n hasAddedRoutes = true\r\n\r\n if (to.path === '/' || to.path === '') {\r\n redirectToHomeOrContinue(to.name, next)\r\n return\r\n }\r\n\r\n if (to.name === layoutRouteName) {\r\n redirectToHomeOrContinue(to.name, next)\r\n return\r\n }\r\n\r\n const currentRoute = routeStore.backendRoutes.find(route => route.name === to.name)\r\n if (currentRoute && !permissionStore.routePermissions.includes(currentRoute.code)) {\r\n warn('No route permission:', to.path)\r\n next({ name: forbiddenRouteName, replace: true })\r\n return\r\n }\r\n\r\n next({\r\n path: to.path,\r\n query: to.query,\r\n hash: to.hash,\r\n replace: true,\r\n })\r\n return\r\n } catch (err) {\r\n logError('Failed to load route permissions:', err)\r\n hasAddedRoutes = false\r\n await getUserStore().logout()\r\n next({ name: loginRouteName, replace: true })\r\n return\r\n }\r\n }\r\n\r\n if (publicPaths.includes(to.path)) {\r\n if (isAuthenticated()) {\r\n next({ path: '/', replace: true })\r\n } else {\r\n next()\r\n }\r\n return\r\n }\r\n\r\n if (!isAuthenticated()) {\r\n next({ name: loginRouteName, replace: true })\r\n return\r\n }\r\n\r\n const permissionStore = getPermissionStore()\r\n const routeStore = getRouteStore()\r\n\r\n if (to.name === homeRouteName) {\r\n next()\r\n return\r\n }\r\n\r\n if (permissionStore.routePermissions.length === 0) {\r\n if (to.path !== '/') {\r\n ElMessage.warning(noPermissionMessage)\r\n next({ path: '/', replace: true })\r\n } else {\r\n redirectToHomeOrContinue(to.name, next)\r\n }\r\n return\r\n }\r\n\r\n if (to.path === '/') {\r\n redirectToHomeOrContinue(to.name, next)\r\n return\r\n }\r\n\r\n if (to.name === layoutRouteName) {\r\n redirectToHomeOrContinue(to.name, next)\r\n return\r\n }\r\n\r\n const currentRoute = routeStore.backendRoutes.find(route => route.name === to.name)\r\n if (currentRoute && !permissionStore.routePermissions.includes(currentRoute.code)) {\r\n warn('No route permission:', to.path)\r\n next({ name: forbiddenRouteName, replace: true })\r\n return\r\n }\r\n\r\n next()\r\n })\r\n\r\n router.afterEach(() => NProgress.done())\r\n\r\n return {\r\n resetRouterState: () => { hasAddedRoutes = false },\r\n }\r\n}\r\n","import type { App } from 'vue'\r\nimport { JButton } from './components/JButton'\r\nimport { JUploadImg } from './components/JUploadImg'\r\nimport { JIconRender } from './components/JIconRender'\r\nimport { JSearchHeader } from './components/JSearchHeader'\r\nimport { JImportExcel } from './components/JImportExcel'\r\nimport { JSidebar, JSideMenuItem } from './components/JSidebar'\r\nimport { JAdminLayout } from './components/JAdminLayout'\r\nimport { JProductDetailDialog, JSkuLink } from './components/JProductDetail'\r\nimport { JSearchInputDialog } from './components/JSearchInputDialog'\r\n\r\n// 组件列表,新增组件后在此处注册\r\nconst components = [\r\n JButton,\r\n JUploadImg,\r\n JIconRender,\r\n JSearchHeader,\r\n JImportExcel,\r\n JSidebar,\r\n JSideMenuItem,\r\n JAdminLayout,\r\n JProductDetailDialog,\r\n JSkuLink,\r\n JSearchInputDialog,\r\n]\r\n\r\n// 全量安装插件(app.use(JgyComponents))\r\nconst install = (app: App) => {\r\n components.forEach((component) => {\r\n app.component(component.name ?? component.__name ?? '', component)\r\n })\r\n}\r\n\r\n// 默认导出插件对象\r\nexport default { install }\r\n\r\n// 按需导出各组件\r\nexport {\r\n JButton,\r\n JUploadImg,\r\n JIconRender,\r\n JSearchHeader,\r\n JImportExcel,\r\n JSidebar,\r\n JSideMenuItem,\r\n JAdminLayout,\r\n JProductDetailDialog,\r\n JSkuLink,\r\n JSearchInputDialog,\r\n}\r\n\r\n// 导出 composable\r\nexport { useProductDetailDialog } from './components/JProductDetail'\r\n\r\n// 导出工具方法\r\nexport { toSnakeCase, toCamelCase, pick, omit, deepClone, filterEmpty, flatten, unflatten, toTableColumns } from './utils'\r\n\r\n// 导出路由工具\r\nexport { createRouterGuard, buildRouteTree, transformBackendRoutes, findFirstAllowedRoute, getComponentImport } from './router'\r\nexport type { BackendRoute, RouteStoreAdapter, PermissionStoreAdapter, UserStoreAdapter, RouterGuardOptions } from './router'\r\n\r\n// 导出类型\r\nexport type { ButtonType, ButtonSize } from './components/JButton'\r\nexport type { JUploadImgProps, JUploadImgEmits, ImageItem } from './components/JUploadImg'\r\nexport type { JIconRenderProps } from './components/JIconRender'\r\nexport type { JSearchHeaderProps } from './components/JSearchHeader'\r\nexport type { JImportExcelProps, ApiFn } from './components/JImportExcel'\r\nexport type { SidebarMenuItem, JSidebarProps, JSideMenuItemProps } from './components/JSidebar'\r\nexport type { AdminLayoutMenuItem, JAdminLayoutProps } from './components/JAdminLayout'\r\nexport type { JProductDetailDialogProps, JSkuLinkProps, JProductRequestFn, JProductRequestConfig } from './components/JProductDetail'\r\nexport type {\r\n JSearchInputDialogProps,\r\n SearchInputOption,\r\n SearchInputModel,\r\n} from './components/JSearchInputDialog'\r\n"],"names":["props","__props","emit","__emit","handleClick","event","_createElementBlock","_openBlock","_hoisted_2","$slots","_hoisted_3","_renderSlot","_ctx","imageUrl","ref","showPreview","showTipText","handlePreviewSingle","handleRemoveSingle","ElMessage","imageList","uploading","initImageList","urls","url","index","watch","val","handleDragEnd","emitMultipleUpdate","handleRemove","handleFileChange","uploadFile","file","error","item","_hoisted_1","_createVNode","_unref","draggable","$event","_withCtx","element","_createElementVNode","ElImage","img","_withModifiers","ElIcon","Delete","_createBlock","ElUpload","Loading","Plus","_Fragment","_hoisted_5","_hoisted_6","ZoomIn","ElImageViewer","_hoisted_7","_hoisted_8","_toDisplayString","_mergeProps","$attrs","formItemsRef","expanded","isAnimated","itemCount","collapsedHeight","shouldCollapse","computed","measureItems","items","lastVisibleItem","wrapperRect","lastVisibleRect","toggleExpand","el","onEnd","observer","onMounted","onBeforeUnmount","ElCard","ElForm","_normalizeClass","ElButton","Search","_cache","Refresh","_createTextVNode","ArrowDown","visible","_useModel","submitting","fieldMap","renderData","stats","statusMap","dataColumns","key","label","handleOpen","res","raw","reader","e","workbook","XLSX","wsName","ws","dataRows","row","cell","list","col","handleDel","idx","handleConfirm","data","_status","_error","rest","r","handleDownloadTemplate","wb","headers","tr","h","handleClose","ElDialog","ElDivider","ElLink","ElRow","ElCol","_hoisted_4","ElTable","_renderList","ElTableColumn","$index","ElSubMenu","JIconRender","child","_component_JSideMenuItem","ElMenuItem","innerCollapsed","toggleCollapse","_normalizeStyle","_a","ElMenu","route","JSideMenuItem","value","layoutStyle","handleTopMenuSelect","path","handleSideMenuClick","JSidebar","sidebarCollapsed","toggle","menu","ElDropdown","ElDropdownMenu","ElDropdownItem","brandDict","unitDict","saleDict","companyDict","tagDict","customAttrDict","dictsLoaded","dictsPromise","loadDicts","request","post","_b","_c","loading","detail","fetchDetail","params","basic","spec","images","purchase","declaration","qc","bindSku","spuBindSku","specBoxList","supplierList","productType","isSpu","productTypeLabel","nameCn","nameEn","mainCode","normalizeStringArray","v","s","arr","x","normalizeAttachments","it","f","fmt","weightText","unit","dimText","l","w","p","dictName","id","hit","brandName","unitName","statusName","declarationUnitName","peNames","codes","c","tagList","code","t","skuAttrText","attr","k","basicAttachments","hasDesc","html","mainImage","sizeImages","sellingPointImages","qcMethodLabel","qcImages","qcAttachments","qcCustomList","dictAttrId","parseAttrOptions","out","name","customAttrDictMap","m","customAttrList","info","def","customAttrValueText","values","options","o","bindSkuList","styleAttrs","skuVariants","variantAttrText","supplierQuoteRows","sup","rows","q","_withDirectives","ElDescriptions","ElDescriptionsItem","ElTag","i","_d","si","_hoisted_9","_hoisted_10","_hoisted_15","ElEmpty","displayText","hasCode","useProductDetailDialog","productDetailDialogVisible","productDetailDialogCode","sku","type","keyword","dialogVisible","textareaValue","currentOption","dialogTitleText","normalizeKeywords","parts","unique","seen","part","keywordToTextarea","openDialog","handleDialogClosed","next","prev","__expose","defaultType","_component_el_input","_component_el_select","_component_el_option","_component_el_button","Memo","_component_el_dialog","deepTransformValue","transformer","toSnakeCase","obj","excludeKeys","newValue","toCamelCase","_","char","pick","keys","result","omit","deepClone","cloned","filterEmpty","deep","filtered","flatten","prefix","separator","newKey","unflatten","current","toTableColumns","getComponentImport","componentPath","viewModules","normalizedPath","fullPath","buildRouteTree","routes","routeMap","rootRoutes","currentRoute","parentRoute","transformBackendRoutes","backendRoutes","projectName","routeConfig","component","findFirstAllowedRoute","routePermissions","layoutRouteName","isDescendantOfLayout","parentName","visited","a","b","NProgress","log","args","warn","logError","createRouterGuard","router","getRouteStore","getPermissionStore","getUserStore","isAuthenticated","homeComponent","notFoundComponent","publicPaths","loginRouteName","forbiddenRouteName","homeRouteName","homeRoutePath","homeTitle","noPermissionMessage","hasAddedRoutes","addDynamicRoutes","layoutRoute","childRoutes","redirectToHomeOrContinue","toName","to","_from","routeStore","permissionStore","err","components","JButton","JUploadImg","JSearchHeader","JImportExcel","JAdminLayout","JProductDetailDialog","JSkuLink","JSearchInputDialog","install","app"],"mappings":"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"}
|