vant-vtk 1.0.3 → 1.0.4

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.
Files changed (43) hide show
  1. package/dist/es/Area.js +193 -0
  2. package/dist/es/Area.js.map +1 -0
  3. package/dist/es/Radio.css +1 -0
  4. package/dist/es/Radio.js +79 -0
  5. package/dist/es/Radio.js.map +1 -0
  6. package/dist/es/Uploader.css +1 -0
  7. package/dist/es/Uploader.js +128 -0
  8. package/dist/es/Uploader.js.map +1 -0
  9. package/dist/es/_plugin-vue_export-helper-CHgC5LLL.js +10 -0
  10. package/dist/es/_plugin-vue_export-helper-CHgC5LLL.js.map +1 -0
  11. package/dist/es/checkbox.css +1 -0
  12. package/dist/es/checkbox.js +86 -0
  13. package/dist/es/checkbox.js.map +1 -0
  14. package/dist/es/index.js +35 -0
  15. package/dist/es/index.js.map +1 -0
  16. package/dist/es/preview.css +1 -0
  17. package/dist/es/preview.js +192 -0
  18. package/dist/es/preview.js.map +1 -0
  19. package/dist/lib/Area.js +2 -0
  20. package/dist/lib/Area.js.map +1 -0
  21. package/dist/lib/Radio.css +1 -0
  22. package/dist/lib/Radio.js +2 -0
  23. package/dist/lib/Radio.js.map +1 -0
  24. package/dist/lib/Uploader.css +1 -0
  25. package/dist/lib/Uploader.js +2 -0
  26. package/dist/lib/Uploader.js.map +1 -0
  27. package/dist/lib/_plugin-vue_export-helper-BHFhmbuH.cjs +2 -0
  28. package/dist/lib/_plugin-vue_export-helper-BHFhmbuH.cjs.map +1 -0
  29. package/dist/lib/checkbox.css +1 -0
  30. package/dist/lib/checkbox.js +2 -0
  31. package/dist/lib/checkbox.js.map +1 -0
  32. package/dist/lib/index.js +2 -0
  33. package/dist/lib/index.js.map +1 -0
  34. package/dist/lib/preview.css +1 -0
  35. package/dist/lib/preview.js +2 -0
  36. package/dist/lib/preview.js.map +1 -0
  37. package/dist/style.css +1 -1
  38. package/dist/vant-vtk.es.js +349 -337
  39. package/dist/vant-vtk.es.js.map +1 -1
  40. package/dist/vant-vtk.umd.js +1 -1
  41. package/dist/vant-vtk.umd.js.map +1 -1
  42. package/package.json +1 -1
  43. package/types/index.d.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"vant-vtk.es.js","sources":["../packages/checkbox/index.vue","../packages/checkbox/index.js","../packages/Area/index.vue","../packages/Area/index.js","../packages/Radio/index.vue","../packages/Radio/index.js","../packages/Uploader/index.vue","../packages/Uploader/index.js","../packages/preview/index.vue","../packages/preview/index.js","../src/index.js"],"sourcesContent":["<template>\r\n <van-field v-bind=\"$attrs\">\r\n <template #input>\r\n <van-checkbox-group v-model=\"internalValue\" direction=\"horizontal\">\r\n <van-checkbox v-for=\"item in parsedOptions\" :key=\"String(item.value)\" :name=\"String(item.value)\" shape=\"square\">\r\n {{ item.text }}\r\n </van-checkbox>\r\n </van-checkbox-group>\r\n </template>\r\n </van-field>\r\n</template>\r\n\r\n<script setup>\r\n import { computed } from 'vue'\r\n\r\n defineOptions({\r\n name: 'VtkCheckbox'\r\n })\r\n\r\n const props = defineProps({\r\n // 绑定值\r\n modelValue: {\r\n type: [String, Array, Object],\r\n default: () => [],\r\n },\r\n // 选项数据:支持数组 [{value, text}] 或 字符串 '1:选项1/2:选项2'\r\n options: {\r\n type: [Array, String],\r\n default: () => [],\r\n },\r\n // 返回值类型: 'string' (逗号分隔), 'array' (值数组), 'object' (对象数组)\r\n valueType: {\r\n type: String,\r\n default: 'array',\r\n validator: (val) => ['string', 'array', 'object'].includes(val),\r\n },\r\n // 当 valueType 为 string 时的分隔符\r\n separator: {\r\n type: String,\r\n default: ',',\r\n },\r\n })\r\n\r\n const emit = defineEmits(['update:modelValue', 'change'])\r\n\r\n // 解析选项\r\n const parsedOptions = computed(() => {\r\n if (Array.isArray(props.options)) {\r\n return props.options\r\n }\r\n if (typeof props.options === 'string' && props.options) {\r\n return props.options\r\n .split('/')\r\n .filter(Boolean)\r\n .map((item) => {\r\n const [value, text] = item.split(':')\r\n return {\r\n text: text || value,\r\n value: value,\r\n }\r\n })\r\n }\r\n return []\r\n })\r\n\r\n // 使用可写计算属性处理 v-model 绑定\r\n const internalValue = computed({\r\n get: () => {\r\n const val = props.modelValue\r\n if (!val) return []\r\n\r\n let arr = []\r\n if (props.valueType === 'string') {\r\n arr = typeof val === 'string' ? val.split(props.separator).filter(Boolean) : []\r\n } else if (props.valueType === 'object') {\r\n arr = Array.isArray(val) ? val.map((item) => item?.value ?? item) : []\r\n } else {\r\n arr = Array.isArray(val) ? val : []\r\n }\r\n // 统一转为字符串,确保与 van-checkbox 的 name 匹配\r\n return arr.map(String)\r\n },\r\n set: (newValues) => {\r\n let emitValue\r\n if (props.valueType === 'string') {\r\n emitValue = newValues.join(props.separator)\r\n } else if (props.valueType === 'object') {\r\n // 从解析后的选项中过滤出完整的对象\r\n emitValue = parsedOptions.value.filter((opt) => newValues.includes(String(opt.value)))\r\n } else {\r\n // 如果原始数据是数字,则尝试转回数字,否则保持字符串\r\n emitValue = newValues.map((val) => {\r\n return isNaN(Number(val)) ? val : Array.isArray(props.modelValue) && typeof props.modelValue[0] === 'number' ? Number(val) : val\r\n })\r\n }\r\n\r\n emit('update:modelValue', emitValue)\r\n emit('change', emitValue)\r\n },\r\n })\r\n</script>\r\n\r\n<style scoped>\r\n :deep(.van-checkbox) {\r\n margin-bottom: 8px;\r\n margin-right: 12px;\r\n }\r\n</style>\r\n","/**\r\n * Checkbox 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Checkbox from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nCheckbox.install = (app) => {\r\n app.component(Checkbox.name || 'VtkCheckbox', Checkbox)\r\n}\r\n\r\nexport default Checkbox\r\nexport { Checkbox }\r\n","<template>\r\n\t<van-field v-model=\"displayValue\" is-link readonly v-bind=\"$attrs\" :placeholder=\"placeholder\" @click=\"handleClick\" />\r\n\t<van-popup v-model:show=\"show\" round position=\"bottom\">\r\n\t\t<van-cascader v-model=\"cascaderValue\" :title=\"title\" :options=\"options\" :field-names=\"fieldNames\" @close=\"show = false\" @finish=\"onFinish\" @change=\"onChange\" />\r\n\t</van-popup>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkArea\",\r\n});\r\nimport { ref, watch } from \"vue\";\r\n// import Request from \"@/utils/request\";\r\n\r\nconst props = defineProps({\r\n\t// 绑定值,根据 valueType 返回不同类型\r\n\tmodelValue: {\r\n\t\ttype: [String, Object, Array],\r\n\t\tdefault: \"\",\r\n\t},\r\n\t// 默认地区编码,用于初始化加载\r\n\tdefaultAreaCode: {\r\n\t\ttype: String,\r\n\t\tdefault: \"33\",\r\n\t},\r\n\t// 返回值类型: 'code' 返回最后一级areaCode, 'codes' 返回所有级别areaCode数组, 'object' 返回完整对象信息\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"code\",\r\n\t\tvalidator: (val) => [\"code\", \"codes\", \"object\"].includes(val),\r\n\t},\r\n\t// 显示分隔符\r\n\tseparator: {\r\n\t\ttype: String,\r\n\t\tdefault: \"/\",\r\n\t},\r\n\t// 弹窗标题\r\n\ttitle: {\r\n\t\ttype: String,\r\n\t\tdefault: \"请选择所在地区\",\r\n\t},\r\n\t// 占位文本\r\n\tplaceholder: {\r\n\t\ttype: String,\r\n\t\tdefault: \"请选择所在地区\",\r\n\t},\r\n\t// 最大层级限制,达到该层级后不再加载下级\r\n\tmaxLevel: {\r\n\t\ttype: Number,\r\n\t\tdefault: 12,\r\n\t},\r\n\t// 显示模式: 'full' 显示完整路径, 'last' 只显示最后一级\r\n\tdisplayMode: {\r\n\t\ttype: String,\r\n\t\tdefault: \"full\",\r\n\t\tvalidator: (val) => [\"full\", \"last\"].includes(val),\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"finish\"]);\r\n\r\nconst show = ref(false); //弹窗显示隐藏\r\nconst cascaderValue = ref(\"\"); //级联选择器绑定值\r\nconst options = ref([]); //级联选择器选项\r\nconst displayValue = ref(\"\"); //显示值\r\nconst loading = ref(false); //加载状态\r\n// 存储完整的选中信息\r\nconst selectedData = ref([]);\r\n\r\nconst fieldNames = {\r\n\ttext: \"areaName\",\r\n\tvalue: \"areaCode\",\r\n\tchildren: \"children\",\r\n};\r\n\r\n// 监听 modelValue 变化,用于回显\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(val) => {\r\n\t\tif (!val) {\r\n\t\t\tdisplayValue.value = \"\";\r\n\t\t\tcascaderValue.value = \"\";\r\n\t\t\tselectedData.value = [];\r\n\t\t}\r\n\t},\r\n\t{ immediate: true },\r\n);\r\n\r\nconst handleClick = () => {\r\n\tshow.value = true;\r\n\tif (options.value.length === 0) {\r\n\t\tloadInitialArea();\r\n\t}\r\n};\r\n\r\n// 加载初始地区\r\nconst loadInitialArea = async () => {\r\n\tif (loading.value) return;\r\n\tloading.value = true;\r\n\ttry {\r\n\t\tconst areaCode = props.defaultAreaCode;\r\n\t\tconst res = await Request.getForm(`dict/area/show/${areaCode}`);\r\n\t\tif (res.data) {\r\n\t\t\tconst rootArea = {\r\n\t\t\t\tareaCode: res.data.areaCode,\r\n\t\t\t\tareaName: res.data.areaName,\r\n\t\t\t\tareaLeve: res.data.areaLeve,\r\n\t\t\t\tchildren: res.data.areaLeve < props.maxLevel ? [] : undefined,\r\n\t\t\t};\r\n\t\t\toptions.value = [rootArea];\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tconsole.error(\"加载初始地区失败:\", error);\r\n\t} finally {\r\n\t\tloading.value = false;\r\n\t}\r\n};\r\n\r\n// 加载下级地区\r\nconst loadChildren = async (item) => {\r\n\tif (item._loading) return;\r\n\titem._loading = true;\r\n\ttry {\r\n\t\tconst res = await Request.getForm(`dict/area/next/${item.areaCode}`);\r\n\t\tif (res.data && res.data.length > 0) {\r\n\t\t\tres.data.forEach((it) => {\r\n\t\t\t\t// 根据 maxLevel 判断是否还有下级\r\n\t\t\t\tif (it.areaLeve < props.maxLevel) {\r\n\t\t\t\t\tit.children = [];\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\titem.children = res.data;\r\n\t\t} else {\r\n\t\t\t// 没有下级数据,移除 children 属性使其成为叶子节点\r\n\t\t\tdelete item.children;\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tconsole.error(\"加载下级地区失败:\", error);\r\n\t} finally {\r\n\t\titem._loading = false;\r\n\t}\r\n};\r\n\r\n// 选项变化时加载下级\r\nconst onChange = ({ value, selectedOptions, tabIndex }) => {\r\n\tconst currentItem = selectedOptions[tabIndex];\r\n\tif (currentItem && currentItem.areaLeve < props.maxLevel && Array.isArray(currentItem.children) && currentItem.children.length === 0) {\r\n\t\tloadChildren(currentItem);\r\n\t}\r\n\temit(\"change\", { value, selectedOptions, tabIndex });\r\n};\r\n\r\n// 完成选择\r\nconst onFinish = ({ selectedOptions }) => {\r\n\t// 根据 displayMode 决定显示值\r\n\tif (props.displayMode === \"last\") {\r\n\t\t// 只显示最后一级\r\n\t\tdisplayValue.value = selectedOptions[selectedOptions.length - 1]?.areaName || \"\";\r\n\t} else {\r\n\t\t// 显示完整路径(默认)\r\n\t\tdisplayValue.value = selectedOptions.map((option) => option.areaName).join(props.separator);\r\n\t}\r\n\r\n\t// 存储完整选中数据\r\n\tselectedData.value = selectedOptions.map((option) => ({\r\n\t\tareaCode: option.areaCode,\r\n\t\tareaName: option.areaName,\r\n\t\tareaLeve: option.areaLeve,\r\n\t}));\r\n\r\n\t// 根据 valueType 返回不同格式的值\r\n\tlet emitValue;\r\n\tswitch (props.valueType) {\r\n\t\tcase \"code\":\r\n\t\t\t// 返回最后一级的 areaCode\r\n\t\t\temitValue = selectedOptions[selectedOptions.length - 1]?.areaCode || \"\";\r\n\t\t\tbreak;\r\n\t\tcase \"codes\":\r\n\t\t\t// 返回所有级别的 areaCode 数组\r\n\t\t\temitValue = selectedOptions.map((option) => option.areaCode);\r\n\t\t\tbreak;\r\n\t\tcase \"object\":\r\n\t\t\t// 返回完整对象信息\r\n\t\t\temitValue = {\r\n\t\t\t\tcodes: selectedOptions.map((option) => option.areaCode),\r\n\t\t\t\tnames: selectedOptions.map((option) => option.areaName),\r\n\t\t\t\tfullName: selectedOptions.map((option) => option.areaName).join(props.separator),\r\n\t\t\t\tlastCode: selectedOptions[selectedOptions.length - 1]?.areaCode || \"\",\r\n\t\t\t\tlastLevel: selectedOptions[selectedOptions.length - 1]?.areaLeve,\r\n\t\t\t\toptions: selectedData.value,\r\n\t\t\t};\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\temitValue = selectedOptions[selectedOptions.length - 1]?.areaCode || \"\";\r\n\t}\r\n\r\n\temit(\"update:modelValue\", emitValue);\r\n\temit(\"finish\", { selectedOptions, value: emitValue });\r\n\tshow.value = false;\r\n};\r\n\r\n// 暴露方法供外部调用\r\ndefineExpose({\r\n\t// 获取当前选中的完整数据\r\n\tgetSelectedData: () => selectedData.value,\r\n\t// 获取显示值\r\n\tgetDisplayValue: () => displayValue.value,\r\n\t// 重置选择\r\n\treset: () => {\r\n\t\tdisplayValue.value = \"\";\r\n\t\tcascaderValue.value = \"\";\r\n\t\tselectedData.value = [];\r\n\t\temit(\"update:modelValue\", props.valueType === \"codes\" ? [] : props.valueType === \"object\" ? null : \"\");\r\n\t},\r\n\t// 打开选择器\r\n\topen: () => {\r\n\t\thandleClick();\r\n\t},\r\n\t// 关闭选择器\r\n\tclose: () => {\r\n\t\tshow.value = false;\r\n\t},\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped></style>\r\n","/**\r\n * Area 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Area from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nArea.install = (app) => {\r\n app.component(Area.name || 'VtkArea', Area)\r\n}\r\n\r\nexport default Area\r\nexport { Area }\r\n","<template>\r\n\t<van-field v-bind=\"$attrs\">\r\n\t\t<template #input>\r\n\t\t\t<van-radio-group v-model=\"internalValue\" direction=\"horizontal\">\r\n\t\t\t\t<van-radio v-for=\"item in parsedOptions\" :key=\"String(item.value)\" :name=\"String(item.value)\">\r\n\t\t\t\t\t{{ item.text }}\r\n\t\t\t\t</van-radio>\r\n\t\t\t</van-radio-group>\r\n\t\t</template>\r\n\t</van-field>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkRadio\",\r\n});\r\nimport { computed } from \"vue\";\r\n\r\nconst props = defineProps({\r\n\t// 绑定值\r\n\tmodelValue: {\r\n\t\ttype: [String, Number, Object],\r\n\t\tdefault: \"\",\r\n\t},\r\n\t// 选项数据:支持数组 [{value, text}] 或 字符串 '1:选项1/2:选项2'\r\n\toptions: {\r\n\t\ttype: [Array, String],\r\n\t\tdefault: () => [],\r\n\t},\r\n\t// 返回值类型: 'string' (基本类型), 'object' (完整对象)\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"string\",\r\n\t\tvalidator: (val) => [\"string\", \"object\"].includes(val),\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\r\n\r\n// 解析选项\r\nconst parsedOptions = computed(() => {\r\n\tif (Array.isArray(props.options)) {\r\n\t\treturn props.options;\r\n\t}\r\n\tif (typeof props.options === \"string\" && props.options) {\r\n\t\treturn props.options\r\n\t\t\t.split(\"/\")\r\n\t\t\t.filter(Boolean)\r\n\t\t\t.map((item) => {\r\n\t\t\t\tconst [value, text] = item.split(\":\");\r\n\t\t\t\treturn {\r\n\t\t\t\t\ttext: text || value,\r\n\t\t\t\t\tvalue: value,\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t}\r\n\treturn [];\r\n});\r\n\r\n// 使用可写计算属性处理 v-model 绑定\r\nconst internalValue = computed({\r\n\tget: () => {\r\n\t\tconst val = props.modelValue;\r\n\t\tif (val === undefined || val === null) return \"\";\r\n\r\n\t\t// 如果是对象类型,提取其中的 value\r\n\t\tif (props.valueType === \"object\" && val && typeof val === \"object\") {\r\n\t\t\treturn String(val.value ?? \"\");\r\n\t\t}\r\n\t\treturn String(val);\r\n\t},\r\n\tset: (newValue) => {\r\n\t\tlet emitValue = newValue;\r\n\r\n\t\t// 处理原始数据类型逻辑(如果父组件传入的是数字,尝试转回数字)\r\n\t\tconst originalValue = props.valueType === \"object\" ? props.modelValue?.value : props.modelValue;\r\n\t\tif (typeof originalValue === \"number\" && !isNaN(Number(newValue))) {\r\n\t\t\temitValue = Number(newValue);\r\n\t\t}\r\n\r\n\t\tif (props.valueType === \"object\") {\r\n\t\t\t// 找回完整对象\r\n\t\t\temitValue = parsedOptions.value.find((opt) => String(opt.value) === String(newValue)) || null;\r\n\t\t}\r\n\r\n\t\temit(\"update:modelValue\", emitValue);\r\n\t\temit(\"change\", emitValue);\r\n\t},\r\n});\r\n</script>\r\n\r\n<style scoped>\r\n:deep(.van-radio) {\r\n\tmargin-right: 12px;\r\n}\r\n</style>\r\n","/**\r\n * Radio 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Radio from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nRadio.install = (app) => {\r\n app.component(Radio.name || 'VtkRadio', Radio)\r\n}\r\n\r\nexport default Radio\r\nexport { Radio }\r\n","<template>\r\n\t<van-uploader v-model=\"fileList\" v-bind=\"$attrs\" :max-size=\"maxSize\" :accept=\"accept\" :before-read=\"beforeRead\" :after-read=\"afterRead\" @delete=\"onDelete\" />\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkUploader\",\r\n\tinheritAttrs: false,\r\n});\r\nimport { ref, watch } from \"vue\";\r\nimport { showToast, showLoadingToast, closeToast } from \"vant\";\r\n\r\nconst props = defineProps({\r\n\t/** 绑定值,支持字符串或数组 */\r\n\tmodelValue: {\r\n\t\ttype: [String, Array],\r\n\t\tdefault: () => [],\r\n\t},\r\n\t/** 返回值类型:'string' 返回逗号分隔的字符串,'array' 返回数组 */\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"array\",\r\n\t\tvalidator: (val) => [\"string\", \"array\"].includes(val),\r\n\t},\r\n\t/** 单个文件最大大小(字节),默认10MB */\r\n\tmaxSize: {\r\n\t\ttype: Number,\r\n\t\tdefault: 10 * 1024 * 1024,\r\n\t},\r\n\t/** 接受的文件类型 */\r\n\taccept: {\r\n\t\ttype: String,\r\n\t\tdefault: \"image/*\",\r\n\t},\r\n\t/** 上传接口地址 */\r\n\tuploadUrl: {\r\n\t\ttype: String,\r\n\t\tdefault: \"/bizp/admin/upload\",\r\n\t},\r\n\t/** 上传文件的字段名 */\r\n\tfieldName: {\r\n\t\ttype: String,\r\n\t\tdefault: \"file\",\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"success\", \"error\"]);\r\n\r\n// 文件列表\r\nconst fileList = ref([]);\r\n\r\n// 解析初始值\r\nconst parseModelValue = (value) => {\r\n\tif (!value) return [];\r\n\r\n\tlet urls = [];\r\n\tif (typeof value === \"string\") {\r\n\t\turls = value.split(\",\").filter((url) => url.trim());\r\n\t} else if (Array.isArray(value)) {\r\n\t\turls = value.filter((url) => url);\r\n\t}\r\n\r\n\treturn urls.map((url) => ({\r\n\t\turl,\r\n\t\tstatus: \"done\",\r\n\t\tmessage: \"\",\r\n\t}));\r\n};\r\n\r\n// 获取已上传的URL列表\r\nconst getUploadedUrls = () => {\r\n\treturn fileList.value.filter((file) => file.status === \"done\" && file.url).map((file) => file.url);\r\n};\r\n\r\n// 格式化输出值\r\nconst formatOutput = (urls) => {\r\n\tif (props.valueType === \"string\") {\r\n\t\treturn urls.join(\",\");\r\n\t}\r\n\treturn urls;\r\n};\r\n\r\n// 触发更新\r\nconst emitValue = () => {\r\n\tconst urls = getUploadedUrls();\r\n\tconst output = formatOutput(urls);\r\n\temit(\"update:modelValue\", output);\r\n\temit(\"change\", output);\r\n};\r\n\r\n// 监听外部值变化\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(newVal) => {\r\n\t\tconst currentUrls = getUploadedUrls().join(\",\");\r\n\t\tconst newUrls = Array.isArray(newVal) ? newVal.join(\",\") : newVal || \"\";\r\n\r\n\t\t// 只有外部值确实改变时才更新\r\n\t\tif (currentUrls !== newUrls) {\r\n\t\t\tfileList.value = parseModelValue(newVal);\r\n\t\t}\r\n\t},\r\n\t{ immediate: true },\r\n);\r\n\r\n// 上传前校验\r\nconst beforeRead = (file) => {\r\n\tconst files = Array.isArray(file) ? file : [file];\r\n\r\n\tfor (const f of files) {\r\n\t\t// 文件大小校验\r\n\t\tif (f.size > props.maxSize) {\r\n\t\t\tconst maxSizeMB = (props.maxSize / 1024 / 1024).toFixed(1);\r\n\t\t\tshowToast(`文件大小不能超过${maxSizeMB}MB`);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\treturn true;\r\n};\r\n\r\n// 上传文件\r\nconst uploadFile = async (file) => {\r\n\tconst formData = new FormData();\r\n\tformData.append(props.fieldName, file.file);\r\n\r\n\ttry {\r\n\t\tconst res = await Request.imp(props.uploadUrl, formData);\r\n\r\n\t\tif (res.meta?.success) {\r\n\t\t\t// 根据实际接口返回格式获取URL\r\n\t\t\tconst url = res.data?.url || res.data?.path || res.data;\r\n\t\t\treturn { success: true, url };\r\n\t\t} else {\r\n\t\t\treturn { success: false, message: res.meta?.message || \"上传失败\" };\r\n\t\t}\r\n\t} catch (error) {\r\n\t\treturn { success: false, message: error.message || \"上传失败\" };\r\n\t}\r\n};\r\n\r\n// 文件读取完成后处理\r\nconst afterRead = async (file) => {\r\n\tconst files = Array.isArray(file) ? file : [file];\r\n\r\n\t// 显示上传中提示\r\n\tif (files.length > 1) {\r\n\t\tshowLoadingToast({\r\n\t\t\tmessage: `正在上传 0/${files.length}`,\r\n\t\t\tforbidClick: true,\r\n\t\t\tduration: 0,\r\n\t\t});\r\n\t}\r\n\r\n\tlet successCount = 0;\r\n\tlet failCount = 0;\r\n\r\n\t// 逐个上传\r\n\tfor (let i = 0; i < files.length; i++) {\r\n\t\tconst fileItem = files[i];\r\n\t\tfileItem.status = \"uploading\";\r\n\t\tfileItem.message = \"上传中...\";\r\n\r\n\t\t// 更新进度提示\r\n\t\tif (files.length > 1) {\r\n\t\t\tshowLoadingToast({\r\n\t\t\t\tmessage: `正在上传 ${i + 1}/${files.length}`,\r\n\t\t\t\tforbidClick: true,\r\n\t\t\t\tduration: 0,\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tconst result = await uploadFile(fileItem);\r\n\r\n\t\tif (result.success) {\r\n\t\t\tfileItem.status = \"done\";\r\n\t\t\tfileItem.message = \"\";\r\n\t\t\tfileItem.url = result.url;\r\n\t\t\tsuccessCount++;\r\n\t\t\temit(\"success\", { file: fileItem, url: result.url });\r\n\t\t} else {\r\n\t\t\tfileItem.status = \"failed\";\r\n\t\t\tfileItem.message = result.message;\r\n\t\t\tfailCount++;\r\n\t\t\temit(\"error\", { file: fileItem, message: result.message });\r\n\t\t}\r\n\t}\r\n\r\n\tcloseToast();\r\n\r\n\t// 显示上传结果\r\n\tif (files.length > 1) {\r\n\t\tif (failCount === 0) {\r\n\t\t\tshowToast(`${successCount}个文件上传成功`);\r\n\t\t} else {\r\n\t\t\tshowToast(`${successCount}个成功,${failCount}个失败`);\r\n\t\t}\r\n\t} else if (failCount > 0) {\r\n\t\tshowToast(files[0].message || \"上传失败\");\r\n\t}\r\n\r\n\t// 触发值更新\r\n\temitValue();\r\n};\r\n\r\n// 删除文件\r\nconst onDelete = () => {\r\n\t// 下一个tick再触发,确保fileList已更新\r\n\tsetTimeout(() => {\r\n\t\temitValue();\r\n\t}, 0);\r\n};\r\n\r\n// 暴露方法给父组件\r\ndefineExpose({\r\n\t/** 获取已上传的URL列表 */\r\n\tgetUrls: getUploadedUrls,\r\n\t/** 清空文件列表 */\r\n\tclear: () => {\r\n\t\tfileList.value = [];\r\n\t\temitValue();\r\n\t},\r\n\t/** 获取文件列表 */\r\n\tgetFileList: () => fileList.value,\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n:deep(.van-uploader__preview-image) {\r\n\tborder-radius: 4px;\r\n}\r\n\r\n:deep(.van-uploader__upload) {\r\n\tborder-radius: 4px;\r\n}\r\n</style>\r\n","/**\r\n * Uploader 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Uploader from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nUploader.install = (app) => {\r\n app.component(Uploader.name || 'VtkUploader', Uploader)\r\n}\r\n\r\nexport default Uploader\r\nexport { Uploader }\r\n","<template>\r\n\t<van-popup v-model:show=\"showPopup\" position=\"bottom\" :style=\"{ height: '100vh' }\">\r\n\t\t<div class=\"file-preview-container\">\r\n\t\t\t<div class=\"file-header\">\r\n\t\t\t\t<div class=\"file-title\">{{ currentFile?.name || \"文件预览\" }}</div>\r\n\t\t\t\t<van-icon name=\"cross\" size=\"20\" @click=\"handleClose\" />\r\n\t\t\t</div>\r\n\r\n\t\t\t<div class=\"file-content\">\r\n\t\t\t\t<div v-if=\"currentType === 'image'\" class=\"image-preview\">\r\n\t\t\t\t\t<van-image :src=\"currentFile?.url\" fit=\"contain\" class=\"preview-image\" />\r\n\t\t\t\t\t<div class=\"image-footer\">\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentIndex <= 0\" @click=\"prevFile\">上一个</van-button>\r\n\t\t\t\t\t\t<span class=\"file-info\">{{ currentIndex + 1 }} / {{ files.length }}</span>\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\">下一个</van-button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<div v-else-if=\"currentType === 'pdf'\" class=\"pdf-preview\">\r\n\t\t\t\t\t<VuePdfEmbed v-if=\"pdfSource\" :source=\"pdfSource\" :page=\"currentPage\" class=\"pdf-embed-preview\" @rendered=\"handlePdfRendered\" @loaded=\"handlePdfLoaded\" />\r\n\t\t\t\t\t<div v-else class=\"pdf-placeholder\">请选择PDF文件</div>\r\n\t\t\t\t\t<div class=\"pdf-footer\">\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentPage <= 1\" @click=\"currentPage--\">上一页</van-button>\r\n\t\t\t\t\t\t<span class=\"page-info\">第 {{ currentPage }} / {{ totalPages || \"?\" }} 页</span>\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"!pdfSource || currentPage >= totalPages\" @click=\"currentPage++\">下一页</van-button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<div class=\"footer\">\r\n\t\t\t\t\t<van-button :disabled=\"currentIndex <= 0\" @click=\"prevFile\" icon=\"arrow-left\" type=\"primary\" round />\r\n\t\t\t\t\t<van-button :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\" icon=\"arrow\" type=\"primary\" round />\r\n\t\t\t\t\t<!-- <van-button size=\"small\" :disabled=\"currentIndex <= 0\" @click=\"prevFile\">上一个</van-button>\r\n <span class=\"file-info\">{{ currentIndex + 1 }} / {{ files.length }}</span>\r\n <van-button size=\"small\" :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\">下一个</van-button> -->\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</van-popup>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkPreview\",\r\n});\r\nimport { ref, watch, computed } from \"vue\";\r\nimport VuePdfEmbed from \"vue-pdf-embed\";\r\n\r\nconst props = defineProps({\r\n\tmodelValue: {\r\n\t\ttype: Boolean,\r\n\t\tdefault: false,\r\n\t},\r\n\tfiles: {\r\n\t\ttype: Array,\r\n\t\tdefault: () => [],\r\n\t},\r\n\tstartIndex: {\r\n\t\ttype: Number,\r\n\t\tdefault: 0,\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"close\"]);\r\n\r\nconst showPopup = ref(props.modelValue);\r\nconst currentIndex = ref(props.startIndex);\r\nconst currentPage = ref(1);\r\nconst pdfSource = ref(null);\r\nconst totalPages = ref(0);\r\n\r\nconst normalizedFiles = computed(() => {\r\n\treturn props.files.map((file, index) => {\r\n\t\tif (typeof file === \"string\") {\r\n\t\t\tconst isPdf = file.toLowerCase().endsWith(\".pdf\");\r\n\t\t\treturn {\r\n\t\t\t\tname: isPdf ? `文档${index + 1}.pdf` : `图片${index + 1}`,\r\n\t\t\t\turl: file,\r\n\t\t\t\ttype: isPdf ? \"pdf\" : \"image\",\r\n\t\t\t};\r\n\t\t}\r\n\t\treturn file;\r\n\t});\r\n});\r\n\r\nconst currentFile = computed(() => {\r\n\treturn normalizedFiles.value[currentIndex.value] || null;\r\n});\r\n\r\nconst currentType = computed(() => {\r\n\tif (!currentFile.value) return null;\r\n\tconst url = currentFile.value.url || currentFile.value;\r\n\tif (typeof url === \"string\") {\r\n\t\treturn url.toLowerCase().endsWith(\".pdf\") ? \"pdf\" : \"image\";\r\n\t}\r\n\treturn currentFile.value.type || \"image\";\r\n});\r\n\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(val) => {\r\n\t\tshowPopup.value = val;\r\n\t\tif (val && normalizedFiles.value.length > 0) {\r\n\t\t\tcurrentIndex.value = props.startIndex;\r\n\t\t\tupdatePreview();\r\n\t\t}\r\n\t},\r\n);\r\n\r\nwatch(\r\n\t() => props.startIndex,\r\n\t(val) => {\r\n\t\tcurrentIndex.value = val;\r\n\t\tupdatePreview();\r\n\t},\r\n);\r\n\r\nwatch(showPopup, (val) => {\r\n\temit(\"update:modelValue\", val);\r\n\tif (!val) {\r\n\t\thandleClose();\r\n\t}\r\n});\r\n\r\nwatch(currentIndex, () => {\r\n\tcurrentPage.value = 1;\r\n\ttotalPages.value = 0;\r\n\tupdatePreview();\r\n});\r\n\r\nconst updatePreview = () => {\r\n\tconst file = currentFile.value;\r\n\tif (!file) return;\r\n\r\n\tif (currentType.value === \"pdf\") {\r\n\t\tpdfSource.value = file.url || file;\r\n\t} else {\r\n\t\tpdfSource.value = null;\r\n\t}\r\n};\r\n\r\nconst handlePdfLoaded = (pdf) => {\r\n\ttotalPages.value = pdf.numPages || 0;\r\n};\r\n\r\nconst handlePdfRendered = () => {\r\n\tconsole.log(\"PDF rendered successfully\");\r\n};\r\n\r\nconst prevFile = () => {\r\n\tif (currentIndex.value > 0) {\r\n\t\tcurrentIndex.value--;\r\n\t}\r\n};\r\n\r\nconst nextFile = () => {\r\n\tif (currentIndex.value < normalizedFiles.value.length - 1) {\r\n\t\tcurrentIndex.value++;\r\n\t}\r\n};\r\n\r\nconst handleClose = () => {\r\n\tshowPopup.value = false;\r\n\tpdfSource.value = null;\r\n\tcurrentPage.value = 1;\r\n\ttotalPages.value = 0;\r\n\temit(\"close\");\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.file-preview-container {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\theight: 100%;\r\n\tbackground-color: #fff;\r\n\tborder-radius: 8px;\r\n\toverflow: hidden;\r\n}\r\n\r\n.file-header {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: space-between;\r\n\tpadding: 12px 16px;\r\n\tborder-bottom: 1px solid #ebedf0;\r\n\tbackground-color: #f7f8fa;\r\n}\r\n\r\n.file-title {\r\n\tfont-size: 16px;\r\n\tfont-weight: 600;\r\n\tcolor: #323233;\r\n}\r\n\r\n.file-content {\r\n\tflex: 1;\r\n\toverflow: hidden;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n}\r\n\r\n.image-preview {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\toverflow: hidden;\r\n}\r\n\r\n.preview-image {\r\n\tflex: 1;\r\n\twidth: 100%;\r\n\theight: 100%;\r\n}\r\n\r\n.image-footer {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 16px;\r\n\tpadding: 12px 16px;\r\n\tborder-top: 1px solid #ebedf0;\r\n\tbackground-color: #fff;\r\n}\r\n\r\n.file-info {\r\n\tfont-size: 14px;\r\n\tcolor: #646566;\r\n\tmin-width: 80px;\r\n\ttext-align: center;\r\n}\r\n\r\n.pdf-preview {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\toverflow: hidden;\r\n}\r\n\r\n.pdf-embed-preview {\r\n\tflex: 1;\r\n\tmax-width: 100%;\r\n\toverflow-y: auto;\r\n\tpadding: 16px;\r\n\tdisplay: flex;\r\n\tjustify-content: center;\r\n\talign-items: flex-start;\r\n\tbackground-color: #f5f5f5;\r\n\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n.pdf-placeholder {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tcolor: #969799;\r\n\tfont-size: 14px;\r\n}\r\n\r\n.pdf-footer {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 16px;\r\n\tpadding: 12px 16px;\r\n\tborder-top: 1px solid #ebedf0;\r\n\tbackground-color: #fff;\r\n}\r\n\r\n.page-info {\r\n\tfont-size: 14px;\r\n\tcolor: #646566;\r\n\tmin-width: 80px;\r\n\ttext-align: center;\r\n}\r\n.footer {\r\n\tposition: fixed;\r\n\ttop: 40%;\r\n\twidth: 100%;\r\n\t.van-button {\r\n\t}\r\n\t.van-button:nth-child(2) {\r\n\t\tfloat: right;\r\n\t}\r\n}\r\n</style>\r\n","/**\r\n * Preview 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Preview from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nPreview.install = (app) => {\r\n app.component(Preview.name || 'VtkPreview', Preview)\r\n}\r\n\r\nexport default Preview\r\nexport { Preview }\r\n","/**\r\n * Vant-VTK 组件库全量导出入口\r\n * 支持全量引入和按需引入\r\n */\r\nimport Checkbox from '../packages/checkbox/index.js'\r\nimport Area from '../packages/Area/index.js'\r\nimport Radio from '../packages/radio/index.js'\r\nimport Uploader from '../packages/Uploader/index.js'\r\nimport Preview from '../packages/preview/index.js'\r\n\r\n\r\n\r\n// 所有组件列表\r\nconst components = [\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n]\r\n\r\n// 全量注册方法\r\nconst install = (app) => {\r\n components.forEach(component => {\r\n if (component.install) {\r\n app.use(component)\r\n } else if (component.name) {\r\n app.component(component.name, component)\r\n }\r\n })\r\n}\r\n\r\n// 默认导出 - 支持 app.use(VantVtk) 全量注册\r\nexport default {\r\n install,\r\n // 也导出所有组件,方便直接访问\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n}\r\n\r\n// 具名导出 - 支持按需引入\r\nexport {\r\n install,\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n}\r\n\r\n// 导出版本号\r\nexport const version = '1.0.0'\r\n"],"names":["props","__props","emit","__emit","parsedOptions","computed","item","value","text","internalValue","val","arr","newValues","emitValue","opt","_openBlock","_createBlock","_component_van_field","$attrs","_createVNode","_component_van_checkbox_group","$event","_createElementBlock","_Fragment","_renderList","_component_van_checkbox","_createTextVNode","_toDisplayString","Checkbox","app","show","ref","cascaderValue","options","displayValue","loading","selectedData","fieldNames","watch","handleClick","loadInitialArea","areaCode","res","rootArea","error","loadChildren","it","onChange","selectedOptions","tabIndex","currentItem","onFinish","_a","option","_b","_c","_d","_e","__expose","_mergeProps","_component_van_popup","_component_van_cascader","Area","newValue","_component_van_radio_group","_component_van_radio","Radio","fileList","parseModelValue","urls","url","getUploadedUrls","file","formatOutput","output","newVal","currentUrls","newUrls","beforeRead","files","maxSizeMB","showToast","uploadFile","formData","afterRead","showLoadingToast","successCount","failCount","i","fileItem","result","closeToast","onDelete","_component_van_uploader","Uploader","showPopup","currentIndex","currentPage","pdfSource","totalPages","normalizedFiles","index","isPdf","currentFile","currentType","updatePreview","handleClose","handlePdfLoaded","pdf","handlePdfRendered","prevFile","nextFile","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_component_van_icon","_hoisted_4","_hoisted_5","_component_van_image","_hoisted_6","_component_van_button","_cache","_hoisted_7","_hoisted_8","_unref","VuePdfEmbed","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","Preview","components","install","component","version"],"mappings":"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"}
1
+ {"version":3,"file":"vant-vtk.es.js","sources":["../packages/checkbox/index.vue","../packages/checkbox/index.js","../packages/Area/index.vue","../packages/Area/index.js","../packages/Radio/index.vue","../packages/Radio/index.js","../packages/Uploader/index.vue","../packages/Uploader/index.js","../packages/preview/index.vue","../packages/preview/index.js","../src/index.js"],"sourcesContent":["<template>\r\n <van-field v-bind=\"$attrs\">\r\n <template #input>\r\n <van-checkbox-group v-model=\"internalValue\" direction=\"horizontal\">\r\n <van-checkbox v-for=\"item in parsedOptions\" :key=\"String(item.value)\" :name=\"String(item.value)\" shape=\"square\">\r\n {{ item.text }}\r\n </van-checkbox>\r\n </van-checkbox-group>\r\n </template>\r\n </van-field>\r\n</template>\r\n\r\n<script setup>\r\n import { computed } from 'vue'\r\n\r\n defineOptions({\r\n name: 'VtkCheckbox'\r\n })\r\n\r\n const props = defineProps({\r\n // 绑定值\r\n modelValue: {\r\n type: [String, Array, Object],\r\n default: () => [],\r\n },\r\n // 选项数据:支持数组 [{value, text}] 或 字符串 '1:选项1/2:选项2'\r\n options: {\r\n type: [Array, String],\r\n default: () => [],\r\n },\r\n // 返回值类型: 'string' (逗号分隔), 'array' (值数组), 'object' (对象数组)\r\n valueType: {\r\n type: String,\r\n default: 'array',\r\n validator: (val) => ['string', 'array', 'object'].includes(val),\r\n },\r\n // 当 valueType 为 string 时的分隔符\r\n separator: {\r\n type: String,\r\n default: ',',\r\n },\r\n })\r\n\r\n const emit = defineEmits(['update:modelValue', 'change'])\r\n\r\n // 解析选项\r\n const parsedOptions = computed(() => {\r\n if (Array.isArray(props.options)) {\r\n return props.options\r\n }\r\n if (typeof props.options === 'string' && props.options) {\r\n return props.options\r\n .split('/')\r\n .filter(Boolean)\r\n .map((item) => {\r\n const [value, text] = item.split(':')\r\n return {\r\n text: text || value,\r\n value: value,\r\n }\r\n })\r\n }\r\n return []\r\n })\r\n\r\n // 使用可写计算属性处理 v-model 绑定\r\n const internalValue = computed({\r\n get: () => {\r\n const val = props.modelValue\r\n if (!val) return []\r\n\r\n let arr = []\r\n if (props.valueType === 'string') {\r\n arr = typeof val === 'string' ? val.split(props.separator).filter(Boolean) : []\r\n } else if (props.valueType === 'object') {\r\n arr = Array.isArray(val) ? val.map((item) => item?.value ?? item) : []\r\n } else {\r\n arr = Array.isArray(val) ? val : []\r\n }\r\n // 统一转为字符串,确保与 van-checkbox 的 name 匹配\r\n return arr.map(String)\r\n },\r\n set: (newValues) => {\r\n let emitValue\r\n if (props.valueType === 'string') {\r\n emitValue = newValues.join(props.separator)\r\n } else if (props.valueType === 'object') {\r\n // 从解析后的选项中过滤出完整的对象\r\n emitValue = parsedOptions.value.filter((opt) => newValues.includes(String(opt.value)))\r\n } else {\r\n // 如果原始数据是数字,则尝试转回数字,否则保持字符串\r\n emitValue = newValues.map((val) => {\r\n return isNaN(Number(val)) ? val : Array.isArray(props.modelValue) && typeof props.modelValue[0] === 'number' ? Number(val) : val\r\n })\r\n }\r\n\r\n emit('update:modelValue', emitValue)\r\n emit('change', emitValue)\r\n },\r\n })\r\n</script>\r\n\r\n<style scoped>\r\n :deep(.van-checkbox) {\r\n margin-bottom: 8px;\r\n margin-right: 12px;\r\n }\r\n</style>\r\n","/**\r\n * Checkbox 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Checkbox from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nCheckbox.install = (app) => {\r\n app.component(Checkbox.name || 'VtkCheckbox', Checkbox)\r\n}\r\n\r\nexport default Checkbox\r\nexport { Checkbox }\r\n","<template>\r\n\t<van-field v-model=\"displayValue\" is-link readonly v-bind=\"$attrs\" :placeholder=\"placeholder\" @click=\"handleClick\" />\r\n\t<van-popup v-model:show=\"show\" round position=\"bottom\">\r\n\t\t<van-cascader v-model=\"cascaderValue\" :title=\"title\" :options=\"options\" :field-names=\"fieldNames\" @close=\"show = false\" @finish=\"onFinish\" @change=\"onChange\" />\r\n\t</van-popup>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkArea\",\r\n});\r\nimport { ref, watch, inject, getCurrentInstance } from \"vue\";\r\n// import Request from \"@/utils/request\";\r\n\r\nconst injectedRequest = inject(\"vant-vtk:request\", null);\r\nconst globalProperties = getCurrentInstance()?.appContext.config.globalProperties;\r\nconst globalRequest = globalProperties?.$vtkRequest || globalProperties?.$request;\r\nconst getRequest = () => {\r\n\tconst request = injectedRequest || globalRequest;\r\n\tif (!request) {\r\n\t\tthrow new Error(\"VantVtk request 未配置\");\r\n\t}\r\n\treturn request;\r\n};\r\n\r\nconst props = defineProps({\r\n\t// 绑定值,根据 valueType 返回不同类型\r\n\tmodelValue: {\r\n\t\ttype: [String, Object, Array],\r\n\t\tdefault: \"\",\r\n\t},\r\n\t// 默认地区编码,用于初始化加载\r\n\tdefaultAreaCode: {\r\n\t\ttype: String,\r\n\t\tdefault: \"33\",\r\n\t},\r\n\t// 返回值类型: 'code' 返回最后一级areaCode, 'codes' 返回所有级别areaCode数组, 'object' 返回完整对象信息\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"code\",\r\n\t\tvalidator: (val) => [\"code\", \"codes\", \"object\"].includes(val),\r\n\t},\r\n\t// 显示分隔符\r\n\tseparator: {\r\n\t\ttype: String,\r\n\t\tdefault: \"/\",\r\n\t},\r\n\t// 弹窗标题\r\n\ttitle: {\r\n\t\ttype: String,\r\n\t\tdefault: \"请选择所在地区\",\r\n\t},\r\n\t// 占位文本\r\n\tplaceholder: {\r\n\t\ttype: String,\r\n\t\tdefault: \"请选择所在地区\",\r\n\t},\r\n\t// 最大层级限制,达到该层级后不再加载下级\r\n\tmaxLevel: {\r\n\t\ttype: Number,\r\n\t\tdefault: 12,\r\n\t},\r\n\t// 显示模式: 'full' 显示完整路径, 'last' 只显示最后一级\r\n\tdisplayMode: {\r\n\t\ttype: String,\r\n\t\tdefault: \"full\",\r\n\t\tvalidator: (val) => [\"full\", \"last\"].includes(val),\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"finish\"]);\r\n\r\nconst show = ref(false); //弹窗显示隐藏\r\nconst cascaderValue = ref(\"\"); //级联选择器绑定值\r\nconst options = ref([]); //级联选择器选项\r\nconst displayValue = ref(\"\"); //显示值\r\nconst loading = ref(false); //加载状态\r\n// 存储完整的选中信息\r\nconst selectedData = ref([]);\r\n\r\nconst fieldNames = {\r\n\ttext: \"areaName\",\r\n\tvalue: \"areaCode\",\r\n\tchildren: \"children\",\r\n};\r\n\r\n// 监听 modelValue 变化,用于回显\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(val) => {\r\n\t\tif (!val) {\r\n\t\t\tdisplayValue.value = \"\";\r\n\t\t\tcascaderValue.value = \"\";\r\n\t\t\tselectedData.value = [];\r\n\t\t}\r\n\t},\r\n\t{ immediate: true },\r\n);\r\n\r\nconst handleClick = () => {\r\n\tshow.value = true;\r\n\tif (options.value.length === 0) {\r\n\t\tloadInitialArea();\r\n\t}\r\n};\r\n\r\n// 加载初始地区\r\nconst loadInitialArea = async () => {\r\n\tif (loading.value) return;\r\n\tloading.value = true;\r\n\ttry {\r\n\t\tconst areaCode = props.defaultAreaCode;\r\n\t\tconst res = await getRequest().getForm(`dict/area/show/${areaCode}`);\r\n\t\tif (res.data) {\r\n\t\t\tconst rootArea = {\r\n\t\t\t\tareaCode: res.data.areaCode,\r\n\t\t\t\tareaName: res.data.areaName,\r\n\t\t\t\tareaLeve: res.data.areaLeve,\r\n\t\t\t\tchildren: res.data.areaLeve < props.maxLevel ? [] : undefined,\r\n\t\t\t};\r\n\t\t\toptions.value = [rootArea];\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tconsole.error(\"加载初始地区失败:\", error);\r\n\t} finally {\r\n\t\tloading.value = false;\r\n\t}\r\n};\r\n\r\n// 加载下级地区\r\nconst loadChildren = async (item) => {\r\n\tif (item._loading) return;\r\n\titem._loading = true;\r\n\ttry {\r\n\t\tconst res = await getRequest().getForm(`dict/area/next/${item.areaCode}`);\r\n\t\tif (res.data && res.data.length > 0) {\r\n\t\t\tres.data.forEach((it) => {\r\n\t\t\t\t// 根据 maxLevel 判断是否还有下级\r\n\t\t\t\tif (it.areaLeve < props.maxLevel) {\r\n\t\t\t\t\tit.children = [];\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\titem.children = res.data;\r\n\t\t} else {\r\n\t\t\t// 没有下级数据,移除 children 属性使其成为叶子节点\r\n\t\t\tdelete item.children;\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tconsole.error(\"加载下级地区失败:\", error);\r\n\t} finally {\r\n\t\titem._loading = false;\r\n\t}\r\n};\r\n\r\n// 选项变化时加载下级\r\nconst onChange = ({ value, selectedOptions, tabIndex }) => {\r\n\tconst currentItem = selectedOptions[tabIndex];\r\n\tif (currentItem && currentItem.areaLeve < props.maxLevel && Array.isArray(currentItem.children) && currentItem.children.length === 0) {\r\n\t\tloadChildren(currentItem);\r\n\t}\r\n\temit(\"change\", { value, selectedOptions, tabIndex });\r\n};\r\n\r\n// 完成选择\r\nconst onFinish = ({ selectedOptions }) => {\r\n\t// 根据 displayMode 决定显示值\r\n\tif (props.displayMode === \"last\") {\r\n\t\t// 只显示最后一级\r\n\t\tdisplayValue.value = selectedOptions[selectedOptions.length - 1]?.areaName || \"\";\r\n\t} else {\r\n\t\t// 显示完整路径(默认)\r\n\t\tdisplayValue.value = selectedOptions.map((option) => option.areaName).join(props.separator);\r\n\t}\r\n\r\n\t// 存储完整选中数据\r\n\tselectedData.value = selectedOptions.map((option) => ({\r\n\t\tareaCode: option.areaCode,\r\n\t\tareaName: option.areaName,\r\n\t\tareaLeve: option.areaLeve,\r\n\t}));\r\n\r\n\t// 根据 valueType 返回不同格式的值\r\n\tlet emitValue;\r\n\tswitch (props.valueType) {\r\n\t\tcase \"code\":\r\n\t\t\t// 返回最后一级的 areaCode\r\n\t\t\temitValue = selectedOptions[selectedOptions.length - 1]?.areaCode || \"\";\r\n\t\t\tbreak;\r\n\t\tcase \"codes\":\r\n\t\t\t// 返回所有级别的 areaCode 数组\r\n\t\t\temitValue = selectedOptions.map((option) => option.areaCode);\r\n\t\t\tbreak;\r\n\t\tcase \"object\":\r\n\t\t\t// 返回完整对象信息\r\n\t\t\temitValue = {\r\n\t\t\t\tcodes: selectedOptions.map((option) => option.areaCode),\r\n\t\t\t\tnames: selectedOptions.map((option) => option.areaName),\r\n\t\t\t\tfullName: selectedOptions.map((option) => option.areaName).join(props.separator),\r\n\t\t\t\tlastCode: selectedOptions[selectedOptions.length - 1]?.areaCode || \"\",\r\n\t\t\t\tlastLevel: selectedOptions[selectedOptions.length - 1]?.areaLeve,\r\n\t\t\t\toptions: selectedData.value,\r\n\t\t\t};\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\temitValue = selectedOptions[selectedOptions.length - 1]?.areaCode || \"\";\r\n\t}\r\n\r\n\temit(\"update:modelValue\", emitValue);\r\n\temit(\"finish\", { selectedOptions, value: emitValue });\r\n\tshow.value = false;\r\n};\r\n\r\n// 暴露方法供外部调用\r\ndefineExpose({\r\n\t// 获取当前选中的完整数据\r\n\tgetSelectedData: () => selectedData.value,\r\n\t// 获取显示值\r\n\tgetDisplayValue: () => displayValue.value,\r\n\t// 重置选择\r\n\treset: () => {\r\n\t\tdisplayValue.value = \"\";\r\n\t\tcascaderValue.value = \"\";\r\n\t\tselectedData.value = [];\r\n\t\temit(\"update:modelValue\", props.valueType === \"codes\" ? [] : props.valueType === \"object\" ? null : \"\");\r\n\t},\r\n\t// 打开选择器\r\n\topen: () => {\r\n\t\thandleClick();\r\n\t},\r\n\t// 关闭选择器\r\n\tclose: () => {\r\n\t\tshow.value = false;\r\n\t},\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped></style>\r\n","/**\r\n * Area 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Area from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nArea.install = (app, options = {}) => {\n if (options?.request) {\n app.provide('vant-vtk:request', options.request)\n app.config.globalProperties.$vtkRequest = options.request\n }\n app.component(Area.name || 'VtkArea', Area)\r\n}\r\n\r\nexport default Area\r\nexport { Area }\r\n","<template>\r\n\t<van-field v-bind=\"$attrs\">\r\n\t\t<template #input>\r\n\t\t\t<van-radio-group v-model=\"internalValue\" direction=\"horizontal\">\r\n\t\t\t\t<van-radio v-for=\"item in parsedOptions\" :key=\"String(item.value)\" :name=\"String(item.value)\">\r\n\t\t\t\t\t{{ item.text }}\r\n\t\t\t\t</van-radio>\r\n\t\t\t</van-radio-group>\r\n\t\t</template>\r\n\t</van-field>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkRadio\",\r\n});\r\nimport { computed } from \"vue\";\r\n\r\nconst props = defineProps({\r\n\t// 绑定值\r\n\tmodelValue: {\r\n\t\ttype: [String, Number, Object],\r\n\t\tdefault: \"\",\r\n\t},\r\n\t// 选项数据:支持数组 [{value, text}] 或 字符串 '1:选项1/2:选项2'\r\n\toptions: {\r\n\t\ttype: [Array, String],\r\n\t\tdefault: () => [],\r\n\t},\r\n\t// 返回值类型: 'string' (基本类型), 'object' (完整对象)\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"string\",\r\n\t\tvalidator: (val) => [\"string\", \"object\"].includes(val),\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\r\n\r\n// 解析选项\r\nconst parsedOptions = computed(() => {\r\n\tif (Array.isArray(props.options)) {\r\n\t\treturn props.options;\r\n\t}\r\n\tif (typeof props.options === \"string\" && props.options) {\r\n\t\treturn props.options\r\n\t\t\t.split(\"/\")\r\n\t\t\t.filter(Boolean)\r\n\t\t\t.map((item) => {\r\n\t\t\t\tconst [value, text] = item.split(\":\");\r\n\t\t\t\treturn {\r\n\t\t\t\t\ttext: text || value,\r\n\t\t\t\t\tvalue: value,\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t}\r\n\treturn [];\r\n});\r\n\r\n// 使用可写计算属性处理 v-model 绑定\r\nconst internalValue = computed({\r\n\tget: () => {\r\n\t\tconst val = props.modelValue;\r\n\t\tif (val === undefined || val === null) return \"\";\r\n\r\n\t\t// 如果是对象类型,提取其中的 value\r\n\t\tif (props.valueType === \"object\" && val && typeof val === \"object\") {\r\n\t\t\treturn String(val.value ?? \"\");\r\n\t\t}\r\n\t\treturn String(val);\r\n\t},\r\n\tset: (newValue) => {\r\n\t\tlet emitValue = newValue;\r\n\r\n\t\t// 处理原始数据类型逻辑(如果父组件传入的是数字,尝试转回数字)\r\n\t\tconst originalValue = props.valueType === \"object\" ? props.modelValue?.value : props.modelValue;\r\n\t\tif (typeof originalValue === \"number\" && !isNaN(Number(newValue))) {\r\n\t\t\temitValue = Number(newValue);\r\n\t\t}\r\n\r\n\t\tif (props.valueType === \"object\") {\r\n\t\t\t// 找回完整对象\r\n\t\t\temitValue = parsedOptions.value.find((opt) => String(opt.value) === String(newValue)) || null;\r\n\t\t}\r\n\r\n\t\temit(\"update:modelValue\", emitValue);\r\n\t\temit(\"change\", emitValue);\r\n\t},\r\n});\r\n</script>\r\n\r\n<style scoped>\r\n:deep(.van-radio) {\r\n\tmargin-right: 12px;\r\n}\r\n</style>\r\n","/**\r\n * Radio 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Radio from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nRadio.install = (app) => {\r\n app.component(Radio.name || 'VtkRadio', Radio)\r\n}\r\n\r\nexport default Radio\r\nexport { Radio }\r\n","<template>\r\n\t<van-uploader v-model=\"fileList\" v-bind=\"$attrs\" :max-size=\"maxSize\" :accept=\"accept\" :before-read=\"beforeRead\" :after-read=\"afterRead\" @delete=\"onDelete\" />\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkUploader\",\r\n\tinheritAttrs: false,\r\n});\r\nimport { ref, watch, inject, getCurrentInstance } from \"vue\";\r\nimport { showToast, showLoadingToast, closeToast } from \"vant\";\r\n\r\nconst injectedRequest = inject(\"vant-vtk:request\", null);\r\nconst globalProperties = getCurrentInstance()?.appContext.config.globalProperties;\r\nconst globalRequest = globalProperties?.$vtkRequest || globalProperties?.$request;\r\nconst getRequest = () => {\r\n\tconst request = injectedRequest || globalRequest;\r\n\tif (!request) {\r\n\t\tthrow new Error(\"VantVtk request 未配置\");\r\n\t}\r\n\treturn request;\r\n};\r\n\r\nconst props = defineProps({\r\n\t/** 绑定值,支持字符串或数组 */\r\n\tmodelValue: {\r\n\t\ttype: [String, Array],\r\n\t\tdefault: () => [],\r\n\t},\r\n\t/** 返回值类型:'string' 返回逗号分隔的字符串,'array' 返回数组 */\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"array\",\r\n\t\tvalidator: (val) => [\"string\", \"array\"].includes(val),\r\n\t},\r\n\t/** 单个文件最大大小(字节),默认10MB */\r\n\tmaxSize: {\r\n\t\ttype: Number,\r\n\t\tdefault: 10 * 1024 * 1024,\r\n\t},\r\n\t/** 接受的文件类型 */\r\n\taccept: {\r\n\t\ttype: String,\r\n\t\tdefault: \"image/*\",\r\n\t},\r\n\t/** 上传接口地址 */\r\n\tuploadUrl: {\r\n\t\ttype: String,\r\n\t\tdefault: \"/bizp/admin/upload\",\r\n\t},\r\n\t/** 上传文件的字段名 */\r\n\tfieldName: {\r\n\t\ttype: String,\r\n\t\tdefault: \"file\",\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"success\", \"error\"]);\r\n\r\n// 文件列表\r\nconst fileList = ref([]);\r\n\r\n// 解析初始值\r\nconst parseModelValue = (value) => {\r\n\tif (!value) return [];\r\n\r\n\tlet urls = [];\r\n\tif (typeof value === \"string\") {\r\n\t\turls = value.split(\",\").filter((url) => url.trim());\r\n\t} else if (Array.isArray(value)) {\r\n\t\turls = value.filter((url) => url);\r\n\t}\r\n\r\n\treturn urls.map((url) => ({\r\n\t\turl,\r\n\t\tstatus: \"done\",\r\n\t\tmessage: \"\",\r\n\t}));\r\n};\r\n\r\n// 获取已上传的URL列表\r\nconst getUploadedUrls = () => {\r\n\treturn fileList.value.filter((file) => file.status === \"done\" && file.url).map((file) => file.url);\r\n};\r\n\r\n// 格式化输出值\r\nconst formatOutput = (urls) => {\r\n\tif (props.valueType === \"string\") {\r\n\t\treturn urls.join(\",\");\r\n\t}\r\n\treturn urls;\r\n};\r\n\r\n// 触发更新\r\nconst emitValue = () => {\r\n\tconst urls = getUploadedUrls();\r\n\tconst output = formatOutput(urls);\r\n\temit(\"update:modelValue\", output);\r\n\temit(\"change\", output);\r\n};\r\n\r\n// 监听外部值变化\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(newVal) => {\r\n\t\tconst currentUrls = getUploadedUrls().join(\",\");\r\n\t\tconst newUrls = Array.isArray(newVal) ? newVal.join(\",\") : newVal || \"\";\r\n\r\n\t\t// 只有外部值确实改变时才更新\r\n\t\tif (currentUrls !== newUrls) {\r\n\t\t\tfileList.value = parseModelValue(newVal);\r\n\t\t}\r\n\t},\r\n\t{ immediate: true },\r\n);\r\n\r\n// 上传前校验\r\nconst beforeRead = (file) => {\r\n\tconst files = Array.isArray(file) ? file : [file];\r\n\r\n\tfor (const f of files) {\r\n\t\t// 文件大小校验\r\n\t\tif (f.size > props.maxSize) {\r\n\t\t\tconst maxSizeMB = (props.maxSize / 1024 / 1024).toFixed(1);\r\n\t\t\tshowToast(`文件大小不能超过${maxSizeMB}MB`);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\treturn true;\r\n};\r\n\r\n// 上传文件\r\nconst uploadFile = async (file) => {\r\n\tconst formData = new FormData();\r\n\tformData.append(props.fieldName, file.file);\r\n\r\n\ttry {\r\n\t\tconst res = await getRequest().imp(props.uploadUrl, formData);\r\n\r\n\t\tif (res.meta?.success) {\r\n\t\t\t// 根据实际接口返回格式获取URL\r\n\t\t\tconst url = res.data?.url || res.data?.path || res.data;\r\n\t\t\treturn { success: true, url };\r\n\t\t} else {\r\n\t\t\treturn { success: false, message: res.meta?.message || \"上传失败\" };\r\n\t\t}\r\n\t} catch (error) {\r\n\t\treturn { success: false, message: error.message || \"上传失败\" };\r\n\t}\r\n};\r\n\r\n// 文件读取完成后处理\r\nconst afterRead = async (file) => {\r\n\tconst files = Array.isArray(file) ? file : [file];\r\n\r\n\t// 显示上传中提示\r\n\tif (files.length > 1) {\r\n\t\tshowLoadingToast({\r\n\t\t\tmessage: `正在上传 0/${files.length}`,\r\n\t\t\tforbidClick: true,\r\n\t\t\tduration: 0,\r\n\t\t});\r\n\t}\r\n\r\n\tlet successCount = 0;\r\n\tlet failCount = 0;\r\n\r\n\t// 逐个上传\r\n\tfor (let i = 0; i < files.length; i++) {\r\n\t\tconst fileItem = files[i];\r\n\t\tfileItem.status = \"uploading\";\r\n\t\tfileItem.message = \"上传中...\";\r\n\r\n\t\t// 更新进度提示\r\n\t\tif (files.length > 1) {\r\n\t\t\tshowLoadingToast({\r\n\t\t\t\tmessage: `正在上传 ${i + 1}/${files.length}`,\r\n\t\t\t\tforbidClick: true,\r\n\t\t\t\tduration: 0,\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tconst result = await uploadFile(fileItem);\r\n\r\n\t\tif (result.success) {\r\n\t\t\tfileItem.status = \"done\";\r\n\t\t\tfileItem.message = \"\";\r\n\t\t\tfileItem.url = result.url;\r\n\t\t\tsuccessCount++;\r\n\t\t\temit(\"success\", { file: fileItem, url: result.url });\r\n\t\t} else {\r\n\t\t\tfileItem.status = \"failed\";\r\n\t\t\tfileItem.message = result.message;\r\n\t\t\tfailCount++;\r\n\t\t\temit(\"error\", { file: fileItem, message: result.message });\r\n\t\t}\r\n\t}\r\n\r\n\tcloseToast();\r\n\r\n\t// 显示上传结果\r\n\tif (files.length > 1) {\r\n\t\tif (failCount === 0) {\r\n\t\t\tshowToast(`${successCount}个文件上传成功`);\r\n\t\t} else {\r\n\t\t\tshowToast(`${successCount}个成功,${failCount}个失败`);\r\n\t\t}\r\n\t} else if (failCount > 0) {\r\n\t\tshowToast(files[0].message || \"上传失败\");\r\n\t}\r\n\r\n\t// 触发值更新\r\n\temitValue();\r\n};\r\n\r\n// 删除文件\r\nconst onDelete = () => {\r\n\t// 下一个tick再触发,确保fileList已更新\r\n\tsetTimeout(() => {\r\n\t\temitValue();\r\n\t}, 0);\r\n};\r\n\r\n// 暴露方法给父组件\r\ndefineExpose({\r\n\t/** 获取已上传的URL列表 */\r\n\tgetUrls: getUploadedUrls,\r\n\t/** 清空文件列表 */\r\n\tclear: () => {\r\n\t\tfileList.value = [];\r\n\t\temitValue();\r\n\t},\r\n\t/** 获取文件列表 */\r\n\tgetFileList: () => fileList.value,\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n:deep(.van-uploader__preview-image) {\r\n\tborder-radius: 4px;\r\n}\r\n\r\n:deep(.van-uploader__upload) {\r\n\tborder-radius: 4px;\r\n}\r\n</style>\r\n","/**\r\n * Uploader 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Uploader from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nUploader.install = (app, options = {}) => {\n if (options?.request) {\n app.provide('vant-vtk:request', options.request)\n app.config.globalProperties.$vtkRequest = options.request\n }\n app.component(Uploader.name || 'VtkUploader', Uploader)\r\n}\r\n\r\nexport default Uploader\r\nexport { Uploader }\r\n","<template>\r\n\t<van-popup v-model:show=\"showPopup\" position=\"bottom\" :style=\"{ height: '100vh' }\">\r\n\t\t<div class=\"file-preview-container\">\r\n\t\t\t<div class=\"file-header\">\r\n\t\t\t\t<div class=\"file-title\">{{ currentFile?.name || \"文件预览\" }}</div>\r\n\t\t\t\t<van-icon name=\"cross\" size=\"20\" @click=\"handleClose\" />\r\n\t\t\t</div>\r\n\r\n\t\t\t<div class=\"file-content\">\r\n\t\t\t\t<div v-if=\"currentType === 'image'\" class=\"image-preview\">\r\n\t\t\t\t\t<van-image :src=\"currentFile?.url\" fit=\"contain\" class=\"preview-image\" />\r\n\t\t\t\t\t<div class=\"image-footer\">\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentIndex <= 0\" @click=\"prevFile\">上一个</van-button>\r\n\t\t\t\t\t\t<span class=\"file-info\">{{ currentIndex + 1 }} / {{ files.length }}</span>\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\">下一个</van-button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<div v-else-if=\"currentType === 'pdf'\" class=\"pdf-preview\">\r\n\t\t\t\t\t<VuePdfEmbed v-if=\"pdfSource\" :source=\"pdfSource\" :page=\"currentPage\" class=\"pdf-embed-preview\" @rendered=\"handlePdfRendered\" @loaded=\"handlePdfLoaded\" />\r\n\t\t\t\t\t<div v-else class=\"pdf-placeholder\">请选择PDF文件</div>\r\n\t\t\t\t\t<div class=\"pdf-footer\">\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentPage <= 1\" @click=\"currentPage--\">上一页</van-button>\r\n\t\t\t\t\t\t<span class=\"page-info\">第 {{ currentPage }} / {{ totalPages || \"?\" }} 页</span>\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"!pdfSource || currentPage >= totalPages\" @click=\"currentPage++\">下一页</van-button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<div class=\"footer\">\r\n\t\t\t\t\t<van-button :disabled=\"currentIndex <= 0\" @click=\"prevFile\" icon=\"arrow-left\" type=\"primary\" round />\r\n\t\t\t\t\t<van-button :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\" icon=\"arrow\" type=\"primary\" round />\r\n\t\t\t\t\t<!-- <van-button size=\"small\" :disabled=\"currentIndex <= 0\" @click=\"prevFile\">上一个</van-button>\r\n <span class=\"file-info\">{{ currentIndex + 1 }} / {{ files.length }}</span>\r\n <van-button size=\"small\" :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\">下一个</van-button> -->\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</van-popup>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkPreview\",\r\n});\r\nimport { ref, watch, computed } from \"vue\";\r\nimport VuePdfEmbed from \"vue-pdf-embed\";\r\n\r\nconst props = defineProps({\r\n\tmodelValue: {\r\n\t\ttype: Boolean,\r\n\t\tdefault: false,\r\n\t},\r\n\tfiles: {\r\n\t\ttype: Array,\r\n\t\tdefault: () => [],\r\n\t},\r\n\tstartIndex: {\r\n\t\ttype: Number,\r\n\t\tdefault: 0,\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"close\"]);\r\n\r\nconst showPopup = ref(props.modelValue);\r\nconst currentIndex = ref(props.startIndex);\r\nconst currentPage = ref(1);\r\nconst pdfSource = ref(null);\r\nconst totalPages = ref(0);\r\n\r\nconst normalizedFiles = computed(() => {\r\n\treturn props.files.map((file, index) => {\r\n\t\tif (typeof file === \"string\") {\r\n\t\t\tconst isPdf = file.toLowerCase().endsWith(\".pdf\");\r\n\t\t\treturn {\r\n\t\t\t\tname: isPdf ? `文档${index + 1}.pdf` : `图片${index + 1}`,\r\n\t\t\t\turl: file,\r\n\t\t\t\ttype: isPdf ? \"pdf\" : \"image\",\r\n\t\t\t};\r\n\t\t}\r\n\t\treturn file;\r\n\t});\r\n});\r\n\r\nconst currentFile = computed(() => {\r\n\treturn normalizedFiles.value[currentIndex.value] || null;\r\n});\r\n\r\nconst currentType = computed(() => {\r\n\tif (!currentFile.value) return null;\r\n\tconst url = currentFile.value.url || currentFile.value;\r\n\tif (typeof url === \"string\") {\r\n\t\treturn url.toLowerCase().endsWith(\".pdf\") ? \"pdf\" : \"image\";\r\n\t}\r\n\treturn currentFile.value.type || \"image\";\r\n});\r\n\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(val) => {\r\n\t\tshowPopup.value = val;\r\n\t\tif (val && normalizedFiles.value.length > 0) {\r\n\t\t\tcurrentIndex.value = props.startIndex;\r\n\t\t\tupdatePreview();\r\n\t\t}\r\n\t},\r\n);\r\n\r\nwatch(\r\n\t() => props.startIndex,\r\n\t(val) => {\r\n\t\tcurrentIndex.value = val;\r\n\t\tupdatePreview();\r\n\t},\r\n);\r\n\r\nwatch(showPopup, (val) => {\r\n\temit(\"update:modelValue\", val);\r\n\tif (!val) {\r\n\t\thandleClose();\r\n\t}\r\n});\r\n\r\nwatch(currentIndex, () => {\r\n\tcurrentPage.value = 1;\r\n\ttotalPages.value = 0;\r\n\tupdatePreview();\r\n});\r\n\r\nconst updatePreview = () => {\r\n\tconst file = currentFile.value;\r\n\tif (!file) return;\r\n\r\n\tif (currentType.value === \"pdf\") {\r\n\t\tpdfSource.value = file.url || file;\r\n\t} else {\r\n\t\tpdfSource.value = null;\r\n\t}\r\n};\r\n\r\nconst handlePdfLoaded = (pdf) => {\r\n\ttotalPages.value = pdf.numPages || 0;\r\n};\r\n\r\nconst handlePdfRendered = () => {\r\n\tconsole.log(\"PDF rendered successfully\");\r\n};\r\n\r\nconst prevFile = () => {\r\n\tif (currentIndex.value > 0) {\r\n\t\tcurrentIndex.value--;\r\n\t}\r\n};\r\n\r\nconst nextFile = () => {\r\n\tif (currentIndex.value < normalizedFiles.value.length - 1) {\r\n\t\tcurrentIndex.value++;\r\n\t}\r\n};\r\n\r\nconst handleClose = () => {\r\n\tshowPopup.value = false;\r\n\tpdfSource.value = null;\r\n\tcurrentPage.value = 1;\r\n\ttotalPages.value = 0;\r\n\temit(\"close\");\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.file-preview-container {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\theight: 100%;\r\n\tbackground-color: #fff;\r\n\tborder-radius: 8px;\r\n\toverflow: hidden;\r\n}\r\n\r\n.file-header {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: space-between;\r\n\tpadding: 12px 16px;\r\n\tborder-bottom: 1px solid #ebedf0;\r\n\tbackground-color: #f7f8fa;\r\n}\r\n\r\n.file-title {\r\n\tfont-size: 16px;\r\n\tfont-weight: 600;\r\n\tcolor: #323233;\r\n}\r\n\r\n.file-content {\r\n\tflex: 1;\r\n\toverflow: hidden;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n}\r\n\r\n.image-preview {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\toverflow: hidden;\r\n}\r\n\r\n.preview-image {\r\n\tflex: 1;\r\n\twidth: 100%;\r\n\theight: 100%;\r\n}\r\n\r\n.image-footer {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 16px;\r\n\tpadding: 12px 16px;\r\n\tborder-top: 1px solid #ebedf0;\r\n\tbackground-color: #fff;\r\n}\r\n\r\n.file-info {\r\n\tfont-size: 14px;\r\n\tcolor: #646566;\r\n\tmin-width: 80px;\r\n\ttext-align: center;\r\n}\r\n\r\n.pdf-preview {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\toverflow: hidden;\r\n}\r\n\r\n.pdf-embed-preview {\r\n\tflex: 1;\r\n\tmax-width: 100%;\r\n\toverflow-y: auto;\r\n\tpadding: 16px;\r\n\tdisplay: flex;\r\n\tjustify-content: center;\r\n\talign-items: flex-start;\r\n\tbackground-color: #f5f5f5;\r\n\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n.pdf-placeholder {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tcolor: #969799;\r\n\tfont-size: 14px;\r\n}\r\n\r\n.pdf-footer {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 16px;\r\n\tpadding: 12px 16px;\r\n\tborder-top: 1px solid #ebedf0;\r\n\tbackground-color: #fff;\r\n}\r\n\r\n.page-info {\r\n\tfont-size: 14px;\r\n\tcolor: #646566;\r\n\tmin-width: 80px;\r\n\ttext-align: center;\r\n}\r\n.footer {\r\n\tposition: fixed;\r\n\ttop: 40%;\r\n\twidth: 100%;\r\n\t.van-button {\r\n\t}\r\n\t.van-button:nth-child(2) {\r\n\t\tfloat: right;\r\n\t}\r\n}\r\n</style>\r\n","/**\r\n * Preview 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Preview from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nPreview.install = (app) => {\r\n app.component(Preview.name || 'VtkPreview', Preview)\r\n}\r\n\r\nexport default Preview\r\nexport { Preview }\r\n","/**\r\n * Vant-VTK 组件库全量导出入口\r\n * 支持全量引入和按需引入\r\n */\r\nimport Checkbox from '../packages/checkbox/index.js'\r\nimport Area from '../packages/Area/index.js'\r\nimport Radio from '../packages/Radio/index.js'\r\nimport Uploader from '../packages/Uploader/index.js'\r\nimport Preview from '../packages/preview/index.js'\r\n\r\n\r\n\r\n// 所有组件列表\r\nconst components = [\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n]\r\n\r\n// 全量注册方法\r\nconst install = (app, options = {}) => {\n if (options?.request) {\n app.provide('vant-vtk:request', options.request)\n app.config.globalProperties.$vtkRequest = options.request\n }\n\n components.forEach(component => {\r\n if (component.install) {\r\n app.use(component, options)\n } else if (component.name) {\r\n app.component(component.name, component)\r\n }\r\n })\r\n}\r\n\r\n// 默认导出 - 支持 app.use(VantVtk) 全量注册\r\nexport default {\r\n install,\r\n // 也导出所有组件,方便直接访问\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n}\r\n\r\n// 具名导出 - 支持按需引入\r\nexport {\r\n install,\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n}\r\n\r\n// 导出版本号\r\nexport const version = '1.0.0'\r\n"],"names":["props","__props","emit","__emit","parsedOptions","computed","item","value","text","internalValue","val","arr","newValues","emitValue","opt","_openBlock","_createBlock","_component_van_field","$attrs","_createVNode","_component_van_checkbox_group","$event","_createElementBlock","_Fragment","_renderList","_component_van_checkbox","_createTextVNode","_toDisplayString","Checkbox","app","injectedRequest","inject","globalProperties","_a","getCurrentInstance","globalRequest","getRequest","request","show","ref","cascaderValue","options","displayValue","loading","selectedData","fieldNames","watch","handleClick","loadInitialArea","areaCode","res","rootArea","error","loadChildren","it","onChange","selectedOptions","tabIndex","currentItem","onFinish","option","_b","_c","_d","_e","__expose","_mergeProps","_component_van_popup","_component_van_cascader","Area","newValue","_component_van_radio_group","_component_van_radio","Radio","fileList","parseModelValue","urls","url","getUploadedUrls","file","formatOutput","output","newVal","currentUrls","newUrls","beforeRead","files","f","maxSizeMB","showToast","uploadFile","formData","afterRead","showLoadingToast","successCount","failCount","i","fileItem","result","closeToast","onDelete","_component_van_uploader","Uploader","showPopup","currentIndex","currentPage","pdfSource","totalPages","normalizedFiles","index","isPdf","currentFile","currentType","updatePreview","handleClose","handlePdfLoaded","pdf","handlePdfRendered","prevFile","nextFile","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_component_van_icon","_hoisted_4","_hoisted_5","_component_van_image","_hoisted_6","_component_van_button","_cache","_hoisted_7","_hoisted_8","_unref","VuePdfEmbed","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","Preview","components","install","component","version"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- (function(k,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("vant"),require("vue-pdf-embed")):typeof define=="function"&&define.amd?define(["exports","vue","vant","vue-pdf-embed"],e):(k=typeof globalThis<"u"?globalThis:k||self,e(k.VantVtk={},k.Vue,k.vant,k.VuePdfEmbed))})(this,function(k,e,x,E){"use strict";const $=(n,_)=>{const s=n.__vccOpts||n;for(const[p,f]of _)s[p]=f;return s},w=$(Object.assign({name:"VtkCheckbox"},{__name:"index",props:{modelValue:{type:[String,Array,Object],default:()=>[]},options:{type:[Array,String],default:()=>[]},valueType:{type:String,default:"array",validator:n=>["string","array","object"].includes(n)},separator:{type:String,default:","}},emits:["update:modelValue","change"],setup(n,{emit:_}){const s=n,p=_,f=e.computed(()=>Array.isArray(s.options)?s.options:typeof s.options=="string"&&s.options?s.options.split("/").filter(Boolean).map(o=>{const[r,i]=o.split(":");return{text:i||r,value:r}}):[]),c=e.computed({get:()=>{const o=s.modelValue;if(!o)return[];let r=[];return s.valueType==="string"?r=typeof o=="string"?o.split(s.separator).filter(Boolean):[]:s.valueType==="object"?r=Array.isArray(o)?o.map(i=>(i==null?void 0:i.value)??i):[]:r=Array.isArray(o)?o:[],r.map(String)},set:o=>{let r;s.valueType==="string"?r=o.join(s.separator):s.valueType==="object"?r=f.value.filter(i=>o.includes(String(i.value))):r=o.map(i=>isNaN(Number(i))?i:Array.isArray(s.modelValue)&&typeof s.modelValue[0]=="number"?Number(i):i),p("update:modelValue",r),p("change",r)}});return(o,r)=>{const i=e.resolveComponent("van-checkbox"),V=e.resolveComponent("van-checkbox-group"),y=e.resolveComponent("van-field");return e.openBlock(),e.createBlock(y,e.normalizeProps(e.guardReactiveProps(o.$attrs)),{input:e.withCtx(()=>[e.createVNode(V,{modelValue:c.value,"onUpdate:modelValue":r[0]||(r[0]=h=>c.value=h),direction:"horizontal"},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(f.value,h=>(e.openBlock(),e.createBlock(i,{key:String(h.value),name:String(h.value),shape:"square"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(h.text),1)]),_:2},1032,["name"]))),128))]),_:1},8,["modelValue"])]),_:1},16)}}}),[["__scopeId","data-v-eb64e8a9"]]);w.install=n=>{n.component(w.name||"VtkCheckbox",w)};const S=Object.assign({name:"VtkArea"},{__name:"index",props:{modelValue:{type:[String,Object,Array],default:""},defaultAreaCode:{type:String,default:"33"},valueType:{type:String,default:"code",validator:n=>["code","codes","object"].includes(n)},separator:{type:String,default:"/"},title:{type:String,default:"请选择所在地区"},placeholder:{type:String,default:"请选择所在地区"},maxLevel:{type:Number,default:12},displayMode:{type:String,default:"full",validator:n=>["full","last"].includes(n)}},emits:["update:modelValue","change","finish"],setup(n,{expose:_,emit:s}){const p=n,f=s,c=e.ref(!1),o=e.ref(""),r=e.ref([]),i=e.ref(""),V=e.ref(!1),y=e.ref([]),h={text:"areaName",value:"areaCode",children:"children"};e.watch(()=>p.modelValue,t=>{t||(i.value="",o.value="",y.value=[])},{immediate:!0});const b=()=>{c.value=!0,r.value.length===0&&j()},j=async()=>{if(!V.value){V.value=!0;try{const t=p.defaultAreaCode,a=await Request.getForm(`dict/area/show/${t}`);if(a.data){const l={areaCode:a.data.areaCode,areaName:a.data.areaName,areaLeve:a.data.areaLeve,children:a.data.areaLeve<p.maxLevel?[]:void 0};r.value=[l]}}catch(t){console.error("加载初始地区失败:",t)}finally{V.value=!1}}},d=async t=>{if(!t._loading){t._loading=!0;try{const a=await Request.getForm(`dict/area/next/${t.areaCode}`);a.data&&a.data.length>0?(a.data.forEach(l=>{l.areaLeve<p.maxLevel&&(l.children=[])}),t.children=a.data):delete t.children}catch(a){console.error("加载下级地区失败:",a)}finally{t._loading=!1}}},u=({value:t,selectedOptions:a,tabIndex:l})=>{const m=a[l];m&&m.areaLeve<p.maxLevel&&Array.isArray(m.children)&&m.children.length===0&&d(m),f("change",{value:t,selectedOptions:a,tabIndex:l})},g=({selectedOptions:t})=>{var l,m,N,C,L;p.displayMode==="last"?i.value=((l=t[t.length-1])==null?void 0:l.areaName)||"":i.value=t.map(v=>v.areaName).join(p.separator),y.value=t.map(v=>({areaCode:v.areaCode,areaName:v.areaName,areaLeve:v.areaLeve}));let a;switch(p.valueType){case"code":a=((m=t[t.length-1])==null?void 0:m.areaCode)||"";break;case"codes":a=t.map(v=>v.areaCode);break;case"object":a={codes:t.map(v=>v.areaCode),names:t.map(v=>v.areaName),fullName:t.map(v=>v.areaName).join(p.separator),lastCode:((N=t[t.length-1])==null?void 0:N.areaCode)||"",lastLevel:(C=t[t.length-1])==null?void 0:C.areaLeve,options:y.value};break;default:a=((L=t[t.length-1])==null?void 0:L.areaCode)||""}f("update:modelValue",a),f("finish",{selectedOptions:t,value:a}),c.value=!1};return _({getSelectedData:()=>y.value,getDisplayValue:()=>i.value,reset:()=>{i.value="",o.value="",y.value=[],f("update:modelValue",p.valueType==="codes"?[]:p.valueType==="object"?null:"")},open:()=>{b()},close:()=>{c.value=!1}}),(t,a)=>{const l=e.resolveComponent("van-field"),m=e.resolveComponent("van-cascader"),N=e.resolveComponent("van-popup");return e.openBlock(),e.createElementBlock(e.Fragment,null,[e.createVNode(l,e.mergeProps({modelValue:i.value,"onUpdate:modelValue":a[0]||(a[0]=C=>i.value=C),"is-link":"",readonly:""},t.$attrs,{placeholder:n.placeholder,onClick:b}),null,16,["modelValue","placeholder"]),e.createVNode(N,{show:c.value,"onUpdate:show":a[3]||(a[3]=C=>c.value=C),round:"",position:"bottom"},{default:e.withCtx(()=>[e.createVNode(m,{modelValue:o.value,"onUpdate:modelValue":a[1]||(a[1]=C=>o.value=C),title:n.title,options:r.value,"field-names":h,onClose:a[2]||(a[2]=C=>c.value=!1),onFinish:g,onChange:u},null,8,["modelValue","title","options"])]),_:1},8,["show"])],64)}}});S.install=n=>{n.component(S.name||"VtkArea",S)};const A=$(Object.assign({name:"VtkRadio"},{__name:"index",props:{modelValue:{type:[String,Number,Object],default:""},options:{type:[Array,String],default:()=>[]},valueType:{type:String,default:"string",validator:n=>["string","object"].includes(n)}},emits:["update:modelValue","change"],setup(n,{emit:_}){const s=n,p=_,f=e.computed(()=>Array.isArray(s.options)?s.options:typeof s.options=="string"&&s.options?s.options.split("/").filter(Boolean).map(o=>{const[r,i]=o.split(":");return{text:i||r,value:r}}):[]),c=e.computed({get:()=>{const o=s.modelValue;return o==null?"":s.valueType==="object"&&o&&typeof o=="object"?String(o.value??""):String(o)},set:o=>{var V;let r=o;typeof(s.valueType==="object"?(V=s.modelValue)==null?void 0:V.value:s.modelValue)=="number"&&!isNaN(Number(o))&&(r=Number(o)),s.valueType==="object"&&(r=f.value.find(y=>String(y.value)===String(o))||null),p("update:modelValue",r),p("change",r)}});return(o,r)=>{const i=e.resolveComponent("van-radio"),V=e.resolveComponent("van-radio-group"),y=e.resolveComponent("van-field");return e.openBlock(),e.createBlock(y,e.normalizeProps(e.guardReactiveProps(o.$attrs)),{input:e.withCtx(()=>[e.createVNode(V,{modelValue:c.value,"onUpdate:modelValue":r[0]||(r[0]=h=>c.value=h),direction:"horizontal"},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(f.value,h=>(e.openBlock(),e.createBlock(i,{key:String(h.value),name:String(h.value)},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(h.text),1)]),_:2},1032,["name"]))),128))]),_:1},8,["modelValue"])]),_:1},16)}}}),[["__scopeId","data-v-3482e335"]]);A.install=n=>{n.component(A.name||"VtkRadio",A)};const U=Object.assign({name:"VtkUploader",inheritAttrs:!1},{__name:"index",props:{modelValue:{type:[String,Array],default:()=>[]},valueType:{type:String,default:"array",validator:n=>["string","array"].includes(n)},maxSize:{type:Number,default:10*1024*1024},accept:{type:String,default:"image/*"},uploadUrl:{type:String,default:"/bizp/admin/upload"},fieldName:{type:String,default:"file"}},emits:["update:modelValue","change","success","error"],setup(n,{expose:_,emit:s}){const p=n,f=s,c=e.ref([]),o=d=>{if(!d)return[];let u=[];return typeof d=="string"?u=d.split(",").filter(g=>g.trim()):Array.isArray(d)&&(u=d.filter(g=>g)),u.map(g=>({url:g,status:"done",message:""}))},r=()=>c.value.filter(d=>d.status==="done"&&d.url).map(d=>d.url),i=d=>p.valueType==="string"?d.join(","):d,V=()=>{const d=r(),u=i(d);f("update:modelValue",u),f("change",u)};e.watch(()=>p.modelValue,d=>{const u=r().join(","),g=Array.isArray(d)?d.join(","):d||"";u!==g&&(c.value=o(d))},{immediate:!0});const y=d=>{const u=Array.isArray(d)?d:[d];for(const g of u)if(g.size>p.maxSize){const t=(p.maxSize/1024/1024).toFixed(1);return x.showToast(`文件大小不能超过${t}MB`),!1}return!0},h=async d=>{var g,t,a,l;const u=new FormData;u.append(p.fieldName,d.file);try{const m=await Request.imp(p.uploadUrl,u);return(g=m.meta)!=null&&g.success?{success:!0,url:((t=m.data)==null?void 0:t.url)||((a=m.data)==null?void 0:a.path)||m.data}:{success:!1,message:((l=m.meta)==null?void 0:l.message)||"上传失败"}}catch(m){return{success:!1,message:m.message||"上传失败"}}},b=async d=>{const u=Array.isArray(d)?d:[d];u.length>1&&x.showLoadingToast({message:`正在上传 0/${u.length}`,forbidClick:!0,duration:0});let g=0,t=0;for(let a=0;a<u.length;a++){const l=u[a];l.status="uploading",l.message="上传中...",u.length>1&&x.showLoadingToast({message:`正在上传 ${a+1}/${u.length}`,forbidClick:!0,duration:0});const m=await h(l);m.success?(l.status="done",l.message="",l.url=m.url,g++,f("success",{file:l,url:m.url})):(l.status="failed",l.message=m.message,t++,f("error",{file:l,message:m.message}))}x.closeToast(),u.length>1?t===0?x.showToast(`${g}个文件上传成功`):x.showToast(`${g}个成功,${t}个失败`):t>0&&x.showToast(u[0].message||"上传失败"),V()},j=()=>{setTimeout(()=>{V()},0)};return _({getUrls:r,clear:()=>{c.value=[],V()},getFileList:()=>c.value}),(d,u)=>{const g=e.resolveComponent("van-uploader");return e.openBlock(),e.createBlock(g,e.mergeProps({modelValue:c.value,"onUpdate:modelValue":u[0]||(u[0]=t=>c.value=t)},d.$attrs,{"max-size":n.maxSize,accept:n.accept,"before-read":y,"after-read":b,onDelete:j}),null,16,["modelValue","max-size","accept"])}}}),T=$(U,[["__scopeId","data-v-2ccc0da3"]]);T.install=n=>{n.component(T.name||"VtkUploader",T)};const F={class:"file-preview-container"},D={class:"file-header"},R={class:"file-title"},I={class:"file-content"},q={key:0,class:"image-preview"},M={class:"image-footer"},W={class:"file-info"},G={key:1,class:"pdf-preview"},H={key:1,class:"pdf-placeholder"},J={class:"pdf-footer"},K={class:"page-info"},Q={class:"footer"},B=$(Object.assign({name:"VtkPreview"},{__name:"index",props:{modelValue:{type:Boolean,default:!1},files:{type:Array,default:()=>[]},startIndex:{type:Number,default:0}},emits:["update:modelValue","close"],setup(n,{emit:_}){const s=n,p=_,f=e.ref(s.modelValue),c=e.ref(s.startIndex),o=e.ref(1),r=e.ref(null),i=e.ref(0),V=e.computed(()=>s.files.map((a,l)=>{if(typeof a=="string"){const m=a.toLowerCase().endsWith(".pdf");return{name:m?`文档${l+1}.pdf`:`图片${l+1}`,url:a,type:m?"pdf":"image"}}return a})),y=e.computed(()=>V.value[c.value]||null),h=e.computed(()=>{if(!y.value)return null;const a=y.value.url||y.value;return typeof a=="string"?a.toLowerCase().endsWith(".pdf")?"pdf":"image":y.value.type||"image"});e.watch(()=>s.modelValue,a=>{f.value=a,a&&V.value.length>0&&(c.value=s.startIndex,b())}),e.watch(()=>s.startIndex,a=>{c.value=a,b()}),e.watch(f,a=>{p("update:modelValue",a),a||t()}),e.watch(c,()=>{o.value=1,i.value=0,b()});const b=()=>{const a=y.value;a&&(h.value==="pdf"?r.value=a.url||a:r.value=null)},j=a=>{i.value=a.numPages||0},d=()=>{console.log("PDF rendered successfully")},u=()=>{c.value>0&&c.value--},g=()=>{c.value<V.value.length-1&&c.value++},t=()=>{f.value=!1,r.value=null,o.value=1,i.value=0,p("close")};return(a,l)=>{const m=e.resolveComponent("van-icon"),N=e.resolveComponent("van-image"),C=e.resolveComponent("van-button"),L=e.resolveComponent("van-popup");return e.openBlock(),e.createBlock(L,{show:f.value,"onUpdate:show":l[2]||(l[2]=v=>f.value=v),position:"bottom",style:{height:"100vh"}},{default:e.withCtx(()=>{var v,z;return[e.createElementVNode("div",F,[e.createElementVNode("div",D,[e.createElementVNode("div",R,e.toDisplayString(((v=y.value)==null?void 0:v.name)||"文件预览"),1),e.createVNode(m,{name:"cross",size:"20",onClick:t})]),e.createElementVNode("div",I,[h.value==="image"?(e.openBlock(),e.createElementBlock("div",q,[e.createVNode(N,{src:(z=y.value)==null?void 0:z.url,fit:"contain",class:"preview-image"},null,8,["src"]),e.createElementVNode("div",M,[e.createVNode(C,{size:"small",disabled:c.value<=0,onClick:u},{default:e.withCtx(()=>[...l[3]||(l[3]=[e.createTextVNode("上一个",-1)])]),_:1},8,["disabled"]),e.createElementVNode("span",W,e.toDisplayString(c.value+1)+" / "+e.toDisplayString(n.files.length),1),e.createVNode(C,{size:"small",disabled:c.value>=n.files.length-1,onClick:g},{default:e.withCtx(()=>[...l[4]||(l[4]=[e.createTextVNode("下一个",-1)])]),_:1},8,["disabled"])])])):h.value==="pdf"?(e.openBlock(),e.createElementBlock("div",G,[r.value?(e.openBlock(),e.createBlock(e.unref(E),{key:0,source:r.value,page:o.value,class:"pdf-embed-preview",onRendered:d,onLoaded:j},null,8,["source","page"])):(e.openBlock(),e.createElementBlock("div",H,"请选择PDF文件")),e.createElementVNode("div",J,[e.createVNode(C,{size:"small",disabled:o.value<=1,onClick:l[0]||(l[0]=O=>o.value--)},{default:e.withCtx(()=>[...l[5]||(l[5]=[e.createTextVNode("上一页",-1)])]),_:1},8,["disabled"]),e.createElementVNode("span",K,"第 "+e.toDisplayString(o.value)+" / "+e.toDisplayString(i.value||"?")+" 页",1),e.createVNode(C,{size:"small",disabled:!r.value||o.value>=i.value,onClick:l[1]||(l[1]=O=>o.value++)},{default:e.withCtx(()=>[...l[6]||(l[6]=[e.createTextVNode("下一页",-1)])]),_:1},8,["disabled"])])])):e.createCommentVNode("",!0),e.createElementVNode("div",Q,[e.createVNode(C,{disabled:c.value<=0,onClick:u,icon:"arrow-left",type:"primary",round:""},null,8,["disabled"]),e.createVNode(C,{disabled:c.value>=n.files.length-1,onClick:g,icon:"arrow",type:"primary",round:""},null,8,["disabled"])])])])]}),_:1},8,["show"])}}}),[["__scopeId","data-v-1ad2c749"]]);B.install=n=>{n.component(B.name||"VtkPreview",B)};const X=[w,S,A,T,B],P=n=>{X.forEach(_=>{_.install?n.use(_):_.name&&n.component(_.name,_)})},Y={install:P,Checkbox:w,Area:S,Radio:A,Uploader:T,Preview:B},Z="1.0.0";k.Area=S,k.Checkbox=w,k.Preview=B,k.Radio=A,k.Uploader=T,k.default=Y,k.install=P,k.version=Z,Object.defineProperties(k,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
1
+ (function(_,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("vant"),require("vue-pdf-embed")):typeof define=="function"&&define.amd?define(["exports","vue","vant","vue-pdf-embed"],e):(_=typeof globalThis<"u"?globalThis:_||self,e(_.VantVtk={},_.Vue,_.vant,_.VuePdfEmbed))})(this,function(_,e,S,F){"use strict";const E=(o,u)=>{const n=o.__vccOpts||o;for(const[k,m]of u)n[k]=m;return n},T=E(Object.assign({name:"VtkCheckbox"},{__name:"index",props:{modelValue:{type:[String,Array,Object],default:()=>[]},options:{type:[Array,String],default:()=>[]},valueType:{type:String,default:"array",validator:o=>["string","array","object"].includes(o)},separator:{type:String,default:","}},emits:["update:modelValue","change"],setup(o,{emit:u}){const n=o,k=u,m=e.computed(()=>Array.isArray(n.options)?n.options:typeof n.options=="string"&&n.options?n.options.split("/").filter(Boolean).map(r=>{const[l,i]=r.split(":");return{text:i||l,value:l}}):[]),y=e.computed({get:()=>{const r=n.modelValue;if(!r)return[];let l=[];return n.valueType==="string"?l=typeof r=="string"?r.split(n.separator).filter(Boolean):[]:n.valueType==="object"?l=Array.isArray(r)?r.map(i=>(i==null?void 0:i.value)??i):[]:l=Array.isArray(r)?r:[],l.map(String)},set:r=>{let l;n.valueType==="string"?l=r.join(n.separator):n.valueType==="object"?l=m.value.filter(i=>r.includes(String(i.value))):l=r.map(i=>isNaN(Number(i))?i:Array.isArray(n.modelValue)&&typeof n.modelValue[0]=="number"?Number(i):i),k("update:modelValue",l),k("change",l)}});return(r,l)=>{const i=e.resolveComponent("van-checkbox"),g=e.resolveComponent("van-checkbox-group"),V=e.resolveComponent("van-field");return e.openBlock(),e.createBlock(V,e.normalizeProps(e.guardReactiveProps(r.$attrs)),{input:e.withCtx(()=>[e.createVNode(g,{modelValue:y.value,"onUpdate:modelValue":l[0]||(l[0]=h=>y.value=h),direction:"horizontal"},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(m.value,h=>(e.openBlock(),e.createBlock(i,{key:String(h.value),name:String(h.value),shape:"square"},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(h.text),1)]),_:2},1032,["name"]))),128))]),_:1},8,["modelValue"])]),_:1},16)}}}),[["__scopeId","data-v-eb64e8a9"]]);T.install=o=>{o.component(T.name||"VtkCheckbox",T)};const B=Object.assign({name:"VtkArea"},{__name:"index",props:{modelValue:{type:[String,Object,Array],default:""},defaultAreaCode:{type:String,default:"33"},valueType:{type:String,default:"code",validator:o=>["code","codes","object"].includes(o)},separator:{type:String,default:"/"},title:{type:String,default:"请选择所在地区"},placeholder:{type:String,default:"请选择所在地区"},maxLevel:{type:Number,default:12},displayMode:{type:String,default:"full",validator:o=>["full","last"].includes(o)}},emits:["update:modelValue","change","finish"],setup(o,{expose:u,emit:n}){var v;const k=e.inject("vant-vtk:request",null),m=(v=e.getCurrentInstance())==null?void 0:v.appContext.config.globalProperties,y=(m==null?void 0:m.$vtkRequest)||(m==null?void 0:m.$request),r=()=>{const t=k||y;if(!t)throw new Error("VantVtk request 未配置");return t},l=o,i=n,g=e.ref(!1),V=e.ref(""),h=e.ref([]),C=e.ref(""),x=e.ref(!1),N=e.ref([]),P={text:"areaName",value:"areaCode",children:"children"};e.watch(()=>l.modelValue,t=>{t||(C.value="",V.value="",N.value=[])},{immediate:!0});const q=()=>{g.value=!0,h.value.length===0&&R()},R=async()=>{if(!x.value){x.value=!0;try{const t=l.defaultAreaCode,s=await r().getForm(`dict/area/show/${t}`);if(s.data){const c={areaCode:s.data.areaCode,areaName:s.data.areaName,areaLeve:s.data.areaLeve,children:s.data.areaLeve<l.maxLevel?[]:void 0};h.value=[c]}}catch(t){console.error("加载初始地区失败:",t)}finally{x.value=!1}}},p=async t=>{if(!t._loading){t._loading=!0;try{const s=await r().getForm(`dict/area/next/${t.areaCode}`);s.data&&s.data.length>0?(s.data.forEach(c=>{c.areaLeve<l.maxLevel&&(c.children=[])}),t.children=s.data):delete t.children}catch(s){console.error("加载下级地区失败:",s)}finally{t._loading=!1}}},a=({value:t,selectedOptions:s,tabIndex:c})=>{const f=s[c];f&&f.areaLeve<l.maxLevel&&Array.isArray(f.children)&&f.children.length===0&&p(f),i("change",{value:t,selectedOptions:s,tabIndex:c})},d=({selectedOptions:t})=>{var c,f,A,w,U;l.displayMode==="last"?C.value=((c=t[t.length-1])==null?void 0:c.areaName)||"":C.value=t.map(b=>b.areaName).join(l.separator),N.value=t.map(b=>({areaCode:b.areaCode,areaName:b.areaName,areaLeve:b.areaLeve}));let s;switch(l.valueType){case"code":s=((f=t[t.length-1])==null?void 0:f.areaCode)||"";break;case"codes":s=t.map(b=>b.areaCode);break;case"object":s={codes:t.map(b=>b.areaCode),names:t.map(b=>b.areaName),fullName:t.map(b=>b.areaName).join(l.separator),lastCode:((A=t[t.length-1])==null?void 0:A.areaCode)||"",lastLevel:(w=t[t.length-1])==null?void 0:w.areaLeve,options:N.value};break;default:s=((U=t[t.length-1])==null?void 0:U.areaCode)||""}i("update:modelValue",s),i("finish",{selectedOptions:t,value:s}),g.value=!1};return u({getSelectedData:()=>N.value,getDisplayValue:()=>C.value,reset:()=>{C.value="",V.value="",N.value=[],i("update:modelValue",l.valueType==="codes"?[]:l.valueType==="object"?null:"")},open:()=>{q()},close:()=>{g.value=!1}}),(t,s)=>{const c=e.resolveComponent("van-field"),f=e.resolveComponent("van-cascader"),A=e.resolveComponent("van-popup");return e.openBlock(),e.createElementBlock(e.Fragment,null,[e.createVNode(c,e.mergeProps({modelValue:C.value,"onUpdate:modelValue":s[0]||(s[0]=w=>C.value=w),"is-link":"",readonly:""},t.$attrs,{placeholder:o.placeholder,onClick:q}),null,16,["modelValue","placeholder"]),e.createVNode(A,{show:g.value,"onUpdate:show":s[3]||(s[3]=w=>g.value=w),round:"",position:"bottom"},{default:e.withCtx(()=>[e.createVNode(f,{modelValue:V.value,"onUpdate:modelValue":s[1]||(s[1]=w=>V.value=w),title:o.title,options:h.value,"field-names":P,onClose:s[2]||(s[2]=w=>g.value=!1),onFinish:d,onChange:a},null,8,["modelValue","title","options"])]),_:1},8,["show"])],64)}}});B.install=(o,u={})=>{u!=null&&u.request&&(o.provide("vant-vtk:request",u.request),o.config.globalProperties.$vtkRequest=u.request),o.component(B.name||"VtkArea",B)};const j=E(Object.assign({name:"VtkRadio"},{__name:"index",props:{modelValue:{type:[String,Number,Object],default:""},options:{type:[Array,String],default:()=>[]},valueType:{type:String,default:"string",validator:o=>["string","object"].includes(o)}},emits:["update:modelValue","change"],setup(o,{emit:u}){const n=o,k=u,m=e.computed(()=>Array.isArray(n.options)?n.options:typeof n.options=="string"&&n.options?n.options.split("/").filter(Boolean).map(r=>{const[l,i]=r.split(":");return{text:i||l,value:l}}):[]),y=e.computed({get:()=>{const r=n.modelValue;return r==null?"":n.valueType==="object"&&r&&typeof r=="object"?String(r.value??""):String(r)},set:r=>{var g;let l=r;typeof(n.valueType==="object"?(g=n.modelValue)==null?void 0:g.value:n.modelValue)=="number"&&!isNaN(Number(r))&&(l=Number(r)),n.valueType==="object"&&(l=m.value.find(V=>String(V.value)===String(r))||null),k("update:modelValue",l),k("change",l)}});return(r,l)=>{const i=e.resolveComponent("van-radio"),g=e.resolveComponent("van-radio-group"),V=e.resolveComponent("van-field");return e.openBlock(),e.createBlock(V,e.normalizeProps(e.guardReactiveProps(r.$attrs)),{input:e.withCtx(()=>[e.createVNode(g,{modelValue:y.value,"onUpdate:modelValue":l[0]||(l[0]=h=>y.value=h),direction:"horizontal"},{default:e.withCtx(()=>[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(m.value,h=>(e.openBlock(),e.createBlock(i,{key:String(h.value),name:String(h.value)},{default:e.withCtx(()=>[e.createTextVNode(e.toDisplayString(h.text),1)]),_:2},1032,["name"]))),128))]),_:1},8,["modelValue"])]),_:1},16)}}}),[["__scopeId","data-v-3482e335"]]);j.install=o=>{o.component(j.name||"VtkRadio",j)};const D=Object.assign({name:"VtkUploader",inheritAttrs:!1},{__name:"index",props:{modelValue:{type:[String,Array],default:()=>[]},valueType:{type:String,default:"array",validator:o=>["string","array"].includes(o)},maxSize:{type:Number,default:10*1024*1024},accept:{type:String,default:"image/*"},uploadUrl:{type:String,default:"/bizp/admin/upload"},fieldName:{type:String,default:"file"}},emits:["update:modelValue","change","success","error"],setup(o,{expose:u,emit:n}){var p;const k=e.inject("vant-vtk:request",null),m=(p=e.getCurrentInstance())==null?void 0:p.appContext.config.globalProperties,y=(m==null?void 0:m.$vtkRequest)||(m==null?void 0:m.$request),r=()=>{const a=k||y;if(!a)throw new Error("VantVtk request 未配置");return a},l=o,i=n,g=e.ref([]),V=a=>{if(!a)return[];let d=[];return typeof a=="string"?d=a.split(",").filter(v=>v.trim()):Array.isArray(a)&&(d=a.filter(v=>v)),d.map(v=>({url:v,status:"done",message:""}))},h=()=>g.value.filter(a=>a.status==="done"&&a.url).map(a=>a.url),C=a=>l.valueType==="string"?a.join(","):a,x=()=>{const a=h(),d=C(a);i("update:modelValue",d),i("change",d)};e.watch(()=>l.modelValue,a=>{const d=h().join(","),v=Array.isArray(a)?a.join(","):a||"";d!==v&&(g.value=V(a))},{immediate:!0});const N=a=>{const d=Array.isArray(a)?a:[a];for(const v of d)if(v.size>l.maxSize){const t=(l.maxSize/1024/1024).toFixed(1);return S.showToast(`文件大小不能超过${t}MB`),!1}return!0},P=async a=>{var v,t,s,c;const d=new FormData;d.append(l.fieldName,a.file);try{const f=await r().imp(l.uploadUrl,d);return(v=f.meta)!=null&&v.success?{success:!0,url:((t=f.data)==null?void 0:t.url)||((s=f.data)==null?void 0:s.path)||f.data}:{success:!1,message:((c=f.meta)==null?void 0:c.message)||"上传失败"}}catch(f){return{success:!1,message:f.message||"上传失败"}}},q=async a=>{const d=Array.isArray(a)?a:[a];d.length>1&&S.showLoadingToast({message:`正在上传 0/${d.length}`,forbidClick:!0,duration:0});let v=0,t=0;for(let s=0;s<d.length;s++){const c=d[s];c.status="uploading",c.message="上传中...",d.length>1&&S.showLoadingToast({message:`正在上传 ${s+1}/${d.length}`,forbidClick:!0,duration:0});const f=await P(c);f.success?(c.status="done",c.message="",c.url=f.url,v++,i("success",{file:c,url:f.url})):(c.status="failed",c.message=f.message,t++,i("error",{file:c,message:f.message}))}S.closeToast(),d.length>1?t===0?S.showToast(`${v}个文件上传成功`):S.showToast(`${v}个成功,${t}个失败`):t>0&&S.showToast(d[0].message||"上传失败"),x()},R=()=>{setTimeout(()=>{x()},0)};return u({getUrls:h,clear:()=>{g.value=[],x()},getFileList:()=>g.value}),(a,d)=>{const v=e.resolveComponent("van-uploader");return e.openBlock(),e.createBlock(v,e.mergeProps({modelValue:g.value,"onUpdate:modelValue":d[0]||(d[0]=t=>g.value=t)},a.$attrs,{"max-size":o.maxSize,accept:o.accept,"before-read":N,"after-read":q,onDelete:R}),null,16,["modelValue","max-size","accept"])}}}),$=E(D,[["__scopeId","data-v-620ae5d0"]]);$.install=(o,u={})=>{u!=null&&u.request&&(o.provide("vant-vtk:request",u.request),o.config.globalProperties.$vtkRequest=u.request),o.component($.name||"VtkUploader",$)};const I={class:"file-preview-container"},M={class:"file-header"},W={class:"file-title"},G={class:"file-content"},H={key:0,class:"image-preview"},J={class:"image-footer"},K={class:"file-info"},Q={key:1,class:"pdf-preview"},X={key:1,class:"pdf-placeholder"},Y={class:"pdf-footer"},Z={class:"page-info"},O={class:"footer"},L=E(Object.assign({name:"VtkPreview"},{__name:"index",props:{modelValue:{type:Boolean,default:!1},files:{type:Array,default:()=>[]},startIndex:{type:Number,default:0}},emits:["update:modelValue","close"],setup(o,{emit:u}){const n=o,k=u,m=e.ref(n.modelValue),y=e.ref(n.startIndex),r=e.ref(1),l=e.ref(null),i=e.ref(0),g=e.computed(()=>n.files.map((p,a)=>{if(typeof p=="string"){const d=p.toLowerCase().endsWith(".pdf");return{name:d?`文档${a+1}.pdf`:`图片${a+1}`,url:p,type:d?"pdf":"image"}}return p})),V=e.computed(()=>g.value[y.value]||null),h=e.computed(()=>{if(!V.value)return null;const p=V.value.url||V.value;return typeof p=="string"?p.toLowerCase().endsWith(".pdf")?"pdf":"image":V.value.type||"image"});e.watch(()=>n.modelValue,p=>{m.value=p,p&&g.value.length>0&&(y.value=n.startIndex,C())}),e.watch(()=>n.startIndex,p=>{y.value=p,C()}),e.watch(m,p=>{k("update:modelValue",p),p||R()}),e.watch(y,()=>{r.value=1,i.value=0,C()});const C=()=>{const p=V.value;p&&(h.value==="pdf"?l.value=p.url||p:l.value=null)},x=p=>{i.value=p.numPages||0},N=()=>{console.log("PDF rendered successfully")},P=()=>{y.value>0&&y.value--},q=()=>{y.value<g.value.length-1&&y.value++},R=()=>{m.value=!1,l.value=null,r.value=1,i.value=0,k("close")};return(p,a)=>{const d=e.resolveComponent("van-icon"),v=e.resolveComponent("van-image"),t=e.resolveComponent("van-button"),s=e.resolveComponent("van-popup");return e.openBlock(),e.createBlock(s,{show:m.value,"onUpdate:show":a[2]||(a[2]=c=>m.value=c),position:"bottom",style:{height:"100vh"}},{default:e.withCtx(()=>{var c,f;return[e.createElementVNode("div",I,[e.createElementVNode("div",M,[e.createElementVNode("div",W,e.toDisplayString(((c=V.value)==null?void 0:c.name)||"文件预览"),1),e.createVNode(d,{name:"cross",size:"20",onClick:R})]),e.createElementVNode("div",G,[h.value==="image"?(e.openBlock(),e.createElementBlock("div",H,[e.createVNode(v,{src:(f=V.value)==null?void 0:f.url,fit:"contain",class:"preview-image"},null,8,["src"]),e.createElementVNode("div",J,[e.createVNode(t,{size:"small",disabled:y.value<=0,onClick:P},{default:e.withCtx(()=>[...a[3]||(a[3]=[e.createTextVNode("上一个",-1)])]),_:1},8,["disabled"]),e.createElementVNode("span",K,e.toDisplayString(y.value+1)+" / "+e.toDisplayString(o.files.length),1),e.createVNode(t,{size:"small",disabled:y.value>=o.files.length-1,onClick:q},{default:e.withCtx(()=>[...a[4]||(a[4]=[e.createTextVNode("下一个",-1)])]),_:1},8,["disabled"])])])):h.value==="pdf"?(e.openBlock(),e.createElementBlock("div",Q,[l.value?(e.openBlock(),e.createBlock(e.unref(F),{key:0,source:l.value,page:r.value,class:"pdf-embed-preview",onRendered:N,onLoaded:x},null,8,["source","page"])):(e.openBlock(),e.createElementBlock("div",X,"请选择PDF文件")),e.createElementVNode("div",Y,[e.createVNode(t,{size:"small",disabled:r.value<=1,onClick:a[0]||(a[0]=A=>r.value--)},{default:e.withCtx(()=>[...a[5]||(a[5]=[e.createTextVNode("上一页",-1)])]),_:1},8,["disabled"]),e.createElementVNode("span",Z,"第 "+e.toDisplayString(r.value)+" / "+e.toDisplayString(i.value||"?")+" 页",1),e.createVNode(t,{size:"small",disabled:!l.value||r.value>=i.value,onClick:a[1]||(a[1]=A=>r.value++)},{default:e.withCtx(()=>[...a[6]||(a[6]=[e.createTextVNode("下一页",-1)])]),_:1},8,["disabled"])])])):e.createCommentVNode("",!0),e.createElementVNode("div",O,[e.createVNode(t,{disabled:y.value<=0,onClick:P,icon:"arrow-left",type:"primary",round:""},null,8,["disabled"]),e.createVNode(t,{disabled:y.value>=o.files.length-1,onClick:q,icon:"arrow",type:"primary",round:""},null,8,["disabled"])])])])]}),_:1},8,["show"])}}}),[["__scopeId","data-v-1ad2c749"]]);L.install=o=>{o.component(L.name||"VtkPreview",L)};const ee=[T,B,j,$,L],z=(o,u={})=>{u!=null&&u.request&&(o.provide("vant-vtk:request",u.request),o.config.globalProperties.$vtkRequest=u.request),ee.forEach(n=>{n.install?o.use(n,u):n.name&&o.component(n.name,n)})},te={install:z,Checkbox:T,Area:B,Radio:j,Uploader:$,Preview:L},ae="1.0.0";_.Area=B,_.Checkbox=T,_.Preview=L,_.Radio=j,_.Uploader=$,_.default=te,_.install=z,_.version=ae,Object.defineProperties(_,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
2
2
  //# sourceMappingURL=vant-vtk.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vant-vtk.umd.js","sources":["../packages/checkbox/index.vue","../packages/checkbox/index.js","../packages/Area/index.vue","../packages/Area/index.js","../packages/Radio/index.vue","../packages/Radio/index.js","../packages/Uploader/index.vue","../packages/Uploader/index.js","../packages/preview/index.vue","../packages/preview/index.js","../src/index.js"],"sourcesContent":["<template>\r\n <van-field v-bind=\"$attrs\">\r\n <template #input>\r\n <van-checkbox-group v-model=\"internalValue\" direction=\"horizontal\">\r\n <van-checkbox v-for=\"item in parsedOptions\" :key=\"String(item.value)\" :name=\"String(item.value)\" shape=\"square\">\r\n {{ item.text }}\r\n </van-checkbox>\r\n </van-checkbox-group>\r\n </template>\r\n </van-field>\r\n</template>\r\n\r\n<script setup>\r\n import { computed } from 'vue'\r\n\r\n defineOptions({\r\n name: 'VtkCheckbox'\r\n })\r\n\r\n const props = defineProps({\r\n // 绑定值\r\n modelValue: {\r\n type: [String, Array, Object],\r\n default: () => [],\r\n },\r\n // 选项数据:支持数组 [{value, text}] 或 字符串 '1:选项1/2:选项2'\r\n options: {\r\n type: [Array, String],\r\n default: () => [],\r\n },\r\n // 返回值类型: 'string' (逗号分隔), 'array' (值数组), 'object' (对象数组)\r\n valueType: {\r\n type: String,\r\n default: 'array',\r\n validator: (val) => ['string', 'array', 'object'].includes(val),\r\n },\r\n // 当 valueType 为 string 时的分隔符\r\n separator: {\r\n type: String,\r\n default: ',',\r\n },\r\n })\r\n\r\n const emit = defineEmits(['update:modelValue', 'change'])\r\n\r\n // 解析选项\r\n const parsedOptions = computed(() => {\r\n if (Array.isArray(props.options)) {\r\n return props.options\r\n }\r\n if (typeof props.options === 'string' && props.options) {\r\n return props.options\r\n .split('/')\r\n .filter(Boolean)\r\n .map((item) => {\r\n const [value, text] = item.split(':')\r\n return {\r\n text: text || value,\r\n value: value,\r\n }\r\n })\r\n }\r\n return []\r\n })\r\n\r\n // 使用可写计算属性处理 v-model 绑定\r\n const internalValue = computed({\r\n get: () => {\r\n const val = props.modelValue\r\n if (!val) return []\r\n\r\n let arr = []\r\n if (props.valueType === 'string') {\r\n arr = typeof val === 'string' ? val.split(props.separator).filter(Boolean) : []\r\n } else if (props.valueType === 'object') {\r\n arr = Array.isArray(val) ? val.map((item) => item?.value ?? item) : []\r\n } else {\r\n arr = Array.isArray(val) ? val : []\r\n }\r\n // 统一转为字符串,确保与 van-checkbox 的 name 匹配\r\n return arr.map(String)\r\n },\r\n set: (newValues) => {\r\n let emitValue\r\n if (props.valueType === 'string') {\r\n emitValue = newValues.join(props.separator)\r\n } else if (props.valueType === 'object') {\r\n // 从解析后的选项中过滤出完整的对象\r\n emitValue = parsedOptions.value.filter((opt) => newValues.includes(String(opt.value)))\r\n } else {\r\n // 如果原始数据是数字,则尝试转回数字,否则保持字符串\r\n emitValue = newValues.map((val) => {\r\n return isNaN(Number(val)) ? val : Array.isArray(props.modelValue) && typeof props.modelValue[0] === 'number' ? Number(val) : val\r\n })\r\n }\r\n\r\n emit('update:modelValue', emitValue)\r\n emit('change', emitValue)\r\n },\r\n })\r\n</script>\r\n\r\n<style scoped>\r\n :deep(.van-checkbox) {\r\n margin-bottom: 8px;\r\n margin-right: 12px;\r\n }\r\n</style>\r\n","/**\r\n * Checkbox 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Checkbox from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nCheckbox.install = (app) => {\r\n app.component(Checkbox.name || 'VtkCheckbox', Checkbox)\r\n}\r\n\r\nexport default Checkbox\r\nexport { Checkbox }\r\n","<template>\r\n\t<van-field v-model=\"displayValue\" is-link readonly v-bind=\"$attrs\" :placeholder=\"placeholder\" @click=\"handleClick\" />\r\n\t<van-popup v-model:show=\"show\" round position=\"bottom\">\r\n\t\t<van-cascader v-model=\"cascaderValue\" :title=\"title\" :options=\"options\" :field-names=\"fieldNames\" @close=\"show = false\" @finish=\"onFinish\" @change=\"onChange\" />\r\n\t</van-popup>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkArea\",\r\n});\r\nimport { ref, watch } from \"vue\";\r\n// import Request from \"@/utils/request\";\r\n\r\nconst props = defineProps({\r\n\t// 绑定值,根据 valueType 返回不同类型\r\n\tmodelValue: {\r\n\t\ttype: [String, Object, Array],\r\n\t\tdefault: \"\",\r\n\t},\r\n\t// 默认地区编码,用于初始化加载\r\n\tdefaultAreaCode: {\r\n\t\ttype: String,\r\n\t\tdefault: \"33\",\r\n\t},\r\n\t// 返回值类型: 'code' 返回最后一级areaCode, 'codes' 返回所有级别areaCode数组, 'object' 返回完整对象信息\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"code\",\r\n\t\tvalidator: (val) => [\"code\", \"codes\", \"object\"].includes(val),\r\n\t},\r\n\t// 显示分隔符\r\n\tseparator: {\r\n\t\ttype: String,\r\n\t\tdefault: \"/\",\r\n\t},\r\n\t// 弹窗标题\r\n\ttitle: {\r\n\t\ttype: String,\r\n\t\tdefault: \"请选择所在地区\",\r\n\t},\r\n\t// 占位文本\r\n\tplaceholder: {\r\n\t\ttype: String,\r\n\t\tdefault: \"请选择所在地区\",\r\n\t},\r\n\t// 最大层级限制,达到该层级后不再加载下级\r\n\tmaxLevel: {\r\n\t\ttype: Number,\r\n\t\tdefault: 12,\r\n\t},\r\n\t// 显示模式: 'full' 显示完整路径, 'last' 只显示最后一级\r\n\tdisplayMode: {\r\n\t\ttype: String,\r\n\t\tdefault: \"full\",\r\n\t\tvalidator: (val) => [\"full\", \"last\"].includes(val),\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"finish\"]);\r\n\r\nconst show = ref(false); //弹窗显示隐藏\r\nconst cascaderValue = ref(\"\"); //级联选择器绑定值\r\nconst options = ref([]); //级联选择器选项\r\nconst displayValue = ref(\"\"); //显示值\r\nconst loading = ref(false); //加载状态\r\n// 存储完整的选中信息\r\nconst selectedData = ref([]);\r\n\r\nconst fieldNames = {\r\n\ttext: \"areaName\",\r\n\tvalue: \"areaCode\",\r\n\tchildren: \"children\",\r\n};\r\n\r\n// 监听 modelValue 变化,用于回显\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(val) => {\r\n\t\tif (!val) {\r\n\t\t\tdisplayValue.value = \"\";\r\n\t\t\tcascaderValue.value = \"\";\r\n\t\t\tselectedData.value = [];\r\n\t\t}\r\n\t},\r\n\t{ immediate: true },\r\n);\r\n\r\nconst handleClick = () => {\r\n\tshow.value = true;\r\n\tif (options.value.length === 0) {\r\n\t\tloadInitialArea();\r\n\t}\r\n};\r\n\r\n// 加载初始地区\r\nconst loadInitialArea = async () => {\r\n\tif (loading.value) return;\r\n\tloading.value = true;\r\n\ttry {\r\n\t\tconst areaCode = props.defaultAreaCode;\r\n\t\tconst res = await Request.getForm(`dict/area/show/${areaCode}`);\r\n\t\tif (res.data) {\r\n\t\t\tconst rootArea = {\r\n\t\t\t\tareaCode: res.data.areaCode,\r\n\t\t\t\tareaName: res.data.areaName,\r\n\t\t\t\tareaLeve: res.data.areaLeve,\r\n\t\t\t\tchildren: res.data.areaLeve < props.maxLevel ? [] : undefined,\r\n\t\t\t};\r\n\t\t\toptions.value = [rootArea];\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tconsole.error(\"加载初始地区失败:\", error);\r\n\t} finally {\r\n\t\tloading.value = false;\r\n\t}\r\n};\r\n\r\n// 加载下级地区\r\nconst loadChildren = async (item) => {\r\n\tif (item._loading) return;\r\n\titem._loading = true;\r\n\ttry {\r\n\t\tconst res = await Request.getForm(`dict/area/next/${item.areaCode}`);\r\n\t\tif (res.data && res.data.length > 0) {\r\n\t\t\tres.data.forEach((it) => {\r\n\t\t\t\t// 根据 maxLevel 判断是否还有下级\r\n\t\t\t\tif (it.areaLeve < props.maxLevel) {\r\n\t\t\t\t\tit.children = [];\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\titem.children = res.data;\r\n\t\t} else {\r\n\t\t\t// 没有下级数据,移除 children 属性使其成为叶子节点\r\n\t\t\tdelete item.children;\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tconsole.error(\"加载下级地区失败:\", error);\r\n\t} finally {\r\n\t\titem._loading = false;\r\n\t}\r\n};\r\n\r\n// 选项变化时加载下级\r\nconst onChange = ({ value, selectedOptions, tabIndex }) => {\r\n\tconst currentItem = selectedOptions[tabIndex];\r\n\tif (currentItem && currentItem.areaLeve < props.maxLevel && Array.isArray(currentItem.children) && currentItem.children.length === 0) {\r\n\t\tloadChildren(currentItem);\r\n\t}\r\n\temit(\"change\", { value, selectedOptions, tabIndex });\r\n};\r\n\r\n// 完成选择\r\nconst onFinish = ({ selectedOptions }) => {\r\n\t// 根据 displayMode 决定显示值\r\n\tif (props.displayMode === \"last\") {\r\n\t\t// 只显示最后一级\r\n\t\tdisplayValue.value = selectedOptions[selectedOptions.length - 1]?.areaName || \"\";\r\n\t} else {\r\n\t\t// 显示完整路径(默认)\r\n\t\tdisplayValue.value = selectedOptions.map((option) => option.areaName).join(props.separator);\r\n\t}\r\n\r\n\t// 存储完整选中数据\r\n\tselectedData.value = selectedOptions.map((option) => ({\r\n\t\tareaCode: option.areaCode,\r\n\t\tareaName: option.areaName,\r\n\t\tareaLeve: option.areaLeve,\r\n\t}));\r\n\r\n\t// 根据 valueType 返回不同格式的值\r\n\tlet emitValue;\r\n\tswitch (props.valueType) {\r\n\t\tcase \"code\":\r\n\t\t\t// 返回最后一级的 areaCode\r\n\t\t\temitValue = selectedOptions[selectedOptions.length - 1]?.areaCode || \"\";\r\n\t\t\tbreak;\r\n\t\tcase \"codes\":\r\n\t\t\t// 返回所有级别的 areaCode 数组\r\n\t\t\temitValue = selectedOptions.map((option) => option.areaCode);\r\n\t\t\tbreak;\r\n\t\tcase \"object\":\r\n\t\t\t// 返回完整对象信息\r\n\t\t\temitValue = {\r\n\t\t\t\tcodes: selectedOptions.map((option) => option.areaCode),\r\n\t\t\t\tnames: selectedOptions.map((option) => option.areaName),\r\n\t\t\t\tfullName: selectedOptions.map((option) => option.areaName).join(props.separator),\r\n\t\t\t\tlastCode: selectedOptions[selectedOptions.length - 1]?.areaCode || \"\",\r\n\t\t\t\tlastLevel: selectedOptions[selectedOptions.length - 1]?.areaLeve,\r\n\t\t\t\toptions: selectedData.value,\r\n\t\t\t};\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\temitValue = selectedOptions[selectedOptions.length - 1]?.areaCode || \"\";\r\n\t}\r\n\r\n\temit(\"update:modelValue\", emitValue);\r\n\temit(\"finish\", { selectedOptions, value: emitValue });\r\n\tshow.value = false;\r\n};\r\n\r\n// 暴露方法供外部调用\r\ndefineExpose({\r\n\t// 获取当前选中的完整数据\r\n\tgetSelectedData: () => selectedData.value,\r\n\t// 获取显示值\r\n\tgetDisplayValue: () => displayValue.value,\r\n\t// 重置选择\r\n\treset: () => {\r\n\t\tdisplayValue.value = \"\";\r\n\t\tcascaderValue.value = \"\";\r\n\t\tselectedData.value = [];\r\n\t\temit(\"update:modelValue\", props.valueType === \"codes\" ? [] : props.valueType === \"object\" ? null : \"\");\r\n\t},\r\n\t// 打开选择器\r\n\topen: () => {\r\n\t\thandleClick();\r\n\t},\r\n\t// 关闭选择器\r\n\tclose: () => {\r\n\t\tshow.value = false;\r\n\t},\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped></style>\r\n","/**\r\n * Area 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Area from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nArea.install = (app) => {\r\n app.component(Area.name || 'VtkArea', Area)\r\n}\r\n\r\nexport default Area\r\nexport { Area }\r\n","<template>\r\n\t<van-field v-bind=\"$attrs\">\r\n\t\t<template #input>\r\n\t\t\t<van-radio-group v-model=\"internalValue\" direction=\"horizontal\">\r\n\t\t\t\t<van-radio v-for=\"item in parsedOptions\" :key=\"String(item.value)\" :name=\"String(item.value)\">\r\n\t\t\t\t\t{{ item.text }}\r\n\t\t\t\t</van-radio>\r\n\t\t\t</van-radio-group>\r\n\t\t</template>\r\n\t</van-field>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkRadio\",\r\n});\r\nimport { computed } from \"vue\";\r\n\r\nconst props = defineProps({\r\n\t// 绑定值\r\n\tmodelValue: {\r\n\t\ttype: [String, Number, Object],\r\n\t\tdefault: \"\",\r\n\t},\r\n\t// 选项数据:支持数组 [{value, text}] 或 字符串 '1:选项1/2:选项2'\r\n\toptions: {\r\n\t\ttype: [Array, String],\r\n\t\tdefault: () => [],\r\n\t},\r\n\t// 返回值类型: 'string' (基本类型), 'object' (完整对象)\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"string\",\r\n\t\tvalidator: (val) => [\"string\", \"object\"].includes(val),\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\r\n\r\n// 解析选项\r\nconst parsedOptions = computed(() => {\r\n\tif (Array.isArray(props.options)) {\r\n\t\treturn props.options;\r\n\t}\r\n\tif (typeof props.options === \"string\" && props.options) {\r\n\t\treturn props.options\r\n\t\t\t.split(\"/\")\r\n\t\t\t.filter(Boolean)\r\n\t\t\t.map((item) => {\r\n\t\t\t\tconst [value, text] = item.split(\":\");\r\n\t\t\t\treturn {\r\n\t\t\t\t\ttext: text || value,\r\n\t\t\t\t\tvalue: value,\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t}\r\n\treturn [];\r\n});\r\n\r\n// 使用可写计算属性处理 v-model 绑定\r\nconst internalValue = computed({\r\n\tget: () => {\r\n\t\tconst val = props.modelValue;\r\n\t\tif (val === undefined || val === null) return \"\";\r\n\r\n\t\t// 如果是对象类型,提取其中的 value\r\n\t\tif (props.valueType === \"object\" && val && typeof val === \"object\") {\r\n\t\t\treturn String(val.value ?? \"\");\r\n\t\t}\r\n\t\treturn String(val);\r\n\t},\r\n\tset: (newValue) => {\r\n\t\tlet emitValue = newValue;\r\n\r\n\t\t// 处理原始数据类型逻辑(如果父组件传入的是数字,尝试转回数字)\r\n\t\tconst originalValue = props.valueType === \"object\" ? props.modelValue?.value : props.modelValue;\r\n\t\tif (typeof originalValue === \"number\" && !isNaN(Number(newValue))) {\r\n\t\t\temitValue = Number(newValue);\r\n\t\t}\r\n\r\n\t\tif (props.valueType === \"object\") {\r\n\t\t\t// 找回完整对象\r\n\t\t\temitValue = parsedOptions.value.find((opt) => String(opt.value) === String(newValue)) || null;\r\n\t\t}\r\n\r\n\t\temit(\"update:modelValue\", emitValue);\r\n\t\temit(\"change\", emitValue);\r\n\t},\r\n});\r\n</script>\r\n\r\n<style scoped>\r\n:deep(.van-radio) {\r\n\tmargin-right: 12px;\r\n}\r\n</style>\r\n","/**\r\n * Radio 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Radio from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nRadio.install = (app) => {\r\n app.component(Radio.name || 'VtkRadio', Radio)\r\n}\r\n\r\nexport default Radio\r\nexport { Radio }\r\n","<template>\r\n\t<van-uploader v-model=\"fileList\" v-bind=\"$attrs\" :max-size=\"maxSize\" :accept=\"accept\" :before-read=\"beforeRead\" :after-read=\"afterRead\" @delete=\"onDelete\" />\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkUploader\",\r\n\tinheritAttrs: false,\r\n});\r\nimport { ref, watch } from \"vue\";\r\nimport { showToast, showLoadingToast, closeToast } from \"vant\";\r\n\r\nconst props = defineProps({\r\n\t/** 绑定值,支持字符串或数组 */\r\n\tmodelValue: {\r\n\t\ttype: [String, Array],\r\n\t\tdefault: () => [],\r\n\t},\r\n\t/** 返回值类型:'string' 返回逗号分隔的字符串,'array' 返回数组 */\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"array\",\r\n\t\tvalidator: (val) => [\"string\", \"array\"].includes(val),\r\n\t},\r\n\t/** 单个文件最大大小(字节),默认10MB */\r\n\tmaxSize: {\r\n\t\ttype: Number,\r\n\t\tdefault: 10 * 1024 * 1024,\r\n\t},\r\n\t/** 接受的文件类型 */\r\n\taccept: {\r\n\t\ttype: String,\r\n\t\tdefault: \"image/*\",\r\n\t},\r\n\t/** 上传接口地址 */\r\n\tuploadUrl: {\r\n\t\ttype: String,\r\n\t\tdefault: \"/bizp/admin/upload\",\r\n\t},\r\n\t/** 上传文件的字段名 */\r\n\tfieldName: {\r\n\t\ttype: String,\r\n\t\tdefault: \"file\",\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"success\", \"error\"]);\r\n\r\n// 文件列表\r\nconst fileList = ref([]);\r\n\r\n// 解析初始值\r\nconst parseModelValue = (value) => {\r\n\tif (!value) return [];\r\n\r\n\tlet urls = [];\r\n\tif (typeof value === \"string\") {\r\n\t\turls = value.split(\",\").filter((url) => url.trim());\r\n\t} else if (Array.isArray(value)) {\r\n\t\turls = value.filter((url) => url);\r\n\t}\r\n\r\n\treturn urls.map((url) => ({\r\n\t\turl,\r\n\t\tstatus: \"done\",\r\n\t\tmessage: \"\",\r\n\t}));\r\n};\r\n\r\n// 获取已上传的URL列表\r\nconst getUploadedUrls = () => {\r\n\treturn fileList.value.filter((file) => file.status === \"done\" && file.url).map((file) => file.url);\r\n};\r\n\r\n// 格式化输出值\r\nconst formatOutput = (urls) => {\r\n\tif (props.valueType === \"string\") {\r\n\t\treturn urls.join(\",\");\r\n\t}\r\n\treturn urls;\r\n};\r\n\r\n// 触发更新\r\nconst emitValue = () => {\r\n\tconst urls = getUploadedUrls();\r\n\tconst output = formatOutput(urls);\r\n\temit(\"update:modelValue\", output);\r\n\temit(\"change\", output);\r\n};\r\n\r\n// 监听外部值变化\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(newVal) => {\r\n\t\tconst currentUrls = getUploadedUrls().join(\",\");\r\n\t\tconst newUrls = Array.isArray(newVal) ? newVal.join(\",\") : newVal || \"\";\r\n\r\n\t\t// 只有外部值确实改变时才更新\r\n\t\tif (currentUrls !== newUrls) {\r\n\t\t\tfileList.value = parseModelValue(newVal);\r\n\t\t}\r\n\t},\r\n\t{ immediate: true },\r\n);\r\n\r\n// 上传前校验\r\nconst beforeRead = (file) => {\r\n\tconst files = Array.isArray(file) ? file : [file];\r\n\r\n\tfor (const f of files) {\r\n\t\t// 文件大小校验\r\n\t\tif (f.size > props.maxSize) {\r\n\t\t\tconst maxSizeMB = (props.maxSize / 1024 / 1024).toFixed(1);\r\n\t\t\tshowToast(`文件大小不能超过${maxSizeMB}MB`);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\treturn true;\r\n};\r\n\r\n// 上传文件\r\nconst uploadFile = async (file) => {\r\n\tconst formData = new FormData();\r\n\tformData.append(props.fieldName, file.file);\r\n\r\n\ttry {\r\n\t\tconst res = await Request.imp(props.uploadUrl, formData);\r\n\r\n\t\tif (res.meta?.success) {\r\n\t\t\t// 根据实际接口返回格式获取URL\r\n\t\t\tconst url = res.data?.url || res.data?.path || res.data;\r\n\t\t\treturn { success: true, url };\r\n\t\t} else {\r\n\t\t\treturn { success: false, message: res.meta?.message || \"上传失败\" };\r\n\t\t}\r\n\t} catch (error) {\r\n\t\treturn { success: false, message: error.message || \"上传失败\" };\r\n\t}\r\n};\r\n\r\n// 文件读取完成后处理\r\nconst afterRead = async (file) => {\r\n\tconst files = Array.isArray(file) ? file : [file];\r\n\r\n\t// 显示上传中提示\r\n\tif (files.length > 1) {\r\n\t\tshowLoadingToast({\r\n\t\t\tmessage: `正在上传 0/${files.length}`,\r\n\t\t\tforbidClick: true,\r\n\t\t\tduration: 0,\r\n\t\t});\r\n\t}\r\n\r\n\tlet successCount = 0;\r\n\tlet failCount = 0;\r\n\r\n\t// 逐个上传\r\n\tfor (let i = 0; i < files.length; i++) {\r\n\t\tconst fileItem = files[i];\r\n\t\tfileItem.status = \"uploading\";\r\n\t\tfileItem.message = \"上传中...\";\r\n\r\n\t\t// 更新进度提示\r\n\t\tif (files.length > 1) {\r\n\t\t\tshowLoadingToast({\r\n\t\t\t\tmessage: `正在上传 ${i + 1}/${files.length}`,\r\n\t\t\t\tforbidClick: true,\r\n\t\t\t\tduration: 0,\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tconst result = await uploadFile(fileItem);\r\n\r\n\t\tif (result.success) {\r\n\t\t\tfileItem.status = \"done\";\r\n\t\t\tfileItem.message = \"\";\r\n\t\t\tfileItem.url = result.url;\r\n\t\t\tsuccessCount++;\r\n\t\t\temit(\"success\", { file: fileItem, url: result.url });\r\n\t\t} else {\r\n\t\t\tfileItem.status = \"failed\";\r\n\t\t\tfileItem.message = result.message;\r\n\t\t\tfailCount++;\r\n\t\t\temit(\"error\", { file: fileItem, message: result.message });\r\n\t\t}\r\n\t}\r\n\r\n\tcloseToast();\r\n\r\n\t// 显示上传结果\r\n\tif (files.length > 1) {\r\n\t\tif (failCount === 0) {\r\n\t\t\tshowToast(`${successCount}个文件上传成功`);\r\n\t\t} else {\r\n\t\t\tshowToast(`${successCount}个成功,${failCount}个失败`);\r\n\t\t}\r\n\t} else if (failCount > 0) {\r\n\t\tshowToast(files[0].message || \"上传失败\");\r\n\t}\r\n\r\n\t// 触发值更新\r\n\temitValue();\r\n};\r\n\r\n// 删除文件\r\nconst onDelete = () => {\r\n\t// 下一个tick再触发,确保fileList已更新\r\n\tsetTimeout(() => {\r\n\t\temitValue();\r\n\t}, 0);\r\n};\r\n\r\n// 暴露方法给父组件\r\ndefineExpose({\r\n\t/** 获取已上传的URL列表 */\r\n\tgetUrls: getUploadedUrls,\r\n\t/** 清空文件列表 */\r\n\tclear: () => {\r\n\t\tfileList.value = [];\r\n\t\temitValue();\r\n\t},\r\n\t/** 获取文件列表 */\r\n\tgetFileList: () => fileList.value,\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n:deep(.van-uploader__preview-image) {\r\n\tborder-radius: 4px;\r\n}\r\n\r\n:deep(.van-uploader__upload) {\r\n\tborder-radius: 4px;\r\n}\r\n</style>\r\n","/**\r\n * Uploader 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Uploader from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nUploader.install = (app) => {\r\n app.component(Uploader.name || 'VtkUploader', Uploader)\r\n}\r\n\r\nexport default Uploader\r\nexport { Uploader }\r\n","<template>\r\n\t<van-popup v-model:show=\"showPopup\" position=\"bottom\" :style=\"{ height: '100vh' }\">\r\n\t\t<div class=\"file-preview-container\">\r\n\t\t\t<div class=\"file-header\">\r\n\t\t\t\t<div class=\"file-title\">{{ currentFile?.name || \"文件预览\" }}</div>\r\n\t\t\t\t<van-icon name=\"cross\" size=\"20\" @click=\"handleClose\" />\r\n\t\t\t</div>\r\n\r\n\t\t\t<div class=\"file-content\">\r\n\t\t\t\t<div v-if=\"currentType === 'image'\" class=\"image-preview\">\r\n\t\t\t\t\t<van-image :src=\"currentFile?.url\" fit=\"contain\" class=\"preview-image\" />\r\n\t\t\t\t\t<div class=\"image-footer\">\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentIndex <= 0\" @click=\"prevFile\">上一个</van-button>\r\n\t\t\t\t\t\t<span class=\"file-info\">{{ currentIndex + 1 }} / {{ files.length }}</span>\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\">下一个</van-button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<div v-else-if=\"currentType === 'pdf'\" class=\"pdf-preview\">\r\n\t\t\t\t\t<VuePdfEmbed v-if=\"pdfSource\" :source=\"pdfSource\" :page=\"currentPage\" class=\"pdf-embed-preview\" @rendered=\"handlePdfRendered\" @loaded=\"handlePdfLoaded\" />\r\n\t\t\t\t\t<div v-else class=\"pdf-placeholder\">请选择PDF文件</div>\r\n\t\t\t\t\t<div class=\"pdf-footer\">\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentPage <= 1\" @click=\"currentPage--\">上一页</van-button>\r\n\t\t\t\t\t\t<span class=\"page-info\">第 {{ currentPage }} / {{ totalPages || \"?\" }} 页</span>\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"!pdfSource || currentPage >= totalPages\" @click=\"currentPage++\">下一页</van-button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<div class=\"footer\">\r\n\t\t\t\t\t<van-button :disabled=\"currentIndex <= 0\" @click=\"prevFile\" icon=\"arrow-left\" type=\"primary\" round />\r\n\t\t\t\t\t<van-button :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\" icon=\"arrow\" type=\"primary\" round />\r\n\t\t\t\t\t<!-- <van-button size=\"small\" :disabled=\"currentIndex <= 0\" @click=\"prevFile\">上一个</van-button>\r\n <span class=\"file-info\">{{ currentIndex + 1 }} / {{ files.length }}</span>\r\n <van-button size=\"small\" :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\">下一个</van-button> -->\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</van-popup>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkPreview\",\r\n});\r\nimport { ref, watch, computed } from \"vue\";\r\nimport VuePdfEmbed from \"vue-pdf-embed\";\r\n\r\nconst props = defineProps({\r\n\tmodelValue: {\r\n\t\ttype: Boolean,\r\n\t\tdefault: false,\r\n\t},\r\n\tfiles: {\r\n\t\ttype: Array,\r\n\t\tdefault: () => [],\r\n\t},\r\n\tstartIndex: {\r\n\t\ttype: Number,\r\n\t\tdefault: 0,\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"close\"]);\r\n\r\nconst showPopup = ref(props.modelValue);\r\nconst currentIndex = ref(props.startIndex);\r\nconst currentPage = ref(1);\r\nconst pdfSource = ref(null);\r\nconst totalPages = ref(0);\r\n\r\nconst normalizedFiles = computed(() => {\r\n\treturn props.files.map((file, index) => {\r\n\t\tif (typeof file === \"string\") {\r\n\t\t\tconst isPdf = file.toLowerCase().endsWith(\".pdf\");\r\n\t\t\treturn {\r\n\t\t\t\tname: isPdf ? `文档${index + 1}.pdf` : `图片${index + 1}`,\r\n\t\t\t\turl: file,\r\n\t\t\t\ttype: isPdf ? \"pdf\" : \"image\",\r\n\t\t\t};\r\n\t\t}\r\n\t\treturn file;\r\n\t});\r\n});\r\n\r\nconst currentFile = computed(() => {\r\n\treturn normalizedFiles.value[currentIndex.value] || null;\r\n});\r\n\r\nconst currentType = computed(() => {\r\n\tif (!currentFile.value) return null;\r\n\tconst url = currentFile.value.url || currentFile.value;\r\n\tif (typeof url === \"string\") {\r\n\t\treturn url.toLowerCase().endsWith(\".pdf\") ? \"pdf\" : \"image\";\r\n\t}\r\n\treturn currentFile.value.type || \"image\";\r\n});\r\n\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(val) => {\r\n\t\tshowPopup.value = val;\r\n\t\tif (val && normalizedFiles.value.length > 0) {\r\n\t\t\tcurrentIndex.value = props.startIndex;\r\n\t\t\tupdatePreview();\r\n\t\t}\r\n\t},\r\n);\r\n\r\nwatch(\r\n\t() => props.startIndex,\r\n\t(val) => {\r\n\t\tcurrentIndex.value = val;\r\n\t\tupdatePreview();\r\n\t},\r\n);\r\n\r\nwatch(showPopup, (val) => {\r\n\temit(\"update:modelValue\", val);\r\n\tif (!val) {\r\n\t\thandleClose();\r\n\t}\r\n});\r\n\r\nwatch(currentIndex, () => {\r\n\tcurrentPage.value = 1;\r\n\ttotalPages.value = 0;\r\n\tupdatePreview();\r\n});\r\n\r\nconst updatePreview = () => {\r\n\tconst file = currentFile.value;\r\n\tif (!file) return;\r\n\r\n\tif (currentType.value === \"pdf\") {\r\n\t\tpdfSource.value = file.url || file;\r\n\t} else {\r\n\t\tpdfSource.value = null;\r\n\t}\r\n};\r\n\r\nconst handlePdfLoaded = (pdf) => {\r\n\ttotalPages.value = pdf.numPages || 0;\r\n};\r\n\r\nconst handlePdfRendered = () => {\r\n\tconsole.log(\"PDF rendered successfully\");\r\n};\r\n\r\nconst prevFile = () => {\r\n\tif (currentIndex.value > 0) {\r\n\t\tcurrentIndex.value--;\r\n\t}\r\n};\r\n\r\nconst nextFile = () => {\r\n\tif (currentIndex.value < normalizedFiles.value.length - 1) {\r\n\t\tcurrentIndex.value++;\r\n\t}\r\n};\r\n\r\nconst handleClose = () => {\r\n\tshowPopup.value = false;\r\n\tpdfSource.value = null;\r\n\tcurrentPage.value = 1;\r\n\ttotalPages.value = 0;\r\n\temit(\"close\");\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.file-preview-container {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\theight: 100%;\r\n\tbackground-color: #fff;\r\n\tborder-radius: 8px;\r\n\toverflow: hidden;\r\n}\r\n\r\n.file-header {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: space-between;\r\n\tpadding: 12px 16px;\r\n\tborder-bottom: 1px solid #ebedf0;\r\n\tbackground-color: #f7f8fa;\r\n}\r\n\r\n.file-title {\r\n\tfont-size: 16px;\r\n\tfont-weight: 600;\r\n\tcolor: #323233;\r\n}\r\n\r\n.file-content {\r\n\tflex: 1;\r\n\toverflow: hidden;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n}\r\n\r\n.image-preview {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\toverflow: hidden;\r\n}\r\n\r\n.preview-image {\r\n\tflex: 1;\r\n\twidth: 100%;\r\n\theight: 100%;\r\n}\r\n\r\n.image-footer {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 16px;\r\n\tpadding: 12px 16px;\r\n\tborder-top: 1px solid #ebedf0;\r\n\tbackground-color: #fff;\r\n}\r\n\r\n.file-info {\r\n\tfont-size: 14px;\r\n\tcolor: #646566;\r\n\tmin-width: 80px;\r\n\ttext-align: center;\r\n}\r\n\r\n.pdf-preview {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\toverflow: hidden;\r\n}\r\n\r\n.pdf-embed-preview {\r\n\tflex: 1;\r\n\tmax-width: 100%;\r\n\toverflow-y: auto;\r\n\tpadding: 16px;\r\n\tdisplay: flex;\r\n\tjustify-content: center;\r\n\talign-items: flex-start;\r\n\tbackground-color: #f5f5f5;\r\n\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n.pdf-placeholder {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tcolor: #969799;\r\n\tfont-size: 14px;\r\n}\r\n\r\n.pdf-footer {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 16px;\r\n\tpadding: 12px 16px;\r\n\tborder-top: 1px solid #ebedf0;\r\n\tbackground-color: #fff;\r\n}\r\n\r\n.page-info {\r\n\tfont-size: 14px;\r\n\tcolor: #646566;\r\n\tmin-width: 80px;\r\n\ttext-align: center;\r\n}\r\n.footer {\r\n\tposition: fixed;\r\n\ttop: 40%;\r\n\twidth: 100%;\r\n\t.van-button {\r\n\t}\r\n\t.van-button:nth-child(2) {\r\n\t\tfloat: right;\r\n\t}\r\n}\r\n</style>\r\n","/**\r\n * Preview 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Preview from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nPreview.install = (app) => {\r\n app.component(Preview.name || 'VtkPreview', Preview)\r\n}\r\n\r\nexport default Preview\r\nexport { Preview }\r\n","/**\r\n * Vant-VTK 组件库全量导出入口\r\n * 支持全量引入和按需引入\r\n */\r\nimport Checkbox from '../packages/checkbox/index.js'\r\nimport Area from '../packages/Area/index.js'\r\nimport Radio from '../packages/radio/index.js'\r\nimport Uploader from '../packages/Uploader/index.js'\r\nimport Preview from '../packages/preview/index.js'\r\n\r\n\r\n\r\n// 所有组件列表\r\nconst components = [\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n]\r\n\r\n// 全量注册方法\r\nconst install = (app) => {\r\n components.forEach(component => {\r\n if (component.install) {\r\n app.use(component)\r\n } else if (component.name) {\r\n app.component(component.name, component)\r\n }\r\n })\r\n}\r\n\r\n// 默认导出 - 支持 app.use(VantVtk) 全量注册\r\nexport default {\r\n install,\r\n // 也导出所有组件,方便直接访问\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n}\r\n\r\n// 具名导出 - 支持按需引入\r\nexport {\r\n install,\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n}\r\n\r\n// 导出版本号\r\nexport const version = '1.0.0'\r\n"],"names":["props","__props","emit","__emit","parsedOptions","computed","item","value","text","internalValue","val","arr","newValues","emitValue","opt","_openBlock","_createBlock","_component_van_field","$attrs","_createVNode","_component_van_checkbox_group","$event","_createElementBlock","_Fragment","_renderList","_component_van_checkbox","_createTextVNode","_toDisplayString","Checkbox","app","show","ref","cascaderValue","options","displayValue","loading","selectedData","fieldNames","watch","handleClick","loadInitialArea","areaCode","res","rootArea","error","loadChildren","it","onChange","selectedOptions","tabIndex","currentItem","onFinish","_a","option","_b","_c","_d","_e","__expose","_mergeProps","_component_van_popup","_component_van_cascader","Area","newValue","_component_van_radio_group","_component_van_radio","Radio","fileList","parseModelValue","urls","url","getUploadedUrls","file","formatOutput","output","newVal","currentUrls","newUrls","beforeRead","files","f","maxSizeMB","showToast","uploadFile","formData","afterRead","showLoadingToast","successCount","failCount","i","fileItem","result","closeToast","onDelete","_component_van_uploader","Uploader","showPopup","currentIndex","currentPage","pdfSource","totalPages","normalizedFiles","index","isPdf","currentFile","currentType","updatePreview","handleClose","handlePdfLoaded","pdf","handlePdfRendered","prevFile","nextFile","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_component_van_icon","_hoisted_4","_hoisted_5","_component_van_image","_hoisted_6","_component_van_button","_cache","_hoisted_7","_hoisted_8","_unref","VuePdfEmbed","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","Preview","components","install","component","version"],"mappings":"2vBAmBE,MAAMA,EAAQC,EAwBRC,EAAOC,EAGPC,EAAgBC,EAAAA,SAAS,IACzB,MAAM,QAAQL,EAAM,OAAO,EACtBA,EAAM,QAEX,OAAOA,EAAM,SAAY,UAAYA,EAAM,QACtCA,EAAM,QACV,MAAM,GAAG,EACT,OAAO,OAAO,EACd,IAAKM,GAAS,CACb,KAAM,CAACC,EAAOC,CAAI,EAAIF,EAAK,MAAM,GAAG,EACpC,MAAO,CACL,KAAME,GAAQD,EACd,MAAOA,CACnB,CACQ,CAAC,EAEE,CAAA,CACR,EAGKE,EAAgBJ,EAAAA,SAAS,CAC7B,IAAK,IAAM,CACT,MAAMK,EAAMV,EAAM,WAClB,GAAI,CAACU,EAAK,MAAO,CAAA,EAEjB,IAAIC,EAAM,CAAA,EACV,OAAIX,EAAM,YAAc,SACtBW,EAAM,OAAOD,GAAQ,SAAWA,EAAI,MAAMV,EAAM,SAAS,EAAE,OAAO,OAAO,EAAI,CAAA,EACpEA,EAAM,YAAc,SAC7BW,EAAM,MAAM,QAAQD,CAAG,EAAIA,EAAI,IAAKJ,IAASA,GAAA,YAAAA,EAAM,QAASA,CAAI,EAAI,CAAA,EAEpEK,EAAM,MAAM,QAAQD,CAAG,EAAIA,EAAM,CAAA,EAG5BC,EAAI,IAAI,MAAM,CACvB,EACA,IAAMC,GAAc,CAClB,IAAIC,EACAb,EAAM,YAAc,SACtBa,EAAYD,EAAU,KAAKZ,EAAM,SAAS,EACjCA,EAAM,YAAc,SAE7Ba,EAAYT,EAAc,MAAM,OAAQU,GAAQF,EAAU,SAAS,OAAOE,EAAI,KAAK,CAAC,CAAC,EAGrFD,EAAYD,EAAU,IAAKF,GAClB,MAAM,OAAOA,CAAG,CAAC,EAAIA,EAAM,MAAM,QAAQV,EAAM,UAAU,GAAK,OAAOA,EAAM,WAAW,CAAC,GAAM,SAAW,OAAOU,CAAG,EAAIA,CAC9H,EAGHR,EAAK,oBAAqBW,CAAS,EACnCX,EAAK,SAAUW,CAAS,CAC1B,CACJ,CAAG,wIAlGD,OAAAE,EAAAA,UAAA,EAAAC,EAAAA,YAQYC,wCAROC,EAAAA,MAAM,CAAA,EAAA,CACZ,gBACT,IAIqB,CAJrBC,EAAAA,YAIqBC,EAAA,YAJQX,EAAA,2CAAAA,EAAa,MAAAY,GAAE,UAAU,iCACtC,IAA6B,kBAA3CC,EAAAA,mBAEeC,EAAAA,SAAA,KAAAC,EAAAA,WAFcpB,EAAA,MAARE,kBAArBU,EAAAA,YAEeS,EAAA,CAF8B,IAAK,OAAOnB,EAAK,KAAK,EAAI,KAAM,OAAOA,EAAK,KAAK,EAAG,MAAM,6BACrG,IAAe,CAAZoB,EAAAA,gBAAAC,EAAAA,gBAAArB,EAAK,IAAI,EAAA,CAAA,2GCEtBsB,EAAS,QAAWC,GAAQ,CAC1BA,EAAI,UAAUD,EAAS,MAAQ,cAAeA,CAAQ,CACxD,4iBCKA,MAAM5B,EAAQC,EA6CRC,EAAOC,EAEP2B,EAAOC,EAAAA,IAAI,EAAK,EAChBC,EAAgBD,EAAAA,IAAI,EAAE,EACtBE,EAAUF,EAAAA,IAAI,CAAA,CAAE,EAChBG,EAAeH,EAAAA,IAAI,EAAE,EACrBI,EAAUJ,EAAAA,IAAI,EAAK,EAEnBK,EAAeL,EAAAA,IAAI,CAAA,CAAE,EAErBM,EAAa,CAClB,KAAM,WACN,MAAO,WACP,SAAU,UACX,EAGAC,EAAAA,MACC,IAAMtC,EAAM,WACXU,GAAQ,CACHA,IACJwB,EAAa,MAAQ,GACrBF,EAAc,MAAQ,GACtBI,EAAa,MAAQ,GAEvB,EACA,CAAE,UAAW,EAAI,CAClB,EAEA,MAAMG,EAAc,IAAM,CACzBT,EAAK,MAAQ,GACTG,EAAQ,MAAM,SAAW,GAC5BO,GAEF,EAGMA,EAAkB,SAAY,CACnC,GAAI,CAAAL,EAAQ,MACZ,CAAAA,EAAQ,MAAQ,GAChB,GAAI,CACH,MAAMM,EAAWzC,EAAM,gBACjB0C,EAAM,MAAM,QAAQ,QAAQ,kBAAkBD,CAAQ,EAAE,EAC9D,GAAIC,EAAI,KAAM,CACb,MAAMC,EAAW,CAChB,SAAUD,EAAI,KAAK,SACnB,SAAUA,EAAI,KAAK,SACnB,SAAUA,EAAI,KAAK,SACnB,SAAUA,EAAI,KAAK,SAAW1C,EAAM,SAAW,CAAA,EAAK,MACxD,EACGiC,EAAQ,MAAQ,CAACU,CAAQ,CAC1B,CACD,OAASC,EAAO,CACf,QAAQ,MAAM,YAAaA,CAAK,CACjC,QAAC,CACAT,EAAQ,MAAQ,EACjB,EACD,EAGMU,EAAe,MAAOvC,GAAS,CACpC,GAAI,CAAAA,EAAK,SACT,CAAAA,EAAK,SAAW,GAChB,GAAI,CACH,MAAMoC,EAAM,MAAM,QAAQ,QAAQ,kBAAkBpC,EAAK,QAAQ,EAAE,EAC/DoC,EAAI,MAAQA,EAAI,KAAK,OAAS,GACjCA,EAAI,KAAK,QAASI,GAAO,CAEpBA,EAAG,SAAW9C,EAAM,WACvB8C,EAAG,SAAW,GAEhB,CAAC,EACDxC,EAAK,SAAWoC,EAAI,MAGpB,OAAOpC,EAAK,QAEd,OAASsC,EAAO,CACf,QAAQ,MAAM,YAAaA,CAAK,CACjC,QAAC,CACAtC,EAAK,SAAW,EACjB,EACD,EAGMyC,EAAW,CAAC,CAAE,MAAAxC,EAAO,gBAAAyC,EAAiB,SAAAC,CAAQ,IAAO,CAC1D,MAAMC,EAAcF,EAAgBC,CAAQ,EACxCC,GAAeA,EAAY,SAAWlD,EAAM,UAAY,MAAM,QAAQkD,EAAY,QAAQ,GAAKA,EAAY,SAAS,SAAW,GAClIL,EAAaK,CAAW,EAEzBhD,EAAK,SAAU,CAAE,MAAAK,EAAO,gBAAAyC,EAAiB,SAAAC,CAAQ,CAAE,CACpD,EAGME,EAAW,CAAC,CAAE,gBAAAH,KAAsB,eAErChD,EAAM,cAAgB,OAEzBkC,EAAa,QAAQkB,EAAAJ,EAAgBA,EAAgB,OAAS,CAAC,IAA1C,YAAAI,EAA6C,WAAY,GAG9ElB,EAAa,MAAQc,EAAgB,IAAKK,GAAWA,EAAO,QAAQ,EAAE,KAAKrD,EAAM,SAAS,EAI3FoC,EAAa,MAAQY,EAAgB,IAAKK,IAAY,CACrD,SAAUA,EAAO,SACjB,SAAUA,EAAO,SACjB,SAAUA,EAAO,QACnB,EAAG,EAGF,IAAIxC,EACJ,OAAQb,EAAM,UAAS,CACtB,IAAK,OAEJa,IAAYyC,EAAAN,EAAgBA,EAAgB,OAAS,CAAC,IAA1C,YAAAM,EAA6C,WAAY,GACrE,MACD,IAAK,QAEJzC,EAAYmC,EAAgB,IAAKK,GAAWA,EAAO,QAAQ,EAC3D,MACD,IAAK,SAEJxC,EAAY,CACX,MAAOmC,EAAgB,IAAKK,GAAWA,EAAO,QAAQ,EACtD,MAAOL,EAAgB,IAAKK,GAAWA,EAAO,QAAQ,EACtD,SAAUL,EAAgB,IAAKK,GAAWA,EAAO,QAAQ,EAAE,KAAKrD,EAAM,SAAS,EAC/E,WAAUuD,EAAAP,EAAgBA,EAAgB,OAAS,CAAC,IAA1C,YAAAO,EAA6C,WAAY,GACnE,WAAWC,EAAAR,EAAgBA,EAAgB,OAAS,CAAC,IAA1C,YAAAQ,EAA6C,SACxD,QAASpB,EAAa,KAC1B,EACG,MACD,QACCvB,IAAY4C,EAAAT,EAAgBA,EAAgB,OAAS,CAAC,IAA1C,YAAAS,EAA6C,WAAY,EACxE,CAECvD,EAAK,oBAAqBW,CAAS,EACnCX,EAAK,SAAU,CAAE,gBAAA8C,EAAiB,MAAOnC,CAAS,CAAE,EACpDiB,EAAK,MAAQ,EACd,EAGA,OAAA4B,EAAa,CAEZ,gBAAiB,IAAMtB,EAAa,MAEpC,gBAAiB,IAAMF,EAAa,MAEpC,MAAO,IAAM,CACZA,EAAa,MAAQ,GACrBF,EAAc,MAAQ,GACtBI,EAAa,MAAQ,GACrBlC,EAAK,oBAAqBF,EAAM,YAAc,QAAU,CAAA,EAAKA,EAAM,YAAc,SAAW,KAAO,EAAE,CACtG,EAEA,KAAM,IAAM,CACXuC,GACD,EAEA,MAAO,IAAM,CACZT,EAAK,MAAQ,EACd,CACD,CAAC,oLA7NAX,EAAAA,YAAqHF,EAArH0C,aAAqH,YAAjGzB,EAAA,2CAAAA,EAAY,MAAAb,GAAE,UAAA,GAAQ,SAAA,IAAiBH,EAAAA,OAAM,CAAG,YAAajB,EAAA,YAAc,QAAOsC,0CACtGpB,EAAAA,YAEYyC,EAAA,CAFO,KAAM9B,EAAA,qCAAAA,EAAI,MAAAT,GAAE,MAAA,GAAM,SAAS,6BAC7C,IAAgK,CAAhKF,EAAAA,YAAgK0C,EAAA,YAAzI7B,EAAA,2CAAAA,EAAa,MAAAX,GAAG,MAAOpB,EAAA,MAAQ,QAASgC,EAAA,MAAU,cAAaI,EAAa,uBAAOP,EAAA,MAAI,IAAW,SAAQqB,EAAW,SAAQJ,wECItJe,EAAK,QAAWjC,GAAQ,CACtBA,EAAI,UAAUiC,EAAK,MAAQ,UAAWA,CAAI,CAC5C,kTCSA,MAAM9D,EAAQC,EAmBRC,EAAOC,EAGPC,EAAgBC,EAAAA,SAAS,IAC1B,MAAM,QAAQL,EAAM,OAAO,EACvBA,EAAM,QAEV,OAAOA,EAAM,SAAY,UAAYA,EAAM,QACvCA,EAAM,QACX,MAAM,GAAG,EACT,OAAO,OAAO,EACd,IAAKM,GAAS,CACd,KAAM,CAACC,EAAOC,CAAI,EAAIF,EAAK,MAAM,GAAG,EACpC,MAAO,CACN,KAAME,GAAQD,EACd,MAAOA,CACZ,CACG,CAAC,EAEI,EACP,EAGKE,EAAgBJ,EAAAA,SAAS,CAC9B,IAAK,IAAM,CACV,MAAMK,EAAMV,EAAM,WAClB,OAAyBU,GAAQ,KAAa,GAG1CV,EAAM,YAAc,UAAYU,GAAO,OAAOA,GAAQ,SAClD,OAAOA,EAAI,OAAS,EAAE,EAEvB,OAAOA,CAAG,CAClB,EACA,IAAMqD,GAAa,OAClB,IAAIlD,EAAYkD,EAIZ,OADkB/D,EAAM,YAAc,UAAWoD,EAAApD,EAAM,aAAN,YAAAoD,EAAkB,MAAQpD,EAAM,aACxD,UAAY,CAAC,MAAM,OAAO+D,CAAQ,CAAC,IAC/DlD,EAAY,OAAOkD,CAAQ,GAGxB/D,EAAM,YAAc,WAEvBa,EAAYT,EAAc,MAAM,KAAMU,GAAQ,OAAOA,EAAI,KAAK,IAAM,OAAOiD,CAAQ,CAAC,GAAK,MAG1F7D,EAAK,oBAAqBW,CAAS,EACnCX,EAAK,SAAUW,CAAS,CACzB,CACD,CAAC,kIAvFA,OAAAE,EAAAA,UAAA,EAAAC,EAAAA,YAQYC,wCAROC,EAAAA,MAAM,CAAA,EAAA,CACb,gBACV,IAIkB,CAJlBC,EAAAA,YAIkB6C,EAAA,YAJQvD,EAAA,2CAAAA,EAAa,MAAAY,GAAE,UAAU,iCACvC,IAA6B,kBAAxCC,EAAAA,mBAEYC,EAAAA,SAAA,KAAAC,EAAAA,WAFcpB,EAAA,MAARE,kBAAlBU,EAAAA,YAEYiD,EAAA,CAF8B,IAAK,OAAO3D,EAAK,KAAK,EAAI,KAAM,OAAOA,EAAK,KAAK,sBAC1F,IAAe,CAAZoB,EAAAA,gBAAAC,EAAAA,gBAAArB,EAAK,IAAI,EAAA,CAAA,2GCEjB4D,EAAM,QAAWrC,GAAQ,CACvBA,EAAI,UAAUqC,EAAM,MAAQ,WAAYA,CAAK,CAC/C,ydCGA,MAAMlE,EAAQC,EAkCRC,EAAOC,EAGPgE,EAAWpC,EAAAA,IAAI,CAAA,CAAE,EAGjBqC,EAAmB7D,GAAU,CAClC,GAAI,CAACA,EAAO,MAAO,GAEnB,IAAI8D,EAAO,CAAA,EACX,OAAI,OAAO9D,GAAU,SACpB8D,EAAO9D,EAAM,MAAM,GAAG,EAAE,OAAQ+D,GAAQA,EAAI,KAAI,CAAE,EACxC,MAAM,QAAQ/D,CAAK,IAC7B8D,EAAO9D,EAAM,OAAQ+D,GAAQA,CAAG,GAG1BD,EAAK,IAAKC,IAAS,CACzB,IAAAA,EACA,OAAQ,OACR,QAAS,EACX,EAAG,CACH,EAGMC,EAAkB,IAChBJ,EAAS,MAAM,OAAQK,GAASA,EAAK,SAAW,QAAUA,EAAK,GAAG,EAAE,IAAKA,GAASA,EAAK,GAAG,EAI5FC,EAAgBJ,GACjBrE,EAAM,YAAc,SAChBqE,EAAK,KAAK,GAAG,EAEdA,EAIFxD,EAAY,IAAM,CACvB,MAAMwD,EAAOE,IACPG,EAASD,EAAaJ,CAAI,EAChCnE,EAAK,oBAAqBwE,CAAM,EAChCxE,EAAK,SAAUwE,CAAM,CACtB,EAGApC,EAAAA,MACC,IAAMtC,EAAM,WACX2E,GAAW,CACX,MAAMC,EAAcL,EAAe,EAAG,KAAK,GAAG,EACxCM,EAAU,MAAM,QAAQF,CAAM,EAAIA,EAAO,KAAK,GAAG,EAAIA,GAAU,GAGjEC,IAAgBC,IACnBV,EAAS,MAAQC,EAAgBO,CAAM,EAEzC,EACA,CAAE,UAAW,EAAI,CAClB,EAGA,MAAMG,EAAcN,GAAS,CAC5B,MAAMO,EAAQ,MAAM,QAAQP,CAAI,EAAIA,EAAO,CAACA,CAAI,EAEhD,UAAWQ,KAAKD,EAEf,GAAIC,EAAE,KAAOhF,EAAM,QAAS,CAC3B,MAAMiF,GAAajF,EAAM,QAAU,KAAO,MAAM,QAAQ,CAAC,EACzDkF,OAAAA,EAAAA,UAAU,WAAWD,CAAS,IAAI,EAC3B,EACR,CAED,MAAO,EACR,EAGME,EAAa,MAAOX,GAAS,aAClC,MAAMY,EAAW,IAAI,SACrBA,EAAS,OAAOpF,EAAM,UAAWwE,EAAK,IAAI,EAE1C,GAAI,CACH,MAAM9B,EAAM,MAAM,QAAQ,IAAI1C,EAAM,UAAWoF,CAAQ,EAEvD,OAAIhC,EAAAV,EAAI,OAAJ,MAAAU,EAAU,QAGN,CAAE,QAAS,GAAM,MADZE,EAAAZ,EAAI,OAAJ,YAAAY,EAAU,QAAOC,EAAAb,EAAI,OAAJ,YAAAa,EAAU,OAAQb,EAAI,MAG5C,CAAE,QAAS,GAAO,UAASc,EAAAd,EAAI,OAAJ,YAAAc,EAAU,UAAW,OAEzD,OAASZ,EAAO,CACf,MAAO,CAAE,QAAS,GAAO,QAASA,EAAM,SAAW,OACpD,CACD,EAGMyC,EAAY,MAAOb,GAAS,CACjC,MAAMO,EAAQ,MAAM,QAAQP,CAAI,EAAIA,EAAO,CAACA,CAAI,EAG5CO,EAAM,OAAS,GAClBO,mBAAiB,CAChB,QAAS,UAAUP,EAAM,MAAM,GAC/B,YAAa,GACb,SAAU,CACb,CAAG,EAGF,IAAIQ,EAAe,EACfC,EAAY,EAGhB,QAASC,EAAI,EAAGA,EAAIV,EAAM,OAAQU,IAAK,CACtC,MAAMC,EAAWX,EAAMU,CAAC,EACxBC,EAAS,OAAS,YAClBA,EAAS,QAAU,SAGfX,EAAM,OAAS,GAClBO,mBAAiB,CAChB,QAAS,QAAQG,EAAI,CAAC,IAAIV,EAAM,MAAM,GACtC,YAAa,GACb,SAAU,CACd,CAAI,EAGF,MAAMY,EAAS,MAAMR,EAAWO,CAAQ,EAEpCC,EAAO,SACVD,EAAS,OAAS,OAClBA,EAAS,QAAU,GACnBA,EAAS,IAAMC,EAAO,IACtBJ,IACArF,EAAK,UAAW,CAAE,KAAMwF,EAAU,IAAKC,EAAO,GAAG,CAAE,IAEnDD,EAAS,OAAS,SAClBA,EAAS,QAAUC,EAAO,QAC1BH,IACAtF,EAAK,QAAS,CAAE,KAAMwF,EAAU,QAASC,EAAO,OAAO,CAAE,EAE3D,CAEAC,EAAAA,aAGIb,EAAM,OAAS,EACdS,IAAc,EACjBN,EAAAA,UAAU,GAAGK,CAAY,SAAS,EAElCL,EAAAA,UAAU,GAAGK,CAAY,OAAOC,CAAS,KAAK,EAErCA,EAAY,GACtBN,EAAAA,UAAUH,EAAM,CAAC,EAAE,SAAW,MAAM,EAIrClE,GACD,EAGMgF,EAAW,IAAM,CAEtB,WAAW,IAAM,CAChBhF,GACD,EAAG,CAAC,CACL,EAGA,OAAA6C,EAAa,CAEZ,QAASa,EAET,MAAO,IAAM,CACZJ,EAAS,MAAQ,GACjBtD,GACD,EAEA,YAAa,IAAMsD,EAAS,KAC7B,CAAC,qDA9NA,OAAApD,YAAA,EAAAC,cAA6J8E,EAA7JnC,EAAAA,WAA6J,YAAtIQ,EAAA,2CAAAA,EAAQ,MAAA9C,IAAUH,EAAAA,OAAM,CAAG,WAAUjB,EAAA,QAAU,OAAQA,EAAA,OAAS,cAAa6E,EAAa,aAAYO,EAAY,SAAQQ,6FCMlJE,EAAS,QAAWlE,GAAQ,CAC1BA,EAAI,UAAUkE,EAAS,MAAQ,cAAeA,CAAQ,CACxD,giBCsCA,MAAM/F,EAAQC,EAeRC,EAAOC,EAEP6F,EAAYjE,EAAAA,IAAI/B,EAAM,UAAU,EAChCiG,EAAelE,EAAAA,IAAI/B,EAAM,UAAU,EACnCkG,EAAcnE,EAAAA,IAAI,CAAC,EACnBoE,EAAYpE,EAAAA,IAAI,IAAI,EACpBqE,EAAarE,EAAAA,IAAI,CAAC,EAElBsE,EAAkBhG,EAAAA,SAAS,IACzBL,EAAM,MAAM,IAAI,CAACwE,EAAM8B,IAAU,CACvC,GAAI,OAAO9B,GAAS,SAAU,CAC7B,MAAM+B,EAAQ/B,EAAK,YAAW,EAAG,SAAS,MAAM,EAChD,MAAO,CACN,KAAM+B,EAAQ,KAAKD,EAAQ,CAAC,OAAS,KAAKA,EAAQ,CAAC,GACnD,IAAK9B,EACL,KAAM+B,EAAQ,MAAQ,OAC1B,CACE,CACA,OAAO/B,CACR,CAAC,CACD,EAEKgC,EAAcnG,EAAAA,SAAS,IACrBgG,EAAgB,MAAMJ,EAAa,KAAK,GAAK,IACpD,EAEKQ,EAAcpG,EAAAA,SAAS,IAAM,CAClC,GAAI,CAACmG,EAAY,MAAO,OAAO,KAC/B,MAAMlC,EAAMkC,EAAY,MAAM,KAAOA,EAAY,MACjD,OAAI,OAAOlC,GAAQ,SACXA,EAAI,cAAc,SAAS,MAAM,EAAI,MAAQ,QAE9CkC,EAAY,MAAM,MAAQ,OAClC,CAAC,EAEDlE,EAAAA,MACC,IAAMtC,EAAM,WACXU,GAAQ,CACRsF,EAAU,MAAQtF,EACdA,GAAO2F,EAAgB,MAAM,OAAS,IACzCJ,EAAa,MAAQjG,EAAM,WAC3B0G,IAEF,CACD,EAEApE,EAAAA,MACC,IAAMtC,EAAM,WACXU,GAAQ,CACRuF,EAAa,MAAQvF,EACrBgG,GACD,CACD,EAEApE,EAAAA,MAAM0D,EAAYtF,GAAQ,CACzBR,EAAK,oBAAqBQ,CAAG,EACxBA,GACJiG,GAEF,CAAC,EAEDrE,EAAAA,MAAM2D,EAAc,IAAM,CACzBC,EAAY,MAAQ,EACpBE,EAAW,MAAQ,EACnBM,GACD,CAAC,EAED,MAAMA,EAAgB,IAAM,CAC3B,MAAMlC,EAAOgC,EAAY,MACpBhC,IAEDiC,EAAY,QAAU,MACzBN,EAAU,MAAQ3B,EAAK,KAAOA,EAE9B2B,EAAU,MAAQ,KAEpB,EAEMS,EAAmBC,GAAQ,CAChCT,EAAW,MAAQS,EAAI,UAAY,CACpC,EAEMC,EAAoB,IAAM,CAC/B,QAAQ,IAAI,2BAA2B,CACxC,EAEMC,EAAW,IAAM,CAClBd,EAAa,MAAQ,GACxBA,EAAa,OAEf,EAEMe,EAAW,IAAM,CAClBf,EAAa,MAAQI,EAAgB,MAAM,OAAS,GACvDJ,EAAa,OAEf,EAEMU,EAAc,IAAM,CACzBX,EAAU,MAAQ,GAClBG,EAAU,MAAQ,KAClBD,EAAY,MAAQ,EACpBE,EAAW,MAAQ,EACnBlG,EAAK,OAAO,CACb,mLArKCc,EAAAA,YAoCY4C,EAAA,CApCO,KAAMoC,EAAA,qCAAAA,EAAS,MAAA3E,GAAE,SAAS,SAAU,MAAO,CAAA,OAAA,OAAA,sBAC7D,IAAA,SAkCM,OAlCN4F,EAAAA,mBAkCM,MAlCNC,EAkCM,CAjCLD,EAAAA,mBAGM,MAHNE,EAGM,CAFLF,qBAA+D,MAA/DG,EAA+DzF,oBAApCyB,EAAAoD,EAAA,QAAA,YAAApD,EAAa,OAAI,MAAA,EAAA,CAAA,EAC5CjC,EAAAA,YAAwDkG,EAAA,CAA9C,KAAK,QAAQ,KAAK,KAAM,QAAOV,MAG1CM,EAAAA,mBA2BM,MA3BNK,EA2BM,CA1BMb,EAAA,QAAW,SAAtB1F,EAAAA,YAAAO,EAAAA,mBAOM,MAPNiG,EAOM,CANLpG,EAAAA,YAAyEqG,EAAA,CAA7D,KAAKlE,EAAAkD,EAAA,QAAA,YAAAlD,EAAa,IAAK,IAAI,UAAU,MAAM,iCACvD2D,EAAAA,mBAIM,MAJNQ,EAIM,CAHLtG,EAAAA,YAAyFuG,EAAA,CAA7E,KAAK,QAAS,SAAUzB,EAAA,OAAY,EAAQ,QAAOc,sBAAU,IAAG,CAAA,GAAAY,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAA,mBAAH,MAAG,EAAA,2BAC5EV,EAAAA,mBAA0E,OAA1EW,EAA0EjG,EAAAA,gBAA/CsE,EAAA,SAAmB,MAAGtE,EAAAA,gBAAG1B,EAAA,MAAM,MAAM,EAAA,CAAA,EAChEkB,EAAAA,YAAwGuG,EAAA,CAA5F,KAAK,QAAS,SAAUzB,EAAA,OAAgBhG,EAAA,MAAM,OAAM,EAAO,QAAO+G,sBAAU,IAAG,CAAA,GAAAW,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAA,mBAAH,MAAG,EAAA,gCAI7ElB,EAAA,QAAW,OAA3B1F,EAAAA,YAAAO,EAAAA,mBAQM,MARNuG,EAQM,CAPc1B,EAAA,qBAAnBnF,EAAAA,YAA0J8G,EAAAA,MAAAC,CAAA,EAAA,OAA3H,OAAQ5B,EAAA,MAAY,KAAMD,EAAA,MAAa,MAAM,oBAAqB,WAAUY,EAAoB,SAAQF,6CACvItF,EAAAA,mBAAkD,MAAlD0G,EAAoC,UAAQ,GAC5Cf,EAAAA,mBAIM,MAJNgB,EAIM,CAHL9G,EAAAA,YAA6FuG,EAAA,CAAjF,KAAK,QAAS,SAAUxB,EAAA,OAAW,EAAQ,uBAAOA,EAAA,6BAAe,IAAG,CAAA,GAAAyB,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAA,mBAAH,MAAG,EAAA,2BAChFV,EAAAA,mBAA8E,OAA9EiB,EAAwB,KAAEvG,EAAAA,gBAAGuE,EAAA,KAAW,EAAG,MAAGvE,EAAAA,gBAAGyE,EAAA,OAAU,GAAA,EAAU,KAAE,CAAA,EACvEjF,EAAAA,YAAoHuG,EAAA,CAAxG,KAAK,QAAS,SAAQ,CAAGvB,EAAA,OAAaD,EAAA,OAAeE,EAAA,MAAa,uBAAOF,EAAA,6BAAe,IAAG,CAAA,GAAAyB,EAAA,CAAA,IAAAA,EAAA,CAAA,EAAA,mBAAH,MAAG,EAAA,4DAIzGV,EAAAA,mBAMM,MANNkB,EAMM,CALLhH,EAAAA,YAAqGuG,EAAA,CAAxF,SAAUzB,EAAA,OAAY,EAAQ,QAAOc,EAAU,KAAK,aAAa,KAAK,UAAU,MAAA,yBAC7F5F,EAAAA,YAA+GuG,EAAA,CAAlG,SAAUzB,EAAA,OAAgBhG,EAAA,MAAM,OAAM,EAAO,QAAO+G,EAAU,KAAK,QAAQ,KAAK,UAAU,MAAA,0FCvB5GoB,EAAQ,QAAWvG,GAAQ,CACzBA,EAAI,UAAUuG,EAAQ,MAAQ,aAAcA,CAAO,CACrD,ECIA,MAAMC,EAAa,CACjBzG,EACAkC,EACAI,EACA6B,EACAqC,CACF,EAGME,EAAWzG,GAAQ,CACvBwG,EAAW,QAAQE,GAAa,CAC1BA,EAAU,QACZ1G,EAAI,IAAI0G,CAAS,EACRA,EAAU,MACnB1G,EAAI,UAAU0G,EAAU,KAAMA,CAAS,CAE3C,CAAC,CACH,EAGAjC,EAAe,CACb,QAAAgC,EAEA,SAAA1G,EACF,KAAEkC,EACA,MAAAI,EACA,SAAA6B,EACA,QAAAqC,CACF,EAaaI,EAAU"}
1
+ {"version":3,"file":"vant-vtk.umd.js","sources":["../packages/checkbox/index.vue","../packages/checkbox/index.js","../packages/Area/index.vue","../packages/Area/index.js","../packages/Radio/index.vue","../packages/Radio/index.js","../packages/Uploader/index.vue","../packages/Uploader/index.js","../packages/preview/index.vue","../packages/preview/index.js","../src/index.js"],"sourcesContent":["<template>\r\n <van-field v-bind=\"$attrs\">\r\n <template #input>\r\n <van-checkbox-group v-model=\"internalValue\" direction=\"horizontal\">\r\n <van-checkbox v-for=\"item in parsedOptions\" :key=\"String(item.value)\" :name=\"String(item.value)\" shape=\"square\">\r\n {{ item.text }}\r\n </van-checkbox>\r\n </van-checkbox-group>\r\n </template>\r\n </van-field>\r\n</template>\r\n\r\n<script setup>\r\n import { computed } from 'vue'\r\n\r\n defineOptions({\r\n name: 'VtkCheckbox'\r\n })\r\n\r\n const props = defineProps({\r\n // 绑定值\r\n modelValue: {\r\n type: [String, Array, Object],\r\n default: () => [],\r\n },\r\n // 选项数据:支持数组 [{value, text}] 或 字符串 '1:选项1/2:选项2'\r\n options: {\r\n type: [Array, String],\r\n default: () => [],\r\n },\r\n // 返回值类型: 'string' (逗号分隔), 'array' (值数组), 'object' (对象数组)\r\n valueType: {\r\n type: String,\r\n default: 'array',\r\n validator: (val) => ['string', 'array', 'object'].includes(val),\r\n },\r\n // 当 valueType 为 string 时的分隔符\r\n separator: {\r\n type: String,\r\n default: ',',\r\n },\r\n })\r\n\r\n const emit = defineEmits(['update:modelValue', 'change'])\r\n\r\n // 解析选项\r\n const parsedOptions = computed(() => {\r\n if (Array.isArray(props.options)) {\r\n return props.options\r\n }\r\n if (typeof props.options === 'string' && props.options) {\r\n return props.options\r\n .split('/')\r\n .filter(Boolean)\r\n .map((item) => {\r\n const [value, text] = item.split(':')\r\n return {\r\n text: text || value,\r\n value: value,\r\n }\r\n })\r\n }\r\n return []\r\n })\r\n\r\n // 使用可写计算属性处理 v-model 绑定\r\n const internalValue = computed({\r\n get: () => {\r\n const val = props.modelValue\r\n if (!val) return []\r\n\r\n let arr = []\r\n if (props.valueType === 'string') {\r\n arr = typeof val === 'string' ? val.split(props.separator).filter(Boolean) : []\r\n } else if (props.valueType === 'object') {\r\n arr = Array.isArray(val) ? val.map((item) => item?.value ?? item) : []\r\n } else {\r\n arr = Array.isArray(val) ? val : []\r\n }\r\n // 统一转为字符串,确保与 van-checkbox 的 name 匹配\r\n return arr.map(String)\r\n },\r\n set: (newValues) => {\r\n let emitValue\r\n if (props.valueType === 'string') {\r\n emitValue = newValues.join(props.separator)\r\n } else if (props.valueType === 'object') {\r\n // 从解析后的选项中过滤出完整的对象\r\n emitValue = parsedOptions.value.filter((opt) => newValues.includes(String(opt.value)))\r\n } else {\r\n // 如果原始数据是数字,则尝试转回数字,否则保持字符串\r\n emitValue = newValues.map((val) => {\r\n return isNaN(Number(val)) ? val : Array.isArray(props.modelValue) && typeof props.modelValue[0] === 'number' ? Number(val) : val\r\n })\r\n }\r\n\r\n emit('update:modelValue', emitValue)\r\n emit('change', emitValue)\r\n },\r\n })\r\n</script>\r\n\r\n<style scoped>\r\n :deep(.van-checkbox) {\r\n margin-bottom: 8px;\r\n margin-right: 12px;\r\n }\r\n</style>\r\n","/**\r\n * Checkbox 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Checkbox from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nCheckbox.install = (app) => {\r\n app.component(Checkbox.name || 'VtkCheckbox', Checkbox)\r\n}\r\n\r\nexport default Checkbox\r\nexport { Checkbox }\r\n","<template>\r\n\t<van-field v-model=\"displayValue\" is-link readonly v-bind=\"$attrs\" :placeholder=\"placeholder\" @click=\"handleClick\" />\r\n\t<van-popup v-model:show=\"show\" round position=\"bottom\">\r\n\t\t<van-cascader v-model=\"cascaderValue\" :title=\"title\" :options=\"options\" :field-names=\"fieldNames\" @close=\"show = false\" @finish=\"onFinish\" @change=\"onChange\" />\r\n\t</van-popup>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkArea\",\r\n});\r\nimport { ref, watch, inject, getCurrentInstance } from \"vue\";\r\n// import Request from \"@/utils/request\";\r\n\r\nconst injectedRequest = inject(\"vant-vtk:request\", null);\r\nconst globalProperties = getCurrentInstance()?.appContext.config.globalProperties;\r\nconst globalRequest = globalProperties?.$vtkRequest || globalProperties?.$request;\r\nconst getRequest = () => {\r\n\tconst request = injectedRequest || globalRequest;\r\n\tif (!request) {\r\n\t\tthrow new Error(\"VantVtk request 未配置\");\r\n\t}\r\n\treturn request;\r\n};\r\n\r\nconst props = defineProps({\r\n\t// 绑定值,根据 valueType 返回不同类型\r\n\tmodelValue: {\r\n\t\ttype: [String, Object, Array],\r\n\t\tdefault: \"\",\r\n\t},\r\n\t// 默认地区编码,用于初始化加载\r\n\tdefaultAreaCode: {\r\n\t\ttype: String,\r\n\t\tdefault: \"33\",\r\n\t},\r\n\t// 返回值类型: 'code' 返回最后一级areaCode, 'codes' 返回所有级别areaCode数组, 'object' 返回完整对象信息\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"code\",\r\n\t\tvalidator: (val) => [\"code\", \"codes\", \"object\"].includes(val),\r\n\t},\r\n\t// 显示分隔符\r\n\tseparator: {\r\n\t\ttype: String,\r\n\t\tdefault: \"/\",\r\n\t},\r\n\t// 弹窗标题\r\n\ttitle: {\r\n\t\ttype: String,\r\n\t\tdefault: \"请选择所在地区\",\r\n\t},\r\n\t// 占位文本\r\n\tplaceholder: {\r\n\t\ttype: String,\r\n\t\tdefault: \"请选择所在地区\",\r\n\t},\r\n\t// 最大层级限制,达到该层级后不再加载下级\r\n\tmaxLevel: {\r\n\t\ttype: Number,\r\n\t\tdefault: 12,\r\n\t},\r\n\t// 显示模式: 'full' 显示完整路径, 'last' 只显示最后一级\r\n\tdisplayMode: {\r\n\t\ttype: String,\r\n\t\tdefault: \"full\",\r\n\t\tvalidator: (val) => [\"full\", \"last\"].includes(val),\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"finish\"]);\r\n\r\nconst show = ref(false); //弹窗显示隐藏\r\nconst cascaderValue = ref(\"\"); //级联选择器绑定值\r\nconst options = ref([]); //级联选择器选项\r\nconst displayValue = ref(\"\"); //显示值\r\nconst loading = ref(false); //加载状态\r\n// 存储完整的选中信息\r\nconst selectedData = ref([]);\r\n\r\nconst fieldNames = {\r\n\ttext: \"areaName\",\r\n\tvalue: \"areaCode\",\r\n\tchildren: \"children\",\r\n};\r\n\r\n// 监听 modelValue 变化,用于回显\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(val) => {\r\n\t\tif (!val) {\r\n\t\t\tdisplayValue.value = \"\";\r\n\t\t\tcascaderValue.value = \"\";\r\n\t\t\tselectedData.value = [];\r\n\t\t}\r\n\t},\r\n\t{ immediate: true },\r\n);\r\n\r\nconst handleClick = () => {\r\n\tshow.value = true;\r\n\tif (options.value.length === 0) {\r\n\t\tloadInitialArea();\r\n\t}\r\n};\r\n\r\n// 加载初始地区\r\nconst loadInitialArea = async () => {\r\n\tif (loading.value) return;\r\n\tloading.value = true;\r\n\ttry {\r\n\t\tconst areaCode = props.defaultAreaCode;\r\n\t\tconst res = await getRequest().getForm(`dict/area/show/${areaCode}`);\r\n\t\tif (res.data) {\r\n\t\t\tconst rootArea = {\r\n\t\t\t\tareaCode: res.data.areaCode,\r\n\t\t\t\tareaName: res.data.areaName,\r\n\t\t\t\tareaLeve: res.data.areaLeve,\r\n\t\t\t\tchildren: res.data.areaLeve < props.maxLevel ? [] : undefined,\r\n\t\t\t};\r\n\t\t\toptions.value = [rootArea];\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tconsole.error(\"加载初始地区失败:\", error);\r\n\t} finally {\r\n\t\tloading.value = false;\r\n\t}\r\n};\r\n\r\n// 加载下级地区\r\nconst loadChildren = async (item) => {\r\n\tif (item._loading) return;\r\n\titem._loading = true;\r\n\ttry {\r\n\t\tconst res = await getRequest().getForm(`dict/area/next/${item.areaCode}`);\r\n\t\tif (res.data && res.data.length > 0) {\r\n\t\t\tres.data.forEach((it) => {\r\n\t\t\t\t// 根据 maxLevel 判断是否还有下级\r\n\t\t\t\tif (it.areaLeve < props.maxLevel) {\r\n\t\t\t\t\tit.children = [];\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\titem.children = res.data;\r\n\t\t} else {\r\n\t\t\t// 没有下级数据,移除 children 属性使其成为叶子节点\r\n\t\t\tdelete item.children;\r\n\t\t}\r\n\t} catch (error) {\r\n\t\tconsole.error(\"加载下级地区失败:\", error);\r\n\t} finally {\r\n\t\titem._loading = false;\r\n\t}\r\n};\r\n\r\n// 选项变化时加载下级\r\nconst onChange = ({ value, selectedOptions, tabIndex }) => {\r\n\tconst currentItem = selectedOptions[tabIndex];\r\n\tif (currentItem && currentItem.areaLeve < props.maxLevel && Array.isArray(currentItem.children) && currentItem.children.length === 0) {\r\n\t\tloadChildren(currentItem);\r\n\t}\r\n\temit(\"change\", { value, selectedOptions, tabIndex });\r\n};\r\n\r\n// 完成选择\r\nconst onFinish = ({ selectedOptions }) => {\r\n\t// 根据 displayMode 决定显示值\r\n\tif (props.displayMode === \"last\") {\r\n\t\t// 只显示最后一级\r\n\t\tdisplayValue.value = selectedOptions[selectedOptions.length - 1]?.areaName || \"\";\r\n\t} else {\r\n\t\t// 显示完整路径(默认)\r\n\t\tdisplayValue.value = selectedOptions.map((option) => option.areaName).join(props.separator);\r\n\t}\r\n\r\n\t// 存储完整选中数据\r\n\tselectedData.value = selectedOptions.map((option) => ({\r\n\t\tareaCode: option.areaCode,\r\n\t\tareaName: option.areaName,\r\n\t\tareaLeve: option.areaLeve,\r\n\t}));\r\n\r\n\t// 根据 valueType 返回不同格式的值\r\n\tlet emitValue;\r\n\tswitch (props.valueType) {\r\n\t\tcase \"code\":\r\n\t\t\t// 返回最后一级的 areaCode\r\n\t\t\temitValue = selectedOptions[selectedOptions.length - 1]?.areaCode || \"\";\r\n\t\t\tbreak;\r\n\t\tcase \"codes\":\r\n\t\t\t// 返回所有级别的 areaCode 数组\r\n\t\t\temitValue = selectedOptions.map((option) => option.areaCode);\r\n\t\t\tbreak;\r\n\t\tcase \"object\":\r\n\t\t\t// 返回完整对象信息\r\n\t\t\temitValue = {\r\n\t\t\t\tcodes: selectedOptions.map((option) => option.areaCode),\r\n\t\t\t\tnames: selectedOptions.map((option) => option.areaName),\r\n\t\t\t\tfullName: selectedOptions.map((option) => option.areaName).join(props.separator),\r\n\t\t\t\tlastCode: selectedOptions[selectedOptions.length - 1]?.areaCode || \"\",\r\n\t\t\t\tlastLevel: selectedOptions[selectedOptions.length - 1]?.areaLeve,\r\n\t\t\t\toptions: selectedData.value,\r\n\t\t\t};\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\temitValue = selectedOptions[selectedOptions.length - 1]?.areaCode || \"\";\r\n\t}\r\n\r\n\temit(\"update:modelValue\", emitValue);\r\n\temit(\"finish\", { selectedOptions, value: emitValue });\r\n\tshow.value = false;\r\n};\r\n\r\n// 暴露方法供外部调用\r\ndefineExpose({\r\n\t// 获取当前选中的完整数据\r\n\tgetSelectedData: () => selectedData.value,\r\n\t// 获取显示值\r\n\tgetDisplayValue: () => displayValue.value,\r\n\t// 重置选择\r\n\treset: () => {\r\n\t\tdisplayValue.value = \"\";\r\n\t\tcascaderValue.value = \"\";\r\n\t\tselectedData.value = [];\r\n\t\temit(\"update:modelValue\", props.valueType === \"codes\" ? [] : props.valueType === \"object\" ? null : \"\");\r\n\t},\r\n\t// 打开选择器\r\n\topen: () => {\r\n\t\thandleClick();\r\n\t},\r\n\t// 关闭选择器\r\n\tclose: () => {\r\n\t\tshow.value = false;\r\n\t},\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped></style>\r\n","/**\r\n * Area 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Area from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nArea.install = (app, options = {}) => {\n if (options?.request) {\n app.provide('vant-vtk:request', options.request)\n app.config.globalProperties.$vtkRequest = options.request\n }\n app.component(Area.name || 'VtkArea', Area)\r\n}\r\n\r\nexport default Area\r\nexport { Area }\r\n","<template>\r\n\t<van-field v-bind=\"$attrs\">\r\n\t\t<template #input>\r\n\t\t\t<van-radio-group v-model=\"internalValue\" direction=\"horizontal\">\r\n\t\t\t\t<van-radio v-for=\"item in parsedOptions\" :key=\"String(item.value)\" :name=\"String(item.value)\">\r\n\t\t\t\t\t{{ item.text }}\r\n\t\t\t\t</van-radio>\r\n\t\t\t</van-radio-group>\r\n\t\t</template>\r\n\t</van-field>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkRadio\",\r\n});\r\nimport { computed } from \"vue\";\r\n\r\nconst props = defineProps({\r\n\t// 绑定值\r\n\tmodelValue: {\r\n\t\ttype: [String, Number, Object],\r\n\t\tdefault: \"\",\r\n\t},\r\n\t// 选项数据:支持数组 [{value, text}] 或 字符串 '1:选项1/2:选项2'\r\n\toptions: {\r\n\t\ttype: [Array, String],\r\n\t\tdefault: () => [],\r\n\t},\r\n\t// 返回值类型: 'string' (基本类型), 'object' (完整对象)\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"string\",\r\n\t\tvalidator: (val) => [\"string\", \"object\"].includes(val),\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\"]);\r\n\r\n// 解析选项\r\nconst parsedOptions = computed(() => {\r\n\tif (Array.isArray(props.options)) {\r\n\t\treturn props.options;\r\n\t}\r\n\tif (typeof props.options === \"string\" && props.options) {\r\n\t\treturn props.options\r\n\t\t\t.split(\"/\")\r\n\t\t\t.filter(Boolean)\r\n\t\t\t.map((item) => {\r\n\t\t\t\tconst [value, text] = item.split(\":\");\r\n\t\t\t\treturn {\r\n\t\t\t\t\ttext: text || value,\r\n\t\t\t\t\tvalue: value,\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t}\r\n\treturn [];\r\n});\r\n\r\n// 使用可写计算属性处理 v-model 绑定\r\nconst internalValue = computed({\r\n\tget: () => {\r\n\t\tconst val = props.modelValue;\r\n\t\tif (val === undefined || val === null) return \"\";\r\n\r\n\t\t// 如果是对象类型,提取其中的 value\r\n\t\tif (props.valueType === \"object\" && val && typeof val === \"object\") {\r\n\t\t\treturn String(val.value ?? \"\");\r\n\t\t}\r\n\t\treturn String(val);\r\n\t},\r\n\tset: (newValue) => {\r\n\t\tlet emitValue = newValue;\r\n\r\n\t\t// 处理原始数据类型逻辑(如果父组件传入的是数字,尝试转回数字)\r\n\t\tconst originalValue = props.valueType === \"object\" ? props.modelValue?.value : props.modelValue;\r\n\t\tif (typeof originalValue === \"number\" && !isNaN(Number(newValue))) {\r\n\t\t\temitValue = Number(newValue);\r\n\t\t}\r\n\r\n\t\tif (props.valueType === \"object\") {\r\n\t\t\t// 找回完整对象\r\n\t\t\temitValue = parsedOptions.value.find((opt) => String(opt.value) === String(newValue)) || null;\r\n\t\t}\r\n\r\n\t\temit(\"update:modelValue\", emitValue);\r\n\t\temit(\"change\", emitValue);\r\n\t},\r\n});\r\n</script>\r\n\r\n<style scoped>\r\n:deep(.van-radio) {\r\n\tmargin-right: 12px;\r\n}\r\n</style>\r\n","/**\r\n * Radio 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Radio from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nRadio.install = (app) => {\r\n app.component(Radio.name || 'VtkRadio', Radio)\r\n}\r\n\r\nexport default Radio\r\nexport { Radio }\r\n","<template>\r\n\t<van-uploader v-model=\"fileList\" v-bind=\"$attrs\" :max-size=\"maxSize\" :accept=\"accept\" :before-read=\"beforeRead\" :after-read=\"afterRead\" @delete=\"onDelete\" />\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkUploader\",\r\n\tinheritAttrs: false,\r\n});\r\nimport { ref, watch, inject, getCurrentInstance } from \"vue\";\r\nimport { showToast, showLoadingToast, closeToast } from \"vant\";\r\n\r\nconst injectedRequest = inject(\"vant-vtk:request\", null);\r\nconst globalProperties = getCurrentInstance()?.appContext.config.globalProperties;\r\nconst globalRequest = globalProperties?.$vtkRequest || globalProperties?.$request;\r\nconst getRequest = () => {\r\n\tconst request = injectedRequest || globalRequest;\r\n\tif (!request) {\r\n\t\tthrow new Error(\"VantVtk request 未配置\");\r\n\t}\r\n\treturn request;\r\n};\r\n\r\nconst props = defineProps({\r\n\t/** 绑定值,支持字符串或数组 */\r\n\tmodelValue: {\r\n\t\ttype: [String, Array],\r\n\t\tdefault: () => [],\r\n\t},\r\n\t/** 返回值类型:'string' 返回逗号分隔的字符串,'array' 返回数组 */\r\n\tvalueType: {\r\n\t\ttype: String,\r\n\t\tdefault: \"array\",\r\n\t\tvalidator: (val) => [\"string\", \"array\"].includes(val),\r\n\t},\r\n\t/** 单个文件最大大小(字节),默认10MB */\r\n\tmaxSize: {\r\n\t\ttype: Number,\r\n\t\tdefault: 10 * 1024 * 1024,\r\n\t},\r\n\t/** 接受的文件类型 */\r\n\taccept: {\r\n\t\ttype: String,\r\n\t\tdefault: \"image/*\",\r\n\t},\r\n\t/** 上传接口地址 */\r\n\tuploadUrl: {\r\n\t\ttype: String,\r\n\t\tdefault: \"/bizp/admin/upload\",\r\n\t},\r\n\t/** 上传文件的字段名 */\r\n\tfieldName: {\r\n\t\ttype: String,\r\n\t\tdefault: \"file\",\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"success\", \"error\"]);\r\n\r\n// 文件列表\r\nconst fileList = ref([]);\r\n\r\n// 解析初始值\r\nconst parseModelValue = (value) => {\r\n\tif (!value) return [];\r\n\r\n\tlet urls = [];\r\n\tif (typeof value === \"string\") {\r\n\t\turls = value.split(\",\").filter((url) => url.trim());\r\n\t} else if (Array.isArray(value)) {\r\n\t\turls = value.filter((url) => url);\r\n\t}\r\n\r\n\treturn urls.map((url) => ({\r\n\t\turl,\r\n\t\tstatus: \"done\",\r\n\t\tmessage: \"\",\r\n\t}));\r\n};\r\n\r\n// 获取已上传的URL列表\r\nconst getUploadedUrls = () => {\r\n\treturn fileList.value.filter((file) => file.status === \"done\" && file.url).map((file) => file.url);\r\n};\r\n\r\n// 格式化输出值\r\nconst formatOutput = (urls) => {\r\n\tif (props.valueType === \"string\") {\r\n\t\treturn urls.join(\",\");\r\n\t}\r\n\treturn urls;\r\n};\r\n\r\n// 触发更新\r\nconst emitValue = () => {\r\n\tconst urls = getUploadedUrls();\r\n\tconst output = formatOutput(urls);\r\n\temit(\"update:modelValue\", output);\r\n\temit(\"change\", output);\r\n};\r\n\r\n// 监听外部值变化\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(newVal) => {\r\n\t\tconst currentUrls = getUploadedUrls().join(\",\");\r\n\t\tconst newUrls = Array.isArray(newVal) ? newVal.join(\",\") : newVal || \"\";\r\n\r\n\t\t// 只有外部值确实改变时才更新\r\n\t\tif (currentUrls !== newUrls) {\r\n\t\t\tfileList.value = parseModelValue(newVal);\r\n\t\t}\r\n\t},\r\n\t{ immediate: true },\r\n);\r\n\r\n// 上传前校验\r\nconst beforeRead = (file) => {\r\n\tconst files = Array.isArray(file) ? file : [file];\r\n\r\n\tfor (const f of files) {\r\n\t\t// 文件大小校验\r\n\t\tif (f.size > props.maxSize) {\r\n\t\t\tconst maxSizeMB = (props.maxSize / 1024 / 1024).toFixed(1);\r\n\t\t\tshowToast(`文件大小不能超过${maxSizeMB}MB`);\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\treturn true;\r\n};\r\n\r\n// 上传文件\r\nconst uploadFile = async (file) => {\r\n\tconst formData = new FormData();\r\n\tformData.append(props.fieldName, file.file);\r\n\r\n\ttry {\r\n\t\tconst res = await getRequest().imp(props.uploadUrl, formData);\r\n\r\n\t\tif (res.meta?.success) {\r\n\t\t\t// 根据实际接口返回格式获取URL\r\n\t\t\tconst url = res.data?.url || res.data?.path || res.data;\r\n\t\t\treturn { success: true, url };\r\n\t\t} else {\r\n\t\t\treturn { success: false, message: res.meta?.message || \"上传失败\" };\r\n\t\t}\r\n\t} catch (error) {\r\n\t\treturn { success: false, message: error.message || \"上传失败\" };\r\n\t}\r\n};\r\n\r\n// 文件读取完成后处理\r\nconst afterRead = async (file) => {\r\n\tconst files = Array.isArray(file) ? file : [file];\r\n\r\n\t// 显示上传中提示\r\n\tif (files.length > 1) {\r\n\t\tshowLoadingToast({\r\n\t\t\tmessage: `正在上传 0/${files.length}`,\r\n\t\t\tforbidClick: true,\r\n\t\t\tduration: 0,\r\n\t\t});\r\n\t}\r\n\r\n\tlet successCount = 0;\r\n\tlet failCount = 0;\r\n\r\n\t// 逐个上传\r\n\tfor (let i = 0; i < files.length; i++) {\r\n\t\tconst fileItem = files[i];\r\n\t\tfileItem.status = \"uploading\";\r\n\t\tfileItem.message = \"上传中...\";\r\n\r\n\t\t// 更新进度提示\r\n\t\tif (files.length > 1) {\r\n\t\t\tshowLoadingToast({\r\n\t\t\t\tmessage: `正在上传 ${i + 1}/${files.length}`,\r\n\t\t\t\tforbidClick: true,\r\n\t\t\t\tduration: 0,\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tconst result = await uploadFile(fileItem);\r\n\r\n\t\tif (result.success) {\r\n\t\t\tfileItem.status = \"done\";\r\n\t\t\tfileItem.message = \"\";\r\n\t\t\tfileItem.url = result.url;\r\n\t\t\tsuccessCount++;\r\n\t\t\temit(\"success\", { file: fileItem, url: result.url });\r\n\t\t} else {\r\n\t\t\tfileItem.status = \"failed\";\r\n\t\t\tfileItem.message = result.message;\r\n\t\t\tfailCount++;\r\n\t\t\temit(\"error\", { file: fileItem, message: result.message });\r\n\t\t}\r\n\t}\r\n\r\n\tcloseToast();\r\n\r\n\t// 显示上传结果\r\n\tif (files.length > 1) {\r\n\t\tif (failCount === 0) {\r\n\t\t\tshowToast(`${successCount}个文件上传成功`);\r\n\t\t} else {\r\n\t\t\tshowToast(`${successCount}个成功,${failCount}个失败`);\r\n\t\t}\r\n\t} else if (failCount > 0) {\r\n\t\tshowToast(files[0].message || \"上传失败\");\r\n\t}\r\n\r\n\t// 触发值更新\r\n\temitValue();\r\n};\r\n\r\n// 删除文件\r\nconst onDelete = () => {\r\n\t// 下一个tick再触发,确保fileList已更新\r\n\tsetTimeout(() => {\r\n\t\temitValue();\r\n\t}, 0);\r\n};\r\n\r\n// 暴露方法给父组件\r\ndefineExpose({\r\n\t/** 获取已上传的URL列表 */\r\n\tgetUrls: getUploadedUrls,\r\n\t/** 清空文件列表 */\r\n\tclear: () => {\r\n\t\tfileList.value = [];\r\n\t\temitValue();\r\n\t},\r\n\t/** 获取文件列表 */\r\n\tgetFileList: () => fileList.value,\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n:deep(.van-uploader__preview-image) {\r\n\tborder-radius: 4px;\r\n}\r\n\r\n:deep(.van-uploader__upload) {\r\n\tborder-radius: 4px;\r\n}\r\n</style>\r\n","/**\r\n * Uploader 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Uploader from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nUploader.install = (app, options = {}) => {\n if (options?.request) {\n app.provide('vant-vtk:request', options.request)\n app.config.globalProperties.$vtkRequest = options.request\n }\n app.component(Uploader.name || 'VtkUploader', Uploader)\r\n}\r\n\r\nexport default Uploader\r\nexport { Uploader }\r\n","<template>\r\n\t<van-popup v-model:show=\"showPopup\" position=\"bottom\" :style=\"{ height: '100vh' }\">\r\n\t\t<div class=\"file-preview-container\">\r\n\t\t\t<div class=\"file-header\">\r\n\t\t\t\t<div class=\"file-title\">{{ currentFile?.name || \"文件预览\" }}</div>\r\n\t\t\t\t<van-icon name=\"cross\" size=\"20\" @click=\"handleClose\" />\r\n\t\t\t</div>\r\n\r\n\t\t\t<div class=\"file-content\">\r\n\t\t\t\t<div v-if=\"currentType === 'image'\" class=\"image-preview\">\r\n\t\t\t\t\t<van-image :src=\"currentFile?.url\" fit=\"contain\" class=\"preview-image\" />\r\n\t\t\t\t\t<div class=\"image-footer\">\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentIndex <= 0\" @click=\"prevFile\">上一个</van-button>\r\n\t\t\t\t\t\t<span class=\"file-info\">{{ currentIndex + 1 }} / {{ files.length }}</span>\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\">下一个</van-button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<div v-else-if=\"currentType === 'pdf'\" class=\"pdf-preview\">\r\n\t\t\t\t\t<VuePdfEmbed v-if=\"pdfSource\" :source=\"pdfSource\" :page=\"currentPage\" class=\"pdf-embed-preview\" @rendered=\"handlePdfRendered\" @loaded=\"handlePdfLoaded\" />\r\n\t\t\t\t\t<div v-else class=\"pdf-placeholder\">请选择PDF文件</div>\r\n\t\t\t\t\t<div class=\"pdf-footer\">\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"currentPage <= 1\" @click=\"currentPage--\">上一页</van-button>\r\n\t\t\t\t\t\t<span class=\"page-info\">第 {{ currentPage }} / {{ totalPages || \"?\" }} 页</span>\r\n\t\t\t\t\t\t<van-button size=\"small\" :disabled=\"!pdfSource || currentPage >= totalPages\" @click=\"currentPage++\">下一页</van-button>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<div class=\"footer\">\r\n\t\t\t\t\t<van-button :disabled=\"currentIndex <= 0\" @click=\"prevFile\" icon=\"arrow-left\" type=\"primary\" round />\r\n\t\t\t\t\t<van-button :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\" icon=\"arrow\" type=\"primary\" round />\r\n\t\t\t\t\t<!-- <van-button size=\"small\" :disabled=\"currentIndex <= 0\" @click=\"prevFile\">上一个</van-button>\r\n <span class=\"file-info\">{{ currentIndex + 1 }} / {{ files.length }}</span>\r\n <van-button size=\"small\" :disabled=\"currentIndex >= files.length - 1\" @click=\"nextFile\">下一个</van-button> -->\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</van-popup>\r\n</template>\r\n\r\n<script setup>\r\ndefineOptions({\r\n\tname: \"VtkPreview\",\r\n});\r\nimport { ref, watch, computed } from \"vue\";\r\nimport VuePdfEmbed from \"vue-pdf-embed\";\r\n\r\nconst props = defineProps({\r\n\tmodelValue: {\r\n\t\ttype: Boolean,\r\n\t\tdefault: false,\r\n\t},\r\n\tfiles: {\r\n\t\ttype: Array,\r\n\t\tdefault: () => [],\r\n\t},\r\n\tstartIndex: {\r\n\t\ttype: Number,\r\n\t\tdefault: 0,\r\n\t},\r\n});\r\n\r\nconst emit = defineEmits([\"update:modelValue\", \"close\"]);\r\n\r\nconst showPopup = ref(props.modelValue);\r\nconst currentIndex = ref(props.startIndex);\r\nconst currentPage = ref(1);\r\nconst pdfSource = ref(null);\r\nconst totalPages = ref(0);\r\n\r\nconst normalizedFiles = computed(() => {\r\n\treturn props.files.map((file, index) => {\r\n\t\tif (typeof file === \"string\") {\r\n\t\t\tconst isPdf = file.toLowerCase().endsWith(\".pdf\");\r\n\t\t\treturn {\r\n\t\t\t\tname: isPdf ? `文档${index + 1}.pdf` : `图片${index + 1}`,\r\n\t\t\t\turl: file,\r\n\t\t\t\ttype: isPdf ? \"pdf\" : \"image\",\r\n\t\t\t};\r\n\t\t}\r\n\t\treturn file;\r\n\t});\r\n});\r\n\r\nconst currentFile = computed(() => {\r\n\treturn normalizedFiles.value[currentIndex.value] || null;\r\n});\r\n\r\nconst currentType = computed(() => {\r\n\tif (!currentFile.value) return null;\r\n\tconst url = currentFile.value.url || currentFile.value;\r\n\tif (typeof url === \"string\") {\r\n\t\treturn url.toLowerCase().endsWith(\".pdf\") ? \"pdf\" : \"image\";\r\n\t}\r\n\treturn currentFile.value.type || \"image\";\r\n});\r\n\r\nwatch(\r\n\t() => props.modelValue,\r\n\t(val) => {\r\n\t\tshowPopup.value = val;\r\n\t\tif (val && normalizedFiles.value.length > 0) {\r\n\t\t\tcurrentIndex.value = props.startIndex;\r\n\t\t\tupdatePreview();\r\n\t\t}\r\n\t},\r\n);\r\n\r\nwatch(\r\n\t() => props.startIndex,\r\n\t(val) => {\r\n\t\tcurrentIndex.value = val;\r\n\t\tupdatePreview();\r\n\t},\r\n);\r\n\r\nwatch(showPopup, (val) => {\r\n\temit(\"update:modelValue\", val);\r\n\tif (!val) {\r\n\t\thandleClose();\r\n\t}\r\n});\r\n\r\nwatch(currentIndex, () => {\r\n\tcurrentPage.value = 1;\r\n\ttotalPages.value = 0;\r\n\tupdatePreview();\r\n});\r\n\r\nconst updatePreview = () => {\r\n\tconst file = currentFile.value;\r\n\tif (!file) return;\r\n\r\n\tif (currentType.value === \"pdf\") {\r\n\t\tpdfSource.value = file.url || file;\r\n\t} else {\r\n\t\tpdfSource.value = null;\r\n\t}\r\n};\r\n\r\nconst handlePdfLoaded = (pdf) => {\r\n\ttotalPages.value = pdf.numPages || 0;\r\n};\r\n\r\nconst handlePdfRendered = () => {\r\n\tconsole.log(\"PDF rendered successfully\");\r\n};\r\n\r\nconst prevFile = () => {\r\n\tif (currentIndex.value > 0) {\r\n\t\tcurrentIndex.value--;\r\n\t}\r\n};\r\n\r\nconst nextFile = () => {\r\n\tif (currentIndex.value < normalizedFiles.value.length - 1) {\r\n\t\tcurrentIndex.value++;\r\n\t}\r\n};\r\n\r\nconst handleClose = () => {\r\n\tshowPopup.value = false;\r\n\tpdfSource.value = null;\r\n\tcurrentPage.value = 1;\r\n\ttotalPages.value = 0;\r\n\temit(\"close\");\r\n};\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.file-preview-container {\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\theight: 100%;\r\n\tbackground-color: #fff;\r\n\tborder-radius: 8px;\r\n\toverflow: hidden;\r\n}\r\n\r\n.file-header {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: space-between;\r\n\tpadding: 12px 16px;\r\n\tborder-bottom: 1px solid #ebedf0;\r\n\tbackground-color: #f7f8fa;\r\n}\r\n\r\n.file-title {\r\n\tfont-size: 16px;\r\n\tfont-weight: 600;\r\n\tcolor: #323233;\r\n}\r\n\r\n.file-content {\r\n\tflex: 1;\r\n\toverflow: hidden;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n}\r\n\r\n.image-preview {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\toverflow: hidden;\r\n}\r\n\r\n.preview-image {\r\n\tflex: 1;\r\n\twidth: 100%;\r\n\theight: 100%;\r\n}\r\n\r\n.image-footer {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 16px;\r\n\tpadding: 12px 16px;\r\n\tborder-top: 1px solid #ebedf0;\r\n\tbackground-color: #fff;\r\n}\r\n\r\n.file-info {\r\n\tfont-size: 14px;\r\n\tcolor: #646566;\r\n\tmin-width: 80px;\r\n\ttext-align: center;\r\n}\r\n\r\n.pdf-preview {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\toverflow: hidden;\r\n}\r\n\r\n.pdf-embed-preview {\r\n\tflex: 1;\r\n\tmax-width: 100%;\r\n\toverflow-y: auto;\r\n\tpadding: 16px;\r\n\tdisplay: flex;\r\n\tjustify-content: center;\r\n\talign-items: flex-start;\r\n\tbackground-color: #f5f5f5;\r\n\tbox-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n.pdf-placeholder {\r\n\tflex: 1;\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tcolor: #969799;\r\n\tfont-size: 14px;\r\n}\r\n\r\n.pdf-footer {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: 16px;\r\n\tpadding: 12px 16px;\r\n\tborder-top: 1px solid #ebedf0;\r\n\tbackground-color: #fff;\r\n}\r\n\r\n.page-info {\r\n\tfont-size: 14px;\r\n\tcolor: #646566;\r\n\tmin-width: 80px;\r\n\ttext-align: center;\r\n}\r\n.footer {\r\n\tposition: fixed;\r\n\ttop: 40%;\r\n\twidth: 100%;\r\n\t.van-button {\r\n\t}\r\n\t.van-button:nth-child(2) {\r\n\t\tfloat: right;\r\n\t}\r\n}\r\n</style>\r\n","/**\r\n * Preview 组件单独导出入口\r\n * 支持按需引入\r\n */\r\nimport Preview from './index.vue'\r\n\r\n// 为组件添加 install 方法,支持 app.use() 方式注册\r\nPreview.install = (app) => {\r\n app.component(Preview.name || 'VtkPreview', Preview)\r\n}\r\n\r\nexport default Preview\r\nexport { Preview }\r\n","/**\r\n * Vant-VTK 组件库全量导出入口\r\n * 支持全量引入和按需引入\r\n */\r\nimport Checkbox from '../packages/checkbox/index.js'\r\nimport Area from '../packages/Area/index.js'\r\nimport Radio from '../packages/Radio/index.js'\r\nimport Uploader from '../packages/Uploader/index.js'\r\nimport Preview from '../packages/preview/index.js'\r\n\r\n\r\n\r\n// 所有组件列表\r\nconst components = [\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n]\r\n\r\n// 全量注册方法\r\nconst install = (app, options = {}) => {\n if (options?.request) {\n app.provide('vant-vtk:request', options.request)\n app.config.globalProperties.$vtkRequest = options.request\n }\n\n components.forEach(component => {\r\n if (component.install) {\r\n app.use(component, options)\n } else if (component.name) {\r\n app.component(component.name, component)\r\n }\r\n })\r\n}\r\n\r\n// 默认导出 - 支持 app.use(VantVtk) 全量注册\r\nexport default {\r\n install,\r\n // 也导出所有组件,方便直接访问\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n}\r\n\r\n// 具名导出 - 支持按需引入\r\nexport {\r\n install,\r\n Checkbox,\r\n Area,\r\n Radio,\r\n Uploader,\r\n Preview\r\n}\r\n\r\n// 导出版本号\r\nexport const version = '1.0.0'\r\n"],"names":["props","__props","emit","__emit","parsedOptions","computed","item","value","text","internalValue","val","arr","newValues","emitValue","opt","_openBlock","_createBlock","_component_van_field","$attrs","_createVNode","_component_van_checkbox_group","$event","_createElementBlock","_Fragment","_renderList","_component_van_checkbox","_createTextVNode","_toDisplayString","Checkbox","app","injectedRequest","inject","globalProperties","getCurrentInstance","globalRequest","getRequest","request","show","ref","cascaderValue","options","displayValue","loading","selectedData","fieldNames","watch","handleClick","loadInitialArea","areaCode","res","rootArea","error","loadChildren","it","onChange","selectedOptions","tabIndex","currentItem","onFinish","_a","option","_b","_c","_d","_e","__expose","_mergeProps","_component_van_popup","_component_van_cascader","Area","newValue","_component_van_radio_group","_component_van_radio","Radio","fileList","parseModelValue","urls","url","getUploadedUrls","file","formatOutput","output","newVal","currentUrls","newUrls","beforeRead","files","f","maxSizeMB","showToast","uploadFile","formData","afterRead","showLoadingToast","successCount","failCount","i","fileItem","result","closeToast","onDelete","_component_van_uploader","Uploader","showPopup","currentIndex","currentPage","pdfSource","totalPages","normalizedFiles","index","isPdf","currentFile","currentType","updatePreview","handleClose","handlePdfLoaded","pdf","handlePdfRendered","prevFile","nextFile","_createElementVNode","_hoisted_1","_hoisted_2","_hoisted_3","_component_van_icon","_hoisted_4","_hoisted_5","_component_van_image","_hoisted_6","_component_van_button","_cache","_hoisted_7","_hoisted_8","_unref","VuePdfEmbed","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","Preview","components","install","component","version"],"mappings":"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"}