fix
This commit is contained in:
1 parent
757de9a43f
commit
3950057707
17 files changed
+2678
-199
No files matched your search
@@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
|
"configVersion": 0,
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
"": {
|
"": {
|
||||||
"name": "my-vue-app",
|
"name": "my-vue-app",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ag-grid-community/locale": "^35.1.0",
|
"@ag-grid-community/locale": "^35.1.0",
|
||||||
|
"@iconify/vue": "^5.0.0",
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"@vueuse/core": "^14.2.1",
|
"@vueuse/core": "^14.2.1",
|
||||||
"ag-grid-community": "^35.1.0",
|
"ag-grid-community": "^35.1.0",
|
||||||
@@ -13,8 +15,10 @@
|
|||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"decimal.js": "^10.6.0",
|
"decimal.js": "^10.6.0",
|
||||||
|
"exceljs": "^4.4.0",
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"lucide-vue-next": "^0.563.0",
|
"lucide-vue-next": "^0.563.0",
|
||||||
|
"motion-v": "^2.0.0",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
"pinia-plugin-persistedstate": "^4.7.1",
|
"pinia-plugin-persistedstate": "^4.7.1",
|
||||||
"reka-ui": "^2.8.0",
|
"reka-ui": "^2.8.0",
|
||||||
@@ -52,6 +56,10 @@
|
|||||||
|
|
||||||
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
|
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
|
||||||
|
|
||||||
|
"@fast-csv/format": ["@fast-csv/format@4.3.5", "", { "dependencies": { "@types/node": "^14.0.1", "lodash.escaperegexp": "^4.1.2", "lodash.isboolean": "^3.0.3", "lodash.isequal": "^4.5.0", "lodash.isfunction": "^3.0.9", "lodash.isnil": "^4.0.0" } }, "sha512-8iRn6QF3I8Ak78lNAa+Gdl5MJJBM5vRHivFtMRUWINdevNo00K7OXxS2PshawLKTejVwieIlPmK5YlLu6w4u8A=="],
|
||||||
|
|
||||||
|
"@fast-csv/parse": ["@fast-csv/parse@4.3.6", "", { "dependencies": { "@types/node": "^14.0.1", "lodash.escaperegexp": "^4.1.2", "lodash.groupby": "^4.6.0", "lodash.isfunction": "^3.0.9", "lodash.isnil": "^4.0.0", "lodash.isundefined": "^3.0.1", "lodash.uniq": "^4.5.0" } }, "sha512-uRsLYksqpbDmWaSmzvJcuApSEe38+6NQZBUsuAyMZKqHxH0g1wcJgsKUvN3WC8tewaqFjBMMGrkHmC+T7k8LvA=="],
|
||||||
|
|
||||||
"@floating-ui/core": ["@floating-ui/core@1.7.4", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg=="],
|
"@floating-ui/core": ["@floating-ui/core@1.7.4", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg=="],
|
||||||
|
|
||||||
"@floating-ui/dom": ["@floating-ui/dom@1.7.5", "", { "dependencies": { "@floating-ui/core": "^1.7.4", "@floating-ui/utils": "^0.2.10" } }, "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg=="],
|
"@floating-ui/dom": ["@floating-ui/dom@1.7.5", "", { "dependencies": { "@floating-ui/core": "^1.7.4", "@floating-ui/utils": "^0.2.10" } }, "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg=="],
|
||||||
@@ -60,6 +68,10 @@
|
|||||||
|
|
||||||
"@floating-ui/vue": ["@floating-ui/vue@1.1.10", "", { "dependencies": { "@floating-ui/dom": "^1.7.5", "@floating-ui/utils": "^0.2.10", "vue-demi": ">=0.13.0" } }, "sha512-vdf8f6rHnFPPLRsmL4p12wYl+Ux4mOJOkjzKEMYVnwdf7UFdvBtHlLvQyx8iKG5vhPRbDRgZxdtpmyigDPjzYg=="],
|
"@floating-ui/vue": ["@floating-ui/vue@1.1.10", "", { "dependencies": { "@floating-ui/dom": "^1.7.5", "@floating-ui/utils": "^0.2.10", "vue-demi": ">=0.13.0" } }, "sha512-vdf8f6rHnFPPLRsmL4p12wYl+Ux4mOJOkjzKEMYVnwdf7UFdvBtHlLvQyx8iKG5vhPRbDRgZxdtpmyigDPjzYg=="],
|
||||||
|
|
||||||
|
"@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="],
|
||||||
|
|
||||||
|
"@iconify/vue": ["@iconify/vue@5.0.0", "", { "dependencies": { "@iconify/types": "^2.0.0" }, "peerDependencies": { "vue": ">=3" } }, "sha512-C+KuEWIF5nSBrobFJhT//JS87OZ++QDORB6f2q2Wm6fl2mueSTpFBeBsveK0KW9hWiZ4mNiPjsh6Zs4jjdROSg=="],
|
||||||
|
|
||||||
"@internationalized/date": ["@internationalized/date@3.11.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-BOx5huLAWhicM9/ZFs84CzP+V3gBW6vlpM02yzsdYC7TGlZJX1OJiEEHcSayF00Z+3jLlm4w79amvSt6RqKN3Q=="],
|
"@internationalized/date": ["@internationalized/date@3.11.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-BOx5huLAWhicM9/ZFs84CzP+V3gBW6vlpM02yzsdYC7TGlZJX1OJiEEHcSayF00Z+3jLlm4w79amvSt6RqKN3Q=="],
|
||||||
|
|
||||||
"@internationalized/number": ["@internationalized/number@3.6.5", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g=="],
|
"@internationalized/number": ["@internationalized/number@3.6.5", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g=="],
|
||||||
@@ -212,46 +224,120 @@
|
|||||||
|
|
||||||
"alien-signals": ["alien-signals@3.1.2", "", {}, "sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw=="],
|
"alien-signals": ["alien-signals@3.1.2", "", {}, "sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw=="],
|
||||||
|
|
||||||
|
"archiver": ["archiver@5.3.2", "", { "dependencies": { "archiver-utils": "^2.1.0", "async": "^3.2.4", "buffer-crc32": "^0.2.1", "readable-stream": "^3.6.0", "readdir-glob": "^1.1.2", "tar-stream": "^2.2.0", "zip-stream": "^4.1.0" } }, "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw=="],
|
||||||
|
|
||||||
|
"archiver-utils": ["archiver-utils@2.1.0", "", { "dependencies": { "glob": "^7.1.4", "graceful-fs": "^4.2.0", "lazystream": "^1.0.0", "lodash.defaults": "^4.2.0", "lodash.difference": "^4.5.0", "lodash.flatten": "^4.4.0", "lodash.isplainobject": "^4.0.6", "lodash.union": "^4.6.0", "normalize-path": "^3.0.0", "readable-stream": "^2.0.0" } }, "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw=="],
|
||||||
|
|
||||||
"aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
|
"aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
|
||||||
|
|
||||||
|
"async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
|
||||||
|
|
||||||
|
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
|
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
|
||||||
|
|
||||||
|
"big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="],
|
||||||
|
|
||||||
|
"binary": ["binary@0.3.0", "", { "dependencies": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" } }, "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg=="],
|
||||||
|
|
||||||
"birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="],
|
"birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="],
|
||||||
|
|
||||||
|
"bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
|
||||||
|
|
||||||
|
"bluebird": ["bluebird@3.4.7", "", {}, "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA=="],
|
||||||
|
|
||||||
|
"brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||||
|
|
||||||
|
"buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
||||||
|
|
||||||
|
"buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
|
||||||
|
|
||||||
|
"buffer-indexof-polyfill": ["buffer-indexof-polyfill@1.0.2", "", {}, "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A=="],
|
||||||
|
|
||||||
|
"buffers": ["buffers@0.1.1", "", {}, "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ=="],
|
||||||
|
|
||||||
"bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
|
"bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
|
||||||
|
|
||||||
|
"chainsaw": ["chainsaw@0.1.0", "", { "dependencies": { "traverse": ">=0.3.0 <0.4" } }, "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ=="],
|
||||||
|
|
||||||
"class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
|
"class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="],
|
||||||
|
|
||||||
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||||
|
|
||||||
|
"compress-commons": ["compress-commons@4.1.2", "", { "dependencies": { "buffer-crc32": "^0.2.13", "crc32-stream": "^4.0.2", "normalize-path": "^3.0.0", "readable-stream": "^3.6.0" } }, "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg=="],
|
||||||
|
|
||||||
|
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||||
|
|
||||||
"copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="],
|
"copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="],
|
||||||
|
|
||||||
|
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
|
||||||
|
|
||||||
|
"crc-32": ["crc-32@1.2.2", "", { "bin": { "crc32": "bin/crc32.njs" } }, "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="],
|
||||||
|
|
||||||
|
"crc32-stream": ["crc32-stream@4.0.3", "", { "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" } }, "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw=="],
|
||||||
|
|
||||||
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||||
|
|
||||||
|
"dayjs": ["dayjs@1.11.19", "", {}, "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="],
|
||||||
|
|
||||||
"decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="],
|
"decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="],
|
||||||
|
|
||||||
"defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
|
"defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
|
||||||
|
|
||||||
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||||
|
|
||||||
|
"duplexer2": ["duplexer2@0.1.4", "", { "dependencies": { "readable-stream": "^2.0.2" } }, "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA=="],
|
||||||
|
|
||||||
|
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
||||||
|
|
||||||
"enhanced-resolve": ["enhanced-resolve@5.19.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg=="],
|
"enhanced-resolve": ["enhanced-resolve@5.19.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg=="],
|
||||||
|
|
||||||
"entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="],
|
"entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="],
|
||||||
|
|
||||||
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
|
|
||||||
|
"exceljs": ["exceljs@4.4.0", "", { "dependencies": { "archiver": "^5.0.0", "dayjs": "^1.8.34", "fast-csv": "^4.3.1", "jszip": "^3.10.1", "readable-stream": "^3.6.0", "saxes": "^5.0.1", "tmp": "^0.2.0", "unzipper": "^0.10.11", "uuid": "^8.3.0" } }, "sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg=="],
|
||||||
|
|
||||||
|
"fast-csv": ["fast-csv@4.3.6", "", { "dependencies": { "@fast-csv/format": "4.3.5", "@fast-csv/parse": "4.3.6" } }, "sha512-2RNSpuwwsJGP0frGsOmTb9oUF+VkFSM4SyLTDgwf2ciHWTarN0lQTC+F2f/t5J9QjW+c65VFIAAu85GsvMIusw=="],
|
||||||
|
|
||||||
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||||
|
|
||||||
|
"framer-motion": ["framer-motion@12.34.3", "", { "dependencies": { "motion-dom": "^12.34.3", "motion-utils": "^12.29.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-v81ecyZKYO/DfpTwHivqkxSUBzvceOpoI+wLfgCgoUIKxlFKEXdg0oR9imxwXumT4SFy8vRk9xzJ5l3/Du/55Q=="],
|
||||||
|
|
||||||
|
"fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
|
||||||
|
|
||||||
|
"fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
|
||||||
|
|
||||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
|
"fstream": ["fstream@1.0.12", "", { "dependencies": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", "mkdirp": ">=0.5 0", "rimraf": "2" } }, "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg=="],
|
||||||
|
|
||||||
|
"glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
|
||||||
|
|
||||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||||
|
|
||||||
|
"hey-listen": ["hey-listen@1.0.8", "", {}, "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="],
|
||||||
|
|
||||||
"hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
|
"hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
|
||||||
|
|
||||||
|
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||||
|
|
||||||
"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
|
"immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="],
|
||||||
|
|
||||||
|
"inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="],
|
||||||
|
|
||||||
|
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||||
|
|
||||||
"is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="],
|
"is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="],
|
||||||
|
|
||||||
|
"isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
|
||||||
|
|
||||||
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
|
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
|
||||||
|
|
||||||
|
"jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="],
|
||||||
|
|
||||||
|
"lazystream": ["lazystream@1.0.1", "", { "dependencies": { "readable-stream": "^2.0.5" } }, "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw=="],
|
||||||
|
|
||||||
"lie": ["lie@3.1.1", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw=="],
|
"lie": ["lie@3.1.1", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw=="],
|
||||||
|
|
||||||
"lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
|
"lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
|
||||||
@@ -278,22 +364,68 @@
|
|||||||
|
|
||||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
|
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
|
||||||
|
|
||||||
|
"listenercount": ["listenercount@1.0.1", "", {}, "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ=="],
|
||||||
|
|
||||||
"localforage": ["localforage@1.10.0", "", { "dependencies": { "lie": "3.1.1" } }, "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg=="],
|
"localforage": ["localforage@1.10.0", "", { "dependencies": { "lie": "3.1.1" } }, "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg=="],
|
||||||
|
|
||||||
|
"lodash.defaults": ["lodash.defaults@4.2.0", "", {}, "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="],
|
||||||
|
|
||||||
|
"lodash.difference": ["lodash.difference@4.5.0", "", {}, "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA=="],
|
||||||
|
|
||||||
|
"lodash.escaperegexp": ["lodash.escaperegexp@4.1.2", "", {}, "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="],
|
||||||
|
|
||||||
|
"lodash.flatten": ["lodash.flatten@4.4.0", "", {}, "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g=="],
|
||||||
|
|
||||||
|
"lodash.groupby": ["lodash.groupby@4.6.0", "", {}, "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw=="],
|
||||||
|
|
||||||
|
"lodash.isboolean": ["lodash.isboolean@3.0.3", "", {}, "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="],
|
||||||
|
|
||||||
|
"lodash.isequal": ["lodash.isequal@4.5.0", "", {}, "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="],
|
||||||
|
|
||||||
|
"lodash.isfunction": ["lodash.isfunction@3.0.9", "", {}, "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw=="],
|
||||||
|
|
||||||
|
"lodash.isnil": ["lodash.isnil@4.0.0", "", {}, "sha512-up2Mzq3545mwVnMhTDMdfoG1OurpA/s5t88JmQX809eH3C8491iu2sfKhTfhQtKY78oPNhiaHJUpT/dUDAAtng=="],
|
||||||
|
|
||||||
|
"lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="],
|
||||||
|
|
||||||
|
"lodash.isundefined": ["lodash.isundefined@3.0.1", "", {}, "sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA=="],
|
||||||
|
|
||||||
|
"lodash.union": ["lodash.union@4.6.0", "", {}, "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw=="],
|
||||||
|
|
||||||
|
"lodash.uniq": ["lodash.uniq@4.5.0", "", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="],
|
||||||
|
|
||||||
"lucide-vue-next": ["lucide-vue-next@0.563.0", "", { "peerDependencies": { "vue": ">=3.0.1" } }, "sha512-zsE/lCKtmaa7bGfhSpN84br1K9YoQ5pCN+2oKWjQQG3Lo6ufUUKBuHSjNFI6RvUevxaajNXb8XwFUKeTXG3sIA=="],
|
"lucide-vue-next": ["lucide-vue-next@0.563.0", "", { "peerDependencies": { "vue": ">=3.0.1" } }, "sha512-zsE/lCKtmaa7bGfhSpN84br1K9YoQ5pCN+2oKWjQQG3Lo6ufUUKBuHSjNFI6RvUevxaajNXb8XwFUKeTXG3sIA=="],
|
||||||
|
|
||||||
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||||
|
|
||||||
|
"minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="],
|
||||||
|
|
||||||
"mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="],
|
"mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="],
|
||||||
|
|
||||||
|
"mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
|
||||||
|
|
||||||
|
"motion-dom": ["motion-dom@12.34.3", "", { "dependencies": { "motion-utils": "^12.29.2" } }, "sha512-sYgFe+pR9aIM7o4fhs2aXtOI+oqlUd33N9Yoxcgo1Fv7M20sRkHtCmzE/VRNIcq7uNJ+qio+Xubt1FXH3pQ+eQ=="],
|
||||||
|
|
||||||
|
"motion-utils": ["motion-utils@12.29.2", "", {}, "sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A=="],
|
||||||
|
|
||||||
|
"motion-v": ["motion-v@2.0.0", "", { "dependencies": { "framer-motion": "^12.29.2", "hey-listen": "^1.0.8", "motion-dom": "^12.29.2", "motion-utils": "^12.29.2" }, "peerDependencies": { "@vueuse/core": ">=10.0.0", "vue": ">=3.0.0" } }, "sha512-oQuQMrPhti+Zps6OosOaW3b/eqzaGAuwI54XHJKq/dIWtQWcNzfyhTo4VB5xmp7yLN+3BE9FKF6skLsynfgbHQ=="],
|
||||||
|
|
||||||
"muggle-string": ["muggle-string@0.4.1", "", {}, "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ=="],
|
"muggle-string": ["muggle-string@0.4.1", "", {}, "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ=="],
|
||||||
|
|
||||||
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|
||||||
|
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
|
||||||
|
|
||||||
"ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="],
|
"ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="],
|
||||||
|
|
||||||
|
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
|
||||||
|
|
||||||
|
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
|
||||||
|
|
||||||
"path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="],
|
"path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="],
|
||||||
|
|
||||||
|
"path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
|
||||||
|
|
||||||
"perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="],
|
"perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="],
|
||||||
|
|
||||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
@@ -306,18 +438,34 @@
|
|||||||
|
|
||||||
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||||
|
|
||||||
|
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
|
||||||
|
|
||||||
|
"readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||||
|
|
||||||
|
"readdir-glob": ["readdir-glob@1.1.3", "", { "dependencies": { "minimatch": "^5.1.0" } }, "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA=="],
|
||||||
|
|
||||||
"reka-ui": ["reka-ui@2.8.2", "", { "dependencies": { "@floating-ui/dom": "^1.6.13", "@floating-ui/vue": "^1.1.6", "@internationalized/date": "^3.5.0", "@internationalized/number": "^3.5.0", "@tanstack/vue-virtual": "^3.12.0", "@vueuse/core": "^14.1.0", "@vueuse/shared": "^14.1.0", "aria-hidden": "^1.2.4", "defu": "^6.1.4", "ohash": "^2.0.11" }, "peerDependencies": { "vue": ">= 3.2.0" } }, "sha512-8lTKcJhmG+D3UyJxhBnNnW/720sLzm0pbA9AC1MWazmJ5YchJAyTSl+O00xP/kxBmEN0fw5JqWVHguiFmsGjzA=="],
|
"reka-ui": ["reka-ui@2.8.2", "", { "dependencies": { "@floating-ui/dom": "^1.6.13", "@floating-ui/vue": "^1.1.6", "@internationalized/date": "^3.5.0", "@internationalized/number": "^3.5.0", "@tanstack/vue-virtual": "^3.12.0", "@vueuse/core": "^14.1.0", "@vueuse/shared": "^14.1.0", "aria-hidden": "^1.2.4", "defu": "^6.1.4", "ohash": "^2.0.11" }, "peerDependencies": { "vue": ">= 3.2.0" } }, "sha512-8lTKcJhmG+D3UyJxhBnNnW/720sLzm0pbA9AC1MWazmJ5YchJAyTSl+O00xP/kxBmEN0fw5JqWVHguiFmsGjzA=="],
|
||||||
|
|
||||||
"rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
|
"rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
|
||||||
|
|
||||||
|
"rimraf": ["rimraf@2.7.1", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w=="],
|
||||||
|
|
||||||
"rolldown": ["rolldown@1.0.0-rc.5", "", { "dependencies": { "@oxc-project/types": "=0.114.0", "@rolldown/pluginutils": "1.0.0-rc.5" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.5", "@rolldown/binding-darwin-arm64": "1.0.0-rc.5", "@rolldown/binding-darwin-x64": "1.0.0-rc.5", "@rolldown/binding-freebsd-x64": "1.0.0-rc.5", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.5", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.5", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.5", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.5", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.5", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.5", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.5", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.5", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.5" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-0AdalTs6hNTioaCYIkAa7+xsmHBfU5hCNclZnM/lp7lGGDuUOb6N4BVNtwiomybbencDjq/waKjTImqiGCs5sw=="],
|
"rolldown": ["rolldown@1.0.0-rc.5", "", { "dependencies": { "@oxc-project/types": "=0.114.0", "@rolldown/pluginutils": "1.0.0-rc.5" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.5", "@rolldown/binding-darwin-arm64": "1.0.0-rc.5", "@rolldown/binding-darwin-x64": "1.0.0-rc.5", "@rolldown/binding-freebsd-x64": "1.0.0-rc.5", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.5", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.5", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.5", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.5", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.5", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.5", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.5", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.5", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.5" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-0AdalTs6hNTioaCYIkAa7+xsmHBfU5hCNclZnM/lp7lGGDuUOb6N4BVNtwiomybbencDjq/waKjTImqiGCs5sw=="],
|
||||||
|
|
||||||
|
"safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
|
||||||
|
|
||||||
|
"saxes": ["saxes@5.0.1", "", { "dependencies": { "xmlchars": "^2.2.0" } }, "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw=="],
|
||||||
|
|
||||||
|
"setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="],
|
||||||
|
|
||||||
"sortablejs": ["sortablejs@1.14.0", "", {}, "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="],
|
"sortablejs": ["sortablejs@1.14.0", "", {}, "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="],
|
||||||
|
|
||||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
|
|
||||||
"speakingurl": ["speakingurl@14.0.1", "", {}, "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="],
|
"speakingurl": ["speakingurl@14.0.1", "", {}, "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="],
|
||||||
|
|
||||||
|
"string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
|
||||||
|
|
||||||
"superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="],
|
"superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="],
|
||||||
|
|
||||||
"tailwind-merge": ["tailwind-merge@3.5.0", "", {}, "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A=="],
|
"tailwind-merge": ["tailwind-merge@3.5.0", "", {}, "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A=="],
|
||||||
@@ -326,8 +474,14 @@
|
|||||||
|
|
||||||
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
|
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
|
||||||
|
|
||||||
|
"tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
|
||||||
|
|
||||||
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
||||||
|
|
||||||
|
"tmp": ["tmp@0.2.5", "", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="],
|
||||||
|
|
||||||
|
"traverse": ["traverse@0.3.9", "", {}, "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ=="],
|
||||||
|
|
||||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
"tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
|
"tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
|
||||||
@@ -336,6 +490,12 @@
|
|||||||
|
|
||||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||||
|
|
||||||
|
"unzipper": ["unzipper@0.10.14", "", { "dependencies": { "big-integer": "^1.6.17", "binary": "~0.3.0", "bluebird": "~3.4.1", "buffer-indexof-polyfill": "~1.0.0", "duplexer2": "~0.1.4", "fstream": "^1.0.12", "graceful-fs": "^4.2.2", "listenercount": "~1.0.1", "readable-stream": "~2.3.6", "setimmediate": "~1.0.4" } }, "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g=="],
|
||||||
|
|
||||||
|
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||||
|
|
||||||
|
"uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
|
||||||
|
|
||||||
"vite": ["vite@8.0.0-beta.15", "", { "dependencies": { "@oxc-project/runtime": "0.114.0", "lightningcss": "^1.31.1", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rolldown": "1.0.0-rc.5", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.0.0-alpha.31", "esbuild": "^0.27.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-RHX7IvsJlEfjyA1rS7MY0UsmF91etdLAamslHR5lfuO3W/BXRdXm2tRE64ztpSPZbKqB4wAAZ0AwtF6QzfKZLA=="],
|
"vite": ["vite@8.0.0-beta.15", "", { "dependencies": { "@oxc-project/runtime": "0.114.0", "lightningcss": "^1.31.1", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rolldown": "1.0.0-rc.5", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.0.0-alpha.31", "esbuild": "^0.27.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-RHX7IvsJlEfjyA1rS7MY0UsmF91etdLAamslHR5lfuO3W/BXRdXm2tRE64ztpSPZbKqB4wAAZ0AwtF6QzfKZLA=="],
|
||||||
|
|
||||||
"vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="],
|
"vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="],
|
||||||
@@ -348,6 +508,16 @@
|
|||||||
|
|
||||||
"vuedraggable": ["vuedraggable@4.1.0", "", { "dependencies": { "sortablejs": "1.14.0" }, "peerDependencies": { "vue": "^3.0.1" } }, "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww=="],
|
"vuedraggable": ["vuedraggable@4.1.0", "", { "dependencies": { "sortablejs": "1.14.0" }, "peerDependencies": { "vue": "^3.0.1" } }, "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww=="],
|
||||||
|
|
||||||
|
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
||||||
|
|
||||||
|
"xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="],
|
||||||
|
|
||||||
|
"zip-stream": ["zip-stream@4.1.1", "", { "dependencies": { "archiver-utils": "^3.0.4", "compress-commons": "^4.1.2", "readable-stream": "^3.6.0" } }, "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ=="],
|
||||||
|
|
||||||
|
"@fast-csv/format/@types/node": ["@types/node@14.18.63", "", {}, "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ=="],
|
||||||
|
|
||||||
|
"@fast-csv/parse/@types/node": ["@types/node@14.18.63", "", {}, "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
|
||||||
@@ -360,6 +530,36 @@
|
|||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"archiver-utils/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
||||||
|
|
||||||
|
"duplexer2/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
||||||
|
|
||||||
|
"glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||||
|
|
||||||
|
"jszip/lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
|
||||||
|
|
||||||
|
"jszip/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
||||||
|
|
||||||
|
"lazystream/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
||||||
|
|
||||||
"rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.5", "", {}, "sha512-RxlLX/DPoarZ9PtxVrQgZhPoor987YtKQqCo5zkjX+0S0yLJ7Vv515Wk6+xtTL67VONKJKxETWZwuZjss2idYw=="],
|
"rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.5", "", {}, "sha512-RxlLX/DPoarZ9PtxVrQgZhPoor987YtKQqCo5zkjX+0S0yLJ7Vv515Wk6+xtTL67VONKJKxETWZwuZjss2idYw=="],
|
||||||
|
|
||||||
|
"string_decoder/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||||
|
|
||||||
|
"unzipper/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
||||||
|
|
||||||
|
"zip-stream/archiver-utils": ["archiver-utils@3.0.4", "", { "dependencies": { "glob": "^7.2.3", "graceful-fs": "^4.2.0", "lazystream": "^1.0.0", "lodash.defaults": "^4.2.0", "lodash.difference": "^4.5.0", "lodash.flatten": "^4.4.0", "lodash.isplainobject": "^4.0.6", "lodash.union": "^4.6.0", "normalize-path": "^3.0.0", "readable-stream": "^3.6.0" } }, "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw=="],
|
||||||
|
|
||||||
|
"archiver-utils/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
||||||
|
|
||||||
|
"duplexer2/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
||||||
|
|
||||||
|
"glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||||
|
|
||||||
|
"jszip/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
||||||
|
|
||||||
|
"lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
||||||
|
|
||||||
|
"unzipper/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ag-grid-community/locale": "^35.1.0",
|
"@ag-grid-community/locale": "^35.1.0",
|
||||||
|
"@iconify/vue": "^5.0.0",
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"@vueuse/core": "^14.2.1",
|
"@vueuse/core": "^14.2.1",
|
||||||
"ag-grid-community": "^35.1.0",
|
"ag-grid-community": "^35.1.0",
|
||||||
@@ -19,8 +20,10 @@
|
|||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"decimal.js": "^10.6.0",
|
"decimal.js": "^10.6.0",
|
||||||
|
"exceljs": "^4.4.0",
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"lucide-vue-next": "^0.563.0",
|
"lucide-vue-next": "^0.563.0",
|
||||||
|
"motion-v": "^2.0.0",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
"pinia-plugin-persistedstate": "^4.7.1",
|
"pinia-plugin-persistedstate": "^4.7.1",
|
||||||
"reka-ui": "^2.8.0",
|
"reka-ui": "^2.8.0",
|
||||||
|
|||||||
@@ -10,6 +10,14 @@ import { useTabStore } from '@/pinia/tab'
|
|||||||
import { ArrowUp, Edit3, GripVertical, MoreHorizontal, Plus, Trash2, X } from 'lucide-vue-next'
|
import { ArrowUp, Edit3, GripVertical, MoreHorizontal, Plus, Trash2, X } from 'lucide-vue-next'
|
||||||
import { decodeZwArchive, encodeZwArchive } from '@/lib/zwArchive'
|
import { decodeZwArchive, encodeZwArchive } from '@/lib/zwArchive'
|
||||||
import {
|
import {
|
||||||
|
AlertDialogAction,
|
||||||
|
AlertDialogCancel,
|
||||||
|
AlertDialogContent,
|
||||||
|
AlertDialogDescription,
|
||||||
|
AlertDialogOverlay,
|
||||||
|
AlertDialogPortal,
|
||||||
|
AlertDialogRoot,
|
||||||
|
AlertDialogTitle,
|
||||||
ToastAction,
|
ToastAction,
|
||||||
ToastDescription,
|
ToastDescription,
|
||||||
ToastProvider,
|
ToastProvider,
|
||||||
@@ -64,6 +72,8 @@ const editingContractId = ref<string | null>(null)
|
|||||||
const toastOpen = ref(false)
|
const toastOpen = ref(false)
|
||||||
const toastTitle = ref('操作成功')
|
const toastTitle = ref('操作成功')
|
||||||
const toastText = ref('')
|
const toastText = ref('')
|
||||||
|
const deleteConfirmOpen = ref(false)
|
||||||
|
const pendingDeleteContractId = ref<string | null>(null)
|
||||||
const modalOffset = ref({ x: 0, y: 0 })
|
const modalOffset = ref({ x: 0, y: 0 })
|
||||||
let dragStartX = 0
|
let dragStartX = 0
|
||||||
let dragStartY = 0
|
let dragStartY = 0
|
||||||
@@ -125,6 +135,30 @@ const notify = (text: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pendingDeleteContractName = computed(() => {
|
||||||
|
if (!pendingDeleteContractId.value) return ''
|
||||||
|
const target = contracts.value.find(item => item.id === pendingDeleteContractId.value)
|
||||||
|
return target?.name || pendingDeleteContractId.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleDeleteConfirmOpenChange = (open: boolean) => {
|
||||||
|
deleteConfirmOpen.value = open
|
||||||
|
if (!open) pendingDeleteContractId.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestDeleteContract = (id: string) => {
|
||||||
|
pendingDeleteContractId.value = id
|
||||||
|
deleteConfirmOpen.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmDeleteContract = async () => {
|
||||||
|
const id = pendingDeleteContractId.value
|
||||||
|
if (!id) return
|
||||||
|
await deleteContract(id)
|
||||||
|
deleteConfirmOpen.value = false
|
||||||
|
pendingDeleteContractId.value = null
|
||||||
|
}
|
||||||
|
|
||||||
const closeContractDataMenu = () => {
|
const closeContractDataMenu = () => {
|
||||||
contractDataMenuOpen.value = false
|
contractDataMenuOpen.value = false
|
||||||
}
|
}
|
||||||
@@ -945,7 +979,7 @@ onBeforeUnmount(() => {
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
:class="[isListLayout ? 'h-6 w-6' : 'h-7 w-7', 'text-destructive']"
|
:class="[isListLayout ? 'h-6 w-6' : 'h-7 w-7', 'text-destructive']"
|
||||||
@click.stop="deleteContract(element.id)"
|
@click.stop="requestDeleteContract(element.id)"
|
||||||
>
|
>
|
||||||
<Trash2 :class="isListLayout ? 'h-3.5 w-3.5' : 'h-4 w-4'" />
|
<Trash2 :class="isListLayout ? 'h-3.5 w-3.5' : 'h-4 w-4'" />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -1063,7 +1097,7 @@ onBeforeUnmount(() => {
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
:class="[isListLayout ? 'h-6 w-6' : 'h-7 w-7', 'text-destructive']"
|
:class="[isListLayout ? 'h-6 w-6' : 'h-7 w-7', 'text-destructive']"
|
||||||
@click.stop="deleteContract(element.id)"
|
@click.stop="requestDeleteContract(element.id)"
|
||||||
>
|
>
|
||||||
<Trash2 :class="isListLayout ? 'h-3.5 w-3.5' : 'h-4 w-4'" />
|
<Trash2 :class="isListLayout ? 'h-3.5 w-3.5' : 'h-4 w-4'" />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -1150,6 +1184,25 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<AlertDialogRoot :open="deleteConfirmOpen" @update:open="handleDeleteConfirmOpenChange">
|
||||||
|
<AlertDialogPortal>
|
||||||
|
<AlertDialogOverlay class="fixed inset-0 z-50 bg-black/45" />
|
||||||
|
<AlertDialogContent class="fixed left-1/2 top-1/2 z-[70] w-[92vw] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg border bg-background p-5 shadow-xl">
|
||||||
|
<AlertDialogTitle class="text-base font-semibold">确认删除合同段</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription class="mt-2 text-sm text-muted-foreground">
|
||||||
|
即将删除“{{ pendingDeleteContractName }}”及其关联咨询服务和计价数据,是否继续?
|
||||||
|
</AlertDialogDescription>
|
||||||
|
<div class="mt-4 flex items-center justify-end gap-2">
|
||||||
|
<AlertDialogCancel as-child>
|
||||||
|
<Button variant="outline">取消</Button>
|
||||||
|
</AlertDialogCancel>
|
||||||
|
<AlertDialogAction as-child>
|
||||||
|
<Button variant="destructive" @click="confirmDeleteContract">确认删除</Button>
|
||||||
|
</AlertDialogAction>
|
||||||
|
</div>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialogPortal>
|
||||||
|
</AlertDialogRoot>
|
||||||
<ToastRoot
|
<ToastRoot
|
||||||
v-model:open="toastOpen"
|
v-model:open="toastOpen"
|
||||||
:duration="1800"
|
:duration="1800"
|
||||||
|
|||||||
@@ -40,13 +40,27 @@ const DB_KEY = computed(() => `hourlyPricing-${props.contractId}-${props.service
|
|||||||
const PRICING_CLEAR_SKIP_PREFIX = 'pricing-clear-skip:'
|
const PRICING_CLEAR_SKIP_PREFIX = 'pricing-clear-skip:'
|
||||||
const PRICING_FORCE_DEFAULT_PREFIX = 'pricing-force-default:'
|
const PRICING_FORCE_DEFAULT_PREFIX = 'pricing-force-default:'
|
||||||
const pricingPaneReloadStore = usePricingPaneReloadStore()
|
const pricingPaneReloadStore = usePricingPaneReloadStore()
|
||||||
|
const paneInstanceCreatedAt = Date.now()
|
||||||
|
|
||||||
const shouldSkipPersist = () => {
|
const shouldSkipPersist = () => {
|
||||||
const storageKey = `${PRICING_CLEAR_SKIP_PREFIX}${DB_KEY.value}`
|
const storageKey = `${PRICING_CLEAR_SKIP_PREFIX}${DB_KEY.value}`
|
||||||
const raw = sessionStorage.getItem(storageKey)
|
const raw = sessionStorage.getItem(storageKey)
|
||||||
if (!raw) return false
|
if (!raw) return false
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
|
if (raw.includes(':')) {
|
||||||
|
const [issuedRaw, untilRaw] = raw.split(':')
|
||||||
|
const issuedAt = Number(issuedRaw)
|
||||||
|
const skipUntil = Number(untilRaw)
|
||||||
|
if (Number.isFinite(issuedAt) && Number.isFinite(skipUntil) && now <= skipUntil) {
|
||||||
|
return paneInstanceCreatedAt <= issuedAt
|
||||||
|
}
|
||||||
|
sessionStorage.removeItem(storageKey)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const skipUntil = Number(raw)
|
const skipUntil = Number(raw)
|
||||||
if (Number.isFinite(skipUntil) && Date.now() <= skipUntil) return true
|
if (Number.isFinite(skipUntil) && now <= skipUntil) return true
|
||||||
sessionStorage.removeItem(storageKey)
|
sessionStorage.removeItem(storageKey)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,18 @@ import { formatThousands } from '@/lib/numberFormat'
|
|||||||
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
||||||
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
||||||
import { loadConsultCategoryFactorMap, loadMajorFactorMap } from '@/lib/xmFactorDefaults'
|
import { loadConsultCategoryFactorMap, loadMajorFactorMap } from '@/lib/xmFactorDefaults'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import {
|
||||||
|
AlertDialogAction,
|
||||||
|
AlertDialogCancel,
|
||||||
|
AlertDialogContent,
|
||||||
|
AlertDialogDescription,
|
||||||
|
AlertDialogOverlay,
|
||||||
|
AlertDialogPortal,
|
||||||
|
AlertDialogRoot,
|
||||||
|
AlertDialogTitle,
|
||||||
|
AlertDialogTrigger,
|
||||||
|
} from 'reka-ui'
|
||||||
|
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale';
|
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale';
|
||||||
// 精简的边框配置(细线条+浅灰色,弱化分割线视觉)
|
// 精简的边框配置(细线条+浅灰色,弱化分割线视觉)
|
||||||
@@ -59,14 +71,14 @@ const pricingPaneReloadStore = usePricingPaneReloadStore()
|
|||||||
const consultCategoryFactorMap = ref<Map<string, number | null>>(new Map())
|
const consultCategoryFactorMap = ref<Map<string, number | null>>(new Map())
|
||||||
const majorFactorMap = ref<Map<string, number | null>>(new Map())
|
const majorFactorMap = ref<Map<string, number | null>>(new Map())
|
||||||
let factorDefaultsLoaded = false
|
let factorDefaultsLoaded = false
|
||||||
|
const paneInstanceCreatedAt = Date.now()
|
||||||
|
|
||||||
const getDefaultConsultCategoryFactor = () =>
|
const getDefaultConsultCategoryFactor = () =>
|
||||||
consultCategoryFactorMap.value.get(String(props.serviceId)) ?? null
|
consultCategoryFactorMap.value.get(String(props.serviceId)) ?? null
|
||||||
|
|
||||||
const getDefaultMajorFactorById = (id: string): number | null => majorFactorMap.value.get(id) ?? null
|
const getDefaultMajorFactorById = (id: string): number | null => majorFactorMap.value.get(id) ?? null
|
||||||
|
|
||||||
const ensureFactorDefaultsLoaded = async () => {
|
const loadFactorDefaults = async () => {
|
||||||
if (factorDefaultsLoaded) return
|
|
||||||
const [consultMap, majorMap] = await Promise.all([
|
const [consultMap, majorMap] = await Promise.all([
|
||||||
loadConsultCategoryFactorMap(),
|
loadConsultCategoryFactorMap(),
|
||||||
loadMajorFactorMap()
|
loadMajorFactorMap()
|
||||||
@@ -76,12 +88,30 @@ const ensureFactorDefaultsLoaded = async () => {
|
|||||||
factorDefaultsLoaded = true
|
factorDefaultsLoaded = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ensureFactorDefaultsLoaded = async () => {
|
||||||
|
if (factorDefaultsLoaded) return
|
||||||
|
await loadFactorDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
const shouldSkipPersist = () => {
|
const shouldSkipPersist = () => {
|
||||||
const storageKey = `${PRICING_CLEAR_SKIP_PREFIX}${DB_KEY.value}`
|
const storageKey = `${PRICING_CLEAR_SKIP_PREFIX}${DB_KEY.value}`
|
||||||
const raw = sessionStorage.getItem(storageKey)
|
const raw = sessionStorage.getItem(storageKey)
|
||||||
if (!raw) return false
|
if (!raw) return false
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
|
if (raw.includes(':')) {
|
||||||
|
const [issuedRaw, untilRaw] = raw.split(':')
|
||||||
|
const issuedAt = Number(issuedRaw)
|
||||||
|
const skipUntil = Number(untilRaw)
|
||||||
|
if (Number.isFinite(issuedAt) && Number.isFinite(skipUntil) && now <= skipUntil) {
|
||||||
|
return paneInstanceCreatedAt <= issuedAt
|
||||||
|
}
|
||||||
|
sessionStorage.removeItem(storageKey)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const skipUntil = Number(raw)
|
const skipUntil = Number(raw)
|
||||||
if (Number.isFinite(skipUntil) && Date.now() <= skipUntil) return true
|
if (Number.isFinite(skipUntil) && now <= skipUntil) return true
|
||||||
sessionStorage.removeItem(storageKey)
|
sessionStorage.removeItem(storageKey)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -165,8 +195,8 @@ const buildDefaultRows = (): DetailRow[] => {
|
|||||||
majorName: child.name,
|
majorName: child.name,
|
||||||
amount: null,
|
amount: null,
|
||||||
benchmarkBudget: null,
|
benchmarkBudget: null,
|
||||||
consultCategoryFactor: getDefaultConsultCategoryFactor(),
|
consultCategoryFactor: null,
|
||||||
majorFactor: getDefaultMajorFactorById(child.id),
|
majorFactor: null,
|
||||||
budgetFee: null,
|
budgetFee: null,
|
||||||
remark: '',
|
remark: '',
|
||||||
path: [group.id, child.id]
|
path: [group.id, child.id]
|
||||||
@@ -177,7 +207,12 @@ const buildDefaultRows = (): DetailRow[] => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SourceRow = Pick<DetailRow, 'id'> & Partial<Pick<DetailRow, 'amount' | 'benchmarkBudget' | 'consultCategoryFactor' | 'majorFactor' | 'budgetFee' | 'remark'>>
|
type SourceRow = Pick<DetailRow, 'id'> & Partial<Pick<DetailRow, 'amount' | 'benchmarkBudget' | 'consultCategoryFactor' | 'majorFactor' | 'budgetFee' | 'remark'>>
|
||||||
const mergeWithDictRows = (rowsFromDb: SourceRow[] | undefined): DetailRow[] => {
|
const mergeWithDictRows = (
|
||||||
|
rowsFromDb: SourceRow[] | undefined,
|
||||||
|
options?: { includeAmount?: boolean; includeFactorValues?: boolean }
|
||||||
|
): DetailRow[] => {
|
||||||
|
const includeAmount = options?.includeAmount ?? true
|
||||||
|
const includeFactorValues = options?.includeFactorValues ?? true
|
||||||
const dbValueMap = new Map<string, SourceRow>()
|
const dbValueMap = new Map<string, SourceRow>()
|
||||||
for (const row of rowsFromDb || []) {
|
for (const row of rowsFromDb || []) {
|
||||||
dbValueMap.set(row.id, row)
|
dbValueMap.set(row.id, row)
|
||||||
@@ -191,20 +226,24 @@ const mergeWithDictRows = (rowsFromDb: SourceRow[] | undefined): DetailRow[] =>
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...row,
|
...row,
|
||||||
amount: typeof fromDb.amount === 'number' ? fromDb.amount : null,
|
amount: includeAmount && typeof fromDb.amount === 'number' ? fromDb.amount : null,
|
||||||
benchmarkBudget: typeof fromDb.benchmarkBudget === 'number' ? fromDb.benchmarkBudget : null,
|
benchmarkBudget: typeof fromDb.benchmarkBudget === 'number' ? fromDb.benchmarkBudget : null,
|
||||||
consultCategoryFactor:
|
consultCategoryFactor:
|
||||||
typeof fromDb.consultCategoryFactor === 'number'
|
!includeFactorValues
|
||||||
? fromDb.consultCategoryFactor
|
? null
|
||||||
: hasConsultCategoryFactor
|
: typeof fromDb.consultCategoryFactor === 'number'
|
||||||
? null
|
? fromDb.consultCategoryFactor
|
||||||
: getDefaultConsultCategoryFactor(),
|
: hasConsultCategoryFactor
|
||||||
|
? null
|
||||||
|
: getDefaultConsultCategoryFactor(),
|
||||||
majorFactor:
|
majorFactor:
|
||||||
typeof fromDb.majorFactor === 'number'
|
!includeFactorValues
|
||||||
? fromDb.majorFactor
|
? null
|
||||||
: hasMajorFactor
|
: typeof fromDb.majorFactor === 'number'
|
||||||
? null
|
? fromDb.majorFactor
|
||||||
: getDefaultMajorFactorById(row.id),
|
: hasMajorFactor
|
||||||
|
? null
|
||||||
|
: getDefaultMajorFactorById(row.id),
|
||||||
budgetFee: typeof fromDb.budgetFee === 'number' ? fromDb.budgetFee : null,
|
budgetFee: typeof fromDb.budgetFee === 'number' ? fromDb.budgetFee : null,
|
||||||
remark: typeof fromDb.remark === 'string' ? fromDb.remark : ''
|
remark: typeof fromDb.remark === 'string' ? fromDb.remark : ''
|
||||||
}
|
}
|
||||||
@@ -226,21 +265,10 @@ const formatEditableNumber = (params: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const formatConsultCategoryFactor = (params: any) => {
|
const formatConsultCategoryFactor = (params: any) => {
|
||||||
if (params.node?.group) {
|
|
||||||
const v = getDefaultConsultCategoryFactor()
|
|
||||||
if (v == null) return ''
|
|
||||||
return Number(v).toFixed(2)
|
|
||||||
}
|
|
||||||
return formatEditableNumber(params)
|
return formatEditableNumber(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatMajorFactor = (params: any) => {
|
const formatMajorFactor = (params: any) => {
|
||||||
if (params.node?.group) {
|
|
||||||
const groupId = String(params.node?.key || '')
|
|
||||||
const v = getDefaultMajorFactorById(groupId)
|
|
||||||
if (v == null) return ''
|
|
||||||
return Number(v).toFixed(2)
|
|
||||||
}
|
|
||||||
return formatEditableNumber(params)
|
return formatEditableNumber(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,10 +466,13 @@ const saveToIndexedDB = async () => {
|
|||||||
|
|
||||||
const loadFromIndexedDB = async () => {
|
const loadFromIndexedDB = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
await ensureFactorDefaultsLoaded()
|
await ensureFactorDefaultsLoaded()
|
||||||
if (shouldForceDefaultLoad()) {
|
if (shouldForceDefaultLoad()) {
|
||||||
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
||||||
detailRows.value = htData?.detailRows ? mergeWithDictRows(htData.detailRows) : buildDefaultRows()
|
detailRows.value = htData?.detailRows
|
||||||
|
? mergeWithDictRows(htData.detailRows, { includeAmount: false, includeFactorValues: false })
|
||||||
|
: buildDefaultRows()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +484,7 @@ const loadFromIndexedDB = async () => {
|
|||||||
|
|
||||||
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
||||||
if (htData?.detailRows) {
|
if (htData?.detailRows) {
|
||||||
detailRows.value = mergeWithDictRows(htData.detailRows)
|
detailRows.value = mergeWithDictRows(htData.detailRows, { includeAmount: false, includeFactorValues: false })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,6 +495,25 @@ const loadFromIndexedDB = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const importContractData = async () => {
|
||||||
|
try {
|
||||||
|
// 使用默认数据时,强制读取最新的项目系数(预算取值优先,空值回退标准系数)
|
||||||
|
await loadFactorDefaults()
|
||||||
|
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
||||||
|
const hasContractRows = Array.isArray(htData?.detailRows) && htData.detailRows.length > 0
|
||||||
|
detailRows.value = hasContractRows
|
||||||
|
? mergeWithDictRows(htData!.detailRows, { includeFactorValues: true })
|
||||||
|
: buildDefaultRows().map(row => ({
|
||||||
|
...row,
|
||||||
|
consultCategoryFactor: getDefaultConsultCategoryFactor(),
|
||||||
|
majorFactor: getDefaultMajorFactorById(row.id)
|
||||||
|
}))
|
||||||
|
await saveToIndexedDB()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('importContractData failed:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => pricingPaneReloadStore.getReloadVersion(props.contractId, props.serviceId),
|
() => pricingPaneReloadStore.getReloadVersion(props.contractId, props.serviceId),
|
||||||
(nextVersion, prevVersion) => {
|
(nextVersion, prevVersion) => {
|
||||||
@@ -521,7 +571,28 @@ const processCellFromClipboard = (params: any) => {
|
|||||||
<div class="rounded-lg border bg-card xmMx flex min-h-0 flex-1 flex-col">
|
<div class="rounded-lg border bg-card xmMx flex min-h-0 flex-1 flex-col">
|
||||||
<div class="flex items-center justify-between border-b px-4 py-3">
|
<div class="flex items-center justify-between border-b px-4 py-3">
|
||||||
<h3 class="text-sm font-semibold text-foreground">投资规模明细</h3>
|
<h3 class="text-sm font-semibold text-foreground">投资规模明细</h3>
|
||||||
<div class="text-xs text-muted-foreground">导入导出</div>
|
<AlertDialogRoot>
|
||||||
|
<AlertDialogTrigger as-child>
|
||||||
|
<Button type="button" variant="outline" size="sm">使用默认数据</Button>
|
||||||
|
</AlertDialogTrigger>
|
||||||
|
<AlertDialogPortal>
|
||||||
|
<AlertDialogOverlay class="fixed inset-0 z-50 bg-black/45" />
|
||||||
|
<AlertDialogContent class="fixed left-1/2 top-1/2 z-50 w-[92vw] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg border bg-background p-5 shadow-xl">
|
||||||
|
<AlertDialogTitle class="text-base font-semibold">确认覆盖当前明细</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription class="mt-2 text-sm text-muted-foreground">
|
||||||
|
将使用合同默认数据覆盖当前投资规模明细,是否继续?
|
||||||
|
</AlertDialogDescription>
|
||||||
|
<div class="mt-4 flex items-center justify-end gap-2">
|
||||||
|
<AlertDialogCancel as-child>
|
||||||
|
<Button variant="outline">取消</Button>
|
||||||
|
</AlertDialogCancel>
|
||||||
|
<AlertDialogAction as-child>
|
||||||
|
<Button @click="importContractData">确认覆盖</Button>
|
||||||
|
</AlertDialogAction>
|
||||||
|
</div>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialogPortal>
|
||||||
|
</AlertDialogRoot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
||||||
|
|||||||
@@ -10,6 +10,18 @@ import { formatThousands } from '@/lib/numberFormat'
|
|||||||
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
import { syncPricingTotalToZxFw, ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
||||||
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
||||||
import { loadConsultCategoryFactorMap, loadMajorFactorMap } from '@/lib/xmFactorDefaults'
|
import { loadConsultCategoryFactorMap, loadMajorFactorMap } from '@/lib/xmFactorDefaults'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import {
|
||||||
|
AlertDialogAction,
|
||||||
|
AlertDialogCancel,
|
||||||
|
AlertDialogContent,
|
||||||
|
AlertDialogDescription,
|
||||||
|
AlertDialogOverlay,
|
||||||
|
AlertDialogPortal,
|
||||||
|
AlertDialogRoot,
|
||||||
|
AlertDialogTitle,
|
||||||
|
AlertDialogTrigger,
|
||||||
|
} from 'reka-ui'
|
||||||
|
|
||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale';
|
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale';
|
||||||
// 精简的边框配置(细线条+浅灰色,弱化分割线视觉)
|
// 精简的边框配置(细线条+浅灰色,弱化分割线视觉)
|
||||||
@@ -60,6 +72,7 @@ const pricingPaneReloadStore = usePricingPaneReloadStore()
|
|||||||
const consultCategoryFactorMap = ref<Map<string, number | null>>(new Map())
|
const consultCategoryFactorMap = ref<Map<string, number | null>>(new Map())
|
||||||
const majorFactorMap = ref<Map<string, number | null>>(new Map())
|
const majorFactorMap = ref<Map<string, number | null>>(new Map())
|
||||||
let factorDefaultsLoaded = false
|
let factorDefaultsLoaded = false
|
||||||
|
const paneInstanceCreatedAt = Date.now()
|
||||||
|
|
||||||
const detailRows = ref<DetailRow[]>([])
|
const detailRows = ref<DetailRow[]>([])
|
||||||
const getDefaultConsultCategoryFactor = () =>
|
const getDefaultConsultCategoryFactor = () =>
|
||||||
@@ -67,8 +80,7 @@ const getDefaultConsultCategoryFactor = () =>
|
|||||||
|
|
||||||
const getDefaultMajorFactorById = (id: string): number | null => majorFactorMap.value.get(id) ?? null
|
const getDefaultMajorFactorById = (id: string): number | null => majorFactorMap.value.get(id) ?? null
|
||||||
|
|
||||||
const ensureFactorDefaultsLoaded = async () => {
|
const loadFactorDefaults = async () => {
|
||||||
if (factorDefaultsLoaded) return
|
|
||||||
const [consultMap, majorMap] = await Promise.all([
|
const [consultMap, majorMap] = await Promise.all([
|
||||||
loadConsultCategoryFactorMap(),
|
loadConsultCategoryFactorMap(),
|
||||||
loadMajorFactorMap()
|
loadMajorFactorMap()
|
||||||
@@ -78,6 +90,11 @@ const ensureFactorDefaultsLoaded = async () => {
|
|||||||
factorDefaultsLoaded = true
|
factorDefaultsLoaded = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ensureFactorDefaultsLoaded = async () => {
|
||||||
|
if (factorDefaultsLoaded) return
|
||||||
|
await loadFactorDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
const shouldForceDefaultLoad = () => {
|
const shouldForceDefaultLoad = () => {
|
||||||
const storageKey = `${PRICING_FORCE_DEFAULT_PREFIX}${DB_KEY.value}`
|
const storageKey = `${PRICING_FORCE_DEFAULT_PREFIX}${DB_KEY.value}`
|
||||||
const raw = sessionStorage.getItem(storageKey)
|
const raw = sessionStorage.getItem(storageKey)
|
||||||
@@ -91,8 +108,21 @@ const shouldSkipPersist = () => {
|
|||||||
const storageKey = `${PRICING_CLEAR_SKIP_PREFIX}${DB_KEY.value}`
|
const storageKey = `${PRICING_CLEAR_SKIP_PREFIX}${DB_KEY.value}`
|
||||||
const raw = sessionStorage.getItem(storageKey)
|
const raw = sessionStorage.getItem(storageKey)
|
||||||
if (!raw) return false
|
if (!raw) return false
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
|
if (raw.includes(':')) {
|
||||||
|
const [issuedRaw, untilRaw] = raw.split(':')
|
||||||
|
const issuedAt = Number(issuedRaw)
|
||||||
|
const skipUntil = Number(untilRaw)
|
||||||
|
if (Number.isFinite(issuedAt) && Number.isFinite(skipUntil) && now <= skipUntil) {
|
||||||
|
return paneInstanceCreatedAt <= issuedAt
|
||||||
|
}
|
||||||
|
sessionStorage.removeItem(storageKey)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const skipUntil = Number(raw)
|
const skipUntil = Number(raw)
|
||||||
if (Number.isFinite(skipUntil) && Date.now() <= skipUntil) return true
|
if (Number.isFinite(skipUntil) && now <= skipUntil) return true
|
||||||
sessionStorage.removeItem(storageKey)
|
sessionStorage.removeItem(storageKey)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -167,8 +197,8 @@ const buildDefaultRows = (): DetailRow[] => {
|
|||||||
amount: null,
|
amount: null,
|
||||||
landArea: null,
|
landArea: null,
|
||||||
benchmarkBudget: null,
|
benchmarkBudget: null,
|
||||||
consultCategoryFactor: getDefaultConsultCategoryFactor(),
|
consultCategoryFactor: null,
|
||||||
majorFactor: getDefaultMajorFactorById(child.id),
|
majorFactor: null,
|
||||||
budgetFee: null,
|
budgetFee: null,
|
||||||
remark: '',
|
remark: '',
|
||||||
path: [group.id, child.id]
|
path: [group.id, child.id]
|
||||||
@@ -179,7 +209,12 @@ const buildDefaultRows = (): DetailRow[] => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SourceRow = Pick<DetailRow, 'id'> & Partial<Pick<DetailRow, 'amount' | 'landArea' | 'benchmarkBudget' | 'consultCategoryFactor' | 'majorFactor' | 'budgetFee' | 'remark'>>
|
type SourceRow = Pick<DetailRow, 'id'> & Partial<Pick<DetailRow, 'amount' | 'landArea' | 'benchmarkBudget' | 'consultCategoryFactor' | 'majorFactor' | 'budgetFee' | 'remark'>>
|
||||||
const mergeWithDictRows = (rowsFromDb: SourceRow[] | undefined): DetailRow[] => {
|
const mergeWithDictRows = (
|
||||||
|
rowsFromDb: SourceRow[] | undefined,
|
||||||
|
options?: { includeScaleValues?: boolean; includeFactorValues?: boolean }
|
||||||
|
): DetailRow[] => {
|
||||||
|
const includeScaleValues = options?.includeScaleValues ?? true
|
||||||
|
const includeFactorValues = options?.includeFactorValues ?? true
|
||||||
const dbValueMap = new Map<string, SourceRow>()
|
const dbValueMap = new Map<string, SourceRow>()
|
||||||
for (const row of rowsFromDb || []) {
|
for (const row of rowsFromDb || []) {
|
||||||
dbValueMap.set(row.id, row)
|
dbValueMap.set(row.id, row)
|
||||||
@@ -193,21 +228,25 @@ const mergeWithDictRows = (rowsFromDb: SourceRow[] | undefined): DetailRow[] =>
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...row,
|
...row,
|
||||||
amount: typeof fromDb.amount === 'number' ? fromDb.amount : null,
|
amount: includeScaleValues && typeof fromDb.amount === 'number' ? fromDb.amount : null,
|
||||||
landArea: typeof fromDb.landArea === 'number' ? fromDb.landArea : null,
|
landArea: includeScaleValues && typeof fromDb.landArea === 'number' ? fromDb.landArea : null,
|
||||||
benchmarkBudget: typeof fromDb.benchmarkBudget === 'number' ? fromDb.benchmarkBudget : null,
|
benchmarkBudget: typeof fromDb.benchmarkBudget === 'number' ? fromDb.benchmarkBudget : null,
|
||||||
consultCategoryFactor:
|
consultCategoryFactor:
|
||||||
typeof fromDb.consultCategoryFactor === 'number'
|
!includeFactorValues
|
||||||
? fromDb.consultCategoryFactor
|
? null
|
||||||
: hasConsultCategoryFactor
|
: typeof fromDb.consultCategoryFactor === 'number'
|
||||||
? null
|
? fromDb.consultCategoryFactor
|
||||||
: getDefaultConsultCategoryFactor(),
|
: hasConsultCategoryFactor
|
||||||
|
? null
|
||||||
|
: getDefaultConsultCategoryFactor(),
|
||||||
majorFactor:
|
majorFactor:
|
||||||
typeof fromDb.majorFactor === 'number'
|
!includeFactorValues
|
||||||
? fromDb.majorFactor
|
? null
|
||||||
: hasMajorFactor
|
: typeof fromDb.majorFactor === 'number'
|
||||||
? null
|
? fromDb.majorFactor
|
||||||
: getDefaultMajorFactorById(row.id),
|
: hasMajorFactor
|
||||||
|
? null
|
||||||
|
: getDefaultMajorFactorById(row.id),
|
||||||
budgetFee: typeof fromDb.budgetFee === 'number' ? fromDb.budgetFee : null,
|
budgetFee: typeof fromDb.budgetFee === 'number' ? fromDb.budgetFee : null,
|
||||||
remark: typeof fromDb.remark === 'string' ? fromDb.remark : ''
|
remark: typeof fromDb.remark === 'string' ? fromDb.remark : ''
|
||||||
}
|
}
|
||||||
@@ -229,21 +268,10 @@ const formatEditableNumber = (params: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const formatConsultCategoryFactor = (params: any) => {
|
const formatConsultCategoryFactor = (params: any) => {
|
||||||
if (params.node?.group) {
|
|
||||||
const v = getDefaultConsultCategoryFactor()
|
|
||||||
if (v == null) return ''
|
|
||||||
return Number(v).toFixed(2)
|
|
||||||
}
|
|
||||||
return formatEditableNumber(params)
|
return formatEditableNumber(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatMajorFactor = (params: any) => {
|
const formatMajorFactor = (params: any) => {
|
||||||
if (params.node?.group) {
|
|
||||||
const groupId = String(params.node?.key || '')
|
|
||||||
const v = getDefaultMajorFactorById(groupId)
|
|
||||||
if (v == null) return ''
|
|
||||||
return Number(v).toFixed(2)
|
|
||||||
}
|
|
||||||
return formatEditableNumber(params)
|
return formatEditableNumber(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +472,9 @@ const loadFromIndexedDB = async () => {
|
|||||||
await ensureFactorDefaultsLoaded()
|
await ensureFactorDefaultsLoaded()
|
||||||
if (shouldForceDefaultLoad()) {
|
if (shouldForceDefaultLoad()) {
|
||||||
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
||||||
detailRows.value = htData?.detailRows ? mergeWithDictRows(htData.detailRows) : buildDefaultRows()
|
detailRows.value = htData?.detailRows
|
||||||
|
? mergeWithDictRows(htData.detailRows, { includeScaleValues: false, includeFactorValues: false })
|
||||||
|
: buildDefaultRows()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,7 +486,7 @@ const loadFromIndexedDB = async () => {
|
|||||||
|
|
||||||
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
||||||
if (htData?.detailRows) {
|
if (htData?.detailRows) {
|
||||||
detailRows.value = mergeWithDictRows(htData.detailRows)
|
detailRows.value = mergeWithDictRows(htData.detailRows, { includeScaleValues: false, includeFactorValues: false })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,6 +497,25 @@ const loadFromIndexedDB = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const importContractData = async () => {
|
||||||
|
try {
|
||||||
|
// 使用默认数据时,强制读取最新的项目系数(预算取值优先,空值回退标准系数)
|
||||||
|
await loadFactorDefaults()
|
||||||
|
const htData = await localforage.getItem<{ detailRows: SourceRow[] }>(HT_DB_KEY.value)
|
||||||
|
const hasContractRows = Array.isArray(htData?.detailRows) && htData.detailRows.length > 0
|
||||||
|
detailRows.value = hasContractRows
|
||||||
|
? mergeWithDictRows(htData!.detailRows, { includeFactorValues: true })
|
||||||
|
: buildDefaultRows().map(row => ({
|
||||||
|
...row,
|
||||||
|
consultCategoryFactor: getDefaultConsultCategoryFactor(),
|
||||||
|
majorFactor: getDefaultMajorFactorById(row.id)
|
||||||
|
}))
|
||||||
|
await saveToIndexedDB()
|
||||||
|
} catch (error) {
|
||||||
|
console.error('importContractData failed:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => pricingPaneReloadStore.getReloadVersion(props.contractId, props.serviceId),
|
() => pricingPaneReloadStore.getReloadVersion(props.contractId, props.serviceId),
|
||||||
(nextVersion, prevVersion) => {
|
(nextVersion, prevVersion) => {
|
||||||
@@ -524,7 +573,28 @@ const processCellFromClipboard = (params: any) => {
|
|||||||
<div class="rounded-lg border bg-card xmMx flex min-h-0 flex-1 flex-col">
|
<div class="rounded-lg border bg-card xmMx flex min-h-0 flex-1 flex-col">
|
||||||
<div class="flex items-center justify-between border-b px-4 py-3">
|
<div class="flex items-center justify-between border-b px-4 py-3">
|
||||||
<h3 class="text-sm font-semibold text-foreground">用地规模明细</h3>
|
<h3 class="text-sm font-semibold text-foreground">用地规模明细</h3>
|
||||||
<div class="text-xs text-muted-foreground">导入导出</div>
|
<AlertDialogRoot>
|
||||||
|
<AlertDialogTrigger as-child>
|
||||||
|
<Button type="button" variant="outline" size="sm">使用默认数据</Button>
|
||||||
|
</AlertDialogTrigger>
|
||||||
|
<AlertDialogPortal>
|
||||||
|
<AlertDialogOverlay class="fixed inset-0 z-50 bg-black/45" />
|
||||||
|
<AlertDialogContent class="fixed left-1/2 top-1/2 z-50 w-[92vw] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg border bg-background p-5 shadow-xl">
|
||||||
|
<AlertDialogTitle class="text-base font-semibold">确认覆盖当前明细</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription class="mt-2 text-sm text-muted-foreground">
|
||||||
|
将使用合同默认数据覆盖当前用地规模明细,是否继续?
|
||||||
|
</AlertDialogDescription>
|
||||||
|
<div class="mt-4 flex items-center justify-end gap-2">
|
||||||
|
<AlertDialogCancel as-child>
|
||||||
|
<Button variant="outline">取消</Button>
|
||||||
|
</AlertDialogCancel>
|
||||||
|
<AlertDialogAction as-child>
|
||||||
|
<Button @click="importContractData">确认覆盖</Button>
|
||||||
|
</AlertDialogAction>
|
||||||
|
</div>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialogPortal>
|
||||||
|
</AlertDialogRoot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
<div class="ag-theme-quartz h-full min-h-0 w-full flex-1">
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ const PRICING_FORCE_DEFAULT_PREFIX = 'pricing-force-default:'
|
|||||||
const pricingPaneReloadStore = usePricingPaneReloadStore()
|
const pricingPaneReloadStore = usePricingPaneReloadStore()
|
||||||
const consultCategoryFactorMap = ref<Map<string, number | null>>(new Map())
|
const consultCategoryFactorMap = ref<Map<string, number | null>>(new Map())
|
||||||
let factorDefaultsLoaded = false
|
let factorDefaultsLoaded = false
|
||||||
|
const paneInstanceCreatedAt = Date.now()
|
||||||
|
|
||||||
const getDefaultConsultCategoryFactor = () =>
|
const getDefaultConsultCategoryFactor = () =>
|
||||||
consultCategoryFactorMap.value.get(String(props.serviceId)) ?? null
|
consultCategoryFactorMap.value.get(String(props.serviceId)) ?? null
|
||||||
@@ -59,8 +60,21 @@ const shouldSkipPersist = () => {
|
|||||||
const storageKey = `${PRICING_CLEAR_SKIP_PREFIX}${DB_KEY.value}`
|
const storageKey = `${PRICING_CLEAR_SKIP_PREFIX}${DB_KEY.value}`
|
||||||
const raw = sessionStorage.getItem(storageKey)
|
const raw = sessionStorage.getItem(storageKey)
|
||||||
if (!raw) return false
|
if (!raw) return false
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
|
if (raw.includes(':')) {
|
||||||
|
const [issuedRaw, untilRaw] = raw.split(':')
|
||||||
|
const issuedAt = Number(issuedRaw)
|
||||||
|
const skipUntil = Number(untilRaw)
|
||||||
|
if (Number.isFinite(issuedAt) && Number.isFinite(skipUntil) && now <= skipUntil) {
|
||||||
|
return paneInstanceCreatedAt <= issuedAt
|
||||||
|
}
|
||||||
|
sessionStorage.removeItem(storageKey)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
const skipUntil = Number(raw)
|
const skipUntil = Number(raw)
|
||||||
if (Number.isFinite(skipUntil) && Date.now() <= skipUntil) return true
|
if (Number.isFinite(skipUntil) && now <= skipUntil) return true
|
||||||
sessionStorage.removeItem(storageKey)
|
sessionStorage.removeItem(storageKey)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -78,7 +92,8 @@ const detailRows = ref<DetailRow[]>([])
|
|||||||
|
|
||||||
type taskLite = {
|
type taskLite = {
|
||||||
serviceID: number
|
serviceID: number
|
||||||
code: string
|
code?: string
|
||||||
|
ref?: string
|
||||||
name: string
|
name: string
|
||||||
basicParam: string
|
basicParam: string
|
||||||
unit: string
|
unit: string
|
||||||
@@ -116,11 +131,12 @@ const buildDefaultRows = (): DetailRow[] => {
|
|||||||
|
|
||||||
for (const [order, taskId] of sourceTaskIds.entries()) {
|
for (const [order, taskId] of sourceTaskIds.entries()) {
|
||||||
const task = (taskList as Record<string, taskLite | undefined>)[String(taskId)]
|
const task = (taskList as Record<string, taskLite | undefined>)[String(taskId)]
|
||||||
if (!task?.code || !task?.name) continue
|
const taskCode = task?.code || task?.ref || ''
|
||||||
|
if (!taskCode || !task?.name) continue
|
||||||
const rowId = `task-${taskId}-${order}`
|
const rowId = `task-${taskId}-${order}`
|
||||||
rows.push({
|
rows.push({
|
||||||
id: rowId,
|
id: rowId,
|
||||||
taskCode: task.code,
|
taskCode,
|
||||||
taskName: task.name,
|
taskName: task.name,
|
||||||
unit: task.unit || '',
|
unit: task.unit || '',
|
||||||
conversion: typeof task.conversion === 'number' && Number.isFinite(task.conversion) ? task.conversion : null,
|
conversion: typeof task.conversion === 'number' && Number.isFinite(task.conversion) ? task.conversion : null,
|
||||||
|
|||||||
+192
-43
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
import { computed, defineComponent, h, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||||
import type { ComponentPublicInstance } from 'vue'
|
import type { ComponentPublicInstance, PropType } from 'vue'
|
||||||
import { AgGridVue } from 'ag-grid-vue3'
|
import { AgGridVue } from 'ag-grid-vue3'
|
||||||
import type { ColDef, GridOptions, ICellRendererParams } from 'ag-grid-community'
|
import type { ColDef, GridOptions, ICellRendererParams } from 'ag-grid-community'
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
@@ -8,10 +8,18 @@ import { myTheme ,gridOptions} from '@/lib/diyAgGridOptions'
|
|||||||
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
import { AG_GRID_LOCALE_CN } from '@ag-grid-community/locale'
|
||||||
import { addNumbers } from '@/lib/decimal'
|
import { addNumbers } from '@/lib/decimal'
|
||||||
import { formatThousands, formatThousandsFlexible } from '@/lib/numberFormat'
|
import { formatThousands, formatThousandsFlexible } from '@/lib/numberFormat'
|
||||||
import { getPricingMethodTotalsForService, getPricingMethodTotalsForServices } from '@/lib/pricingMethodTotals'
|
import { getPricingMethodTotalsForServices } from '@/lib/pricingMethodTotals'
|
||||||
import { ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
import { ZXFW_RELOAD_SERVICE_KEY } from '@/lib/zxFwPricingSync'
|
||||||
import { Search } from 'lucide-vue-next'
|
import { Search } from 'lucide-vue-next'
|
||||||
import {
|
import {
|
||||||
|
AlertDialogAction,
|
||||||
|
AlertDialogCancel,
|
||||||
|
AlertDialogContent,
|
||||||
|
AlertDialogDescription,
|
||||||
|
AlertDialogOverlay,
|
||||||
|
AlertDialogPortal,
|
||||||
|
AlertDialogRoot,
|
||||||
|
AlertDialogTitle,
|
||||||
DialogClose,
|
DialogClose,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogDescription,
|
DialogDescription,
|
||||||
@@ -22,6 +30,7 @@ import {
|
|||||||
DialogTrigger
|
DialogTrigger
|
||||||
} from 'reka-ui'
|
} from 'reka-ui'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from '@/components/ui/tooltip'
|
||||||
import { serviceList } from '@/sql'
|
import { serviceList } from '@/sql'
|
||||||
import { useTabStore } from '@/pinia/tab'
|
import { useTabStore } from '@/pinia/tab'
|
||||||
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
import { usePricingPaneReloadStore } from '@/pinia/pricingPaneReload'
|
||||||
@@ -153,6 +162,8 @@ function handleSnapHostScroll() {
|
|||||||
const pickerOpen = ref(false)
|
const pickerOpen = ref(false)
|
||||||
const pickerTempIds = ref<string[]>([])
|
const pickerTempIds = ref<string[]>([])
|
||||||
const pickerSearch = ref('')
|
const pickerSearch = ref('')
|
||||||
|
const clearConfirmOpen = ref(false)
|
||||||
|
const pendingClearServiceId = ref<string | null>(null)
|
||||||
const dragSelecting = ref(false)
|
const dragSelecting = ref(false)
|
||||||
const dragMoved = ref(false)
|
const dragMoved = ref(false)
|
||||||
let dragSelectChecked = false
|
let dragSelectChecked = false
|
||||||
@@ -170,6 +181,39 @@ const selectedServiceText = computed(() => {
|
|||||||
return `${names.slice(0, 2).join('、')} 等 ${names.length} 项`
|
return `${names.slice(0, 2).join('、')} 等 ${names.length} 项`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const pendingClearServiceName = computed(() => {
|
||||||
|
if (!pendingClearServiceId.value) return ''
|
||||||
|
const row = detailRows.value.find(item => item.id === pendingClearServiceId.value)
|
||||||
|
if (row) return `${row.code}${row.name}`
|
||||||
|
const dict = serviceById.get(pendingClearServiceId.value)
|
||||||
|
if (dict) return `${dict.code}${dict.name}`
|
||||||
|
return pendingClearServiceId.value
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleClearConfirmOpenChange = (open: boolean) => {
|
||||||
|
clearConfirmOpen.value = open
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestClearRow = (row: DetailRow) => {
|
||||||
|
if (isFixedRow(row)) return
|
||||||
|
pendingClearServiceId.value = row.id
|
||||||
|
clearConfirmOpen.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmClearRow = async () => {
|
||||||
|
const id = pendingClearServiceId.value
|
||||||
|
if (!id) return
|
||||||
|
const row = detailRows.value.find(item => item.id === id)
|
||||||
|
if (!row || isFixedRow(row)) {
|
||||||
|
clearConfirmOpen.value = false
|
||||||
|
pendingClearServiceId.value = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await clearRowValues(row)
|
||||||
|
clearConfirmOpen.value = false
|
||||||
|
pendingClearServiceId.value = null
|
||||||
|
}
|
||||||
|
|
||||||
const filteredServiceDict = computed(() => {
|
const filteredServiceDict = computed(() => {
|
||||||
const keyword = pickerSearch.value.trim()
|
const keyword = pickerSearch.value.trim()
|
||||||
if (!keyword) return serviceDict
|
if (!keyword) return serviceDict
|
||||||
@@ -198,6 +242,26 @@ const numericParser = (newValue: any): number | null => {
|
|||||||
|
|
||||||
const valueOrZero = (v: number | null | undefined) => (typeof v === 'number' ? v : 0)
|
const valueOrZero = (v: number | null | undefined) => (typeof v === 'number' ? v : 0)
|
||||||
|
|
||||||
|
const getMethodTotalFromRows = (
|
||||||
|
rows: DetailRow[],
|
||||||
|
field: 'investScale' | 'landScale' | 'workload' | 'hourly'
|
||||||
|
) =>
|
||||||
|
rows.reduce((sum, row) => {
|
||||||
|
if (isFixedRow(row)) return sum
|
||||||
|
return addNumbers(sum, valueOrZero(row[field]))
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
const getMethodTotal = (field: 'investScale' | 'landScale' | 'workload' | 'hourly') =>
|
||||||
|
getMethodTotalFromRows(detailRows.value, field)
|
||||||
|
|
||||||
|
const getFixedRowSubtotal = () =>
|
||||||
|
addNumbers(
|
||||||
|
getMethodTotal('investScale'),
|
||||||
|
getMethodTotal('landScale'),
|
||||||
|
getMethodTotal('workload'),
|
||||||
|
getMethodTotal('hourly')
|
||||||
|
)
|
||||||
|
|
||||||
const getPricingPaneStorageKeys = (serviceId: string) => [
|
const getPricingPaneStorageKeys = (serviceId: string) => [
|
||||||
`tzGMF-${props.contractId}-${serviceId}`,
|
`tzGMF-${props.contractId}-${serviceId}`,
|
||||||
`ydGMF-${props.contractId}-${serviceId}`,
|
`ydGMF-${props.contractId}-${serviceId}`,
|
||||||
@@ -207,9 +271,11 @@ const getPricingPaneStorageKeys = (serviceId: string) => [
|
|||||||
|
|
||||||
const clearPricingPaneValues = async (serviceId: string) => {
|
const clearPricingPaneValues = async (serviceId: string) => {
|
||||||
const keys = getPricingPaneStorageKeys(serviceId)
|
const keys = getPricingPaneStorageKeys(serviceId)
|
||||||
const skipUntil = Date.now() + PRICING_CLEAR_SKIP_TTL_MS
|
const clearIssuedAt = Date.now()
|
||||||
|
const skipUntil = clearIssuedAt + PRICING_CLEAR_SKIP_TTL_MS
|
||||||
|
const skipToken = `${clearIssuedAt}:${skipUntil}`
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
sessionStorage.setItem(`${PRICING_CLEAR_SKIP_PREFIX}${key}`, String(skipUntil))
|
sessionStorage.setItem(`${PRICING_CLEAR_SKIP_PREFIX}${key}`, skipToken)
|
||||||
sessionStorage.setItem(`${PRICING_FORCE_DEFAULT_PREFIX}${key}`, String(skipUntil))
|
sessionStorage.setItem(`${PRICING_FORCE_DEFAULT_PREFIX}${key}`, String(skipUntil))
|
||||||
}
|
}
|
||||||
await Promise.all(keys.map(key => localforage.removeItem(key)))
|
await Promise.all(keys.map(key => localforage.removeItem(key)))
|
||||||
@@ -222,21 +288,37 @@ const clearRowValues = async (row: DetailRow) => {
|
|||||||
// 若该服务编辑页已打开,先关闭,避免子页面卸载时把旧数据写回缓? tabStore.removeTab(`zxfw-edit-${props.contractId}-${row.id}`)
|
// 若该服务编辑页已打开,先关闭,避免子页面卸载时把旧数据写回缓? tabStore.removeTab(`zxfw-edit-${props.contractId}-${row.id}`)
|
||||||
await nextTick()
|
await nextTick()
|
||||||
await clearPricingPaneValues(row.id)
|
await clearPricingPaneValues(row.id)
|
||||||
const totals = await getPricingMethodTotalsForService({
|
// const totals = await getPricingMethodTotalsForService({
|
||||||
contractId: props.contractId,
|
// contractId: props.contractId,
|
||||||
serviceId: row.id
|
// serviceId: row.id
|
||||||
})
|
// })
|
||||||
detailRows.value = detailRows.value.map(item =>
|
const clearedRows = detailRows.value.map(item =>
|
||||||
item.id !== row.id
|
item.id !== row.id
|
||||||
? item
|
? item
|
||||||
: {
|
: {
|
||||||
...item,
|
...item,
|
||||||
investScale: totals.investScale,
|
investScale: null,
|
||||||
landScale: totals.landScale,
|
landScale: null,
|
||||||
workload: totals.workload,
|
workload: null,
|
||||||
hourly: totals.hourly
|
hourly: null
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
const nextInvestScale = getMethodTotalFromRows(clearedRows, 'investScale')
|
||||||
|
const nextLandScale = getMethodTotalFromRows(clearedRows, 'landScale')
|
||||||
|
const nextWorkload = getMethodTotalFromRows(clearedRows, 'workload')
|
||||||
|
const nextHourly = getMethodTotalFromRows(clearedRows, 'hourly')
|
||||||
|
detailRows.value = clearedRows.map(item =>
|
||||||
|
isFixedRow(item)
|
||||||
|
? {
|
||||||
|
...item,
|
||||||
|
investScale: nextInvestScale,
|
||||||
|
landScale: nextLandScale,
|
||||||
|
workload: nextWorkload,
|
||||||
|
hourly: nextHourly,
|
||||||
|
subtotal: addNumbers(nextInvestScale, nextLandScale, nextWorkload, nextHourly)
|
||||||
|
}
|
||||||
|
: item
|
||||||
|
)
|
||||||
await saveToIndexedDB()
|
await saveToIndexedDB()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +331,41 @@ const openEditTab = (row: DetailRow) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ActionCellRenderer = defineComponent({
|
||||||
|
name: 'ActionCellRenderer',
|
||||||
|
props: {
|
||||||
|
params: {
|
||||||
|
type: Object as PropType<ICellRendererParams<DetailRow>>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
return () => {
|
||||||
|
if (isFixedRow(props.params.data)) return null
|
||||||
|
return h('div', { class: 'zxfw-action-wrap' }, [
|
||||||
|
h(TooltipRoot, null, {
|
||||||
|
default: () => [
|
||||||
|
h(TooltipTrigger, { asChild: true }, {
|
||||||
|
default: () =>
|
||||||
|
h('button', { class: 'zxfw-action-btn', 'data-action': 'edit' }, '✏️')
|
||||||
|
}),
|
||||||
|
h(TooltipContent, { side: 'top' }, { default: () => '编辑' })
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
h(TooltipRoot, null, {
|
||||||
|
default: () => [
|
||||||
|
h(TooltipTrigger, { asChild: true }, {
|
||||||
|
default: () =>
|
||||||
|
h('button', { class: 'zxfw-action-btn', 'data-action': 'clear' }, '🧹')
|
||||||
|
}),
|
||||||
|
h(TooltipContent, { side: 'top' }, { default: () => '清空' })
|
||||||
|
]
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const columnDefs: ColDef<DetailRow>[] = [
|
const columnDefs: ColDef<DetailRow>[] = [
|
||||||
{ headerName: '编码', field: 'code', minWidth: 50, maxWidth: 100 },
|
{ headerName: '编码', field: 'code', minWidth: 50, maxWidth: 100 },
|
||||||
{ headerName: '名称', field: 'name', minWidth: 250, flex: 3, tooltipField: 'name' },
|
{ headerName: '名称', field: 'name', minWidth: 250, flex: 3, tooltipField: 'name' },
|
||||||
@@ -261,6 +378,11 @@ const columnDefs: ColDef<DetailRow>[] = [
|
|||||||
cellClass: 'ag-right-aligned-cell',
|
cellClass: 'ag-right-aligned-cell',
|
||||||
editable: false,
|
editable: false,
|
||||||
|
|
||||||
|
valueGetter: params => {
|
||||||
|
if (!params.data) return null
|
||||||
|
if (isFixedRow(params.data)) return getMethodTotal('investScale')
|
||||||
|
return params.data.investScale
|
||||||
|
},
|
||||||
valueParser: params => numericParser(params.newValue),
|
valueParser: params => numericParser(params.newValue),
|
||||||
valueFormatter: params => (params.value == null ? '' : formatThousands(params.value))
|
valueFormatter: params => (params.value == null ? '' : formatThousands(params.value))
|
||||||
},
|
},
|
||||||
@@ -273,6 +395,11 @@ const columnDefs: ColDef<DetailRow>[] = [
|
|||||||
cellClass: 'ag-right-aligned-cell',
|
cellClass: 'ag-right-aligned-cell',
|
||||||
editable: false,
|
editable: false,
|
||||||
|
|
||||||
|
valueGetter: params => {
|
||||||
|
if (!params.data) return null
|
||||||
|
if (isFixedRow(params.data)) return getMethodTotal('landScale')
|
||||||
|
return params.data.landScale
|
||||||
|
},
|
||||||
valueParser: params => numericParser(params.newValue),
|
valueParser: params => numericParser(params.newValue),
|
||||||
valueFormatter: params => (params.value == null ? '' : formatThousandsFlexible(params.value, 2))
|
valueFormatter: params => (params.value == null ? '' : formatThousandsFlexible(params.value, 2))
|
||||||
},
|
},
|
||||||
@@ -285,6 +412,11 @@ const columnDefs: ColDef<DetailRow>[] = [
|
|||||||
cellClass: 'ag-right-aligned-cell',
|
cellClass: 'ag-right-aligned-cell',
|
||||||
editable: false,
|
editable: false,
|
||||||
|
|
||||||
|
valueGetter: params => {
|
||||||
|
if (!params.data) return null
|
||||||
|
if (isFixedRow(params.data)) return getMethodTotal('workload')
|
||||||
|
return params.data.workload
|
||||||
|
},
|
||||||
// editable: params => !params.node?.rowPinned && !isFixedRow(params.data),
|
// editable: params => !params.node?.rowPinned && !isFixedRow(params.data),
|
||||||
valueParser: params => numericParser(params.newValue),
|
valueParser: params => numericParser(params.newValue),
|
||||||
valueFormatter: params => (params.value == null ? '' : formatThousands(params.value))
|
valueFormatter: params => (params.value == null ? '' : formatThousands(params.value))
|
||||||
@@ -298,6 +430,11 @@ const columnDefs: ColDef<DetailRow>[] = [
|
|||||||
cellClass: 'ag-right-aligned-cell',
|
cellClass: 'ag-right-aligned-cell',
|
||||||
editable: false,
|
editable: false,
|
||||||
|
|
||||||
|
valueGetter: params => {
|
||||||
|
if (!params.data) return null
|
||||||
|
if (isFixedRow(params.data)) return getMethodTotal('hourly')
|
||||||
|
return params.data.hourly
|
||||||
|
},
|
||||||
// editable: params => !params.node?.rowPinned && !isFixedRow(params.data),
|
// editable: params => !params.node?.rowPinned && !isFixedRow(params.data),
|
||||||
valueParser: params => numericParser(params.newValue),
|
valueParser: params => numericParser(params.newValue),
|
||||||
valueFormatter: params => (params.value == null ? '' : formatThousands(params.value))
|
valueFormatter: params => (params.value == null ? '' : formatThousands(params.value))
|
||||||
@@ -313,6 +450,7 @@ const columnDefs: ColDef<DetailRow>[] = [
|
|||||||
editable: false,
|
editable: false,
|
||||||
valueGetter: params => {
|
valueGetter: params => {
|
||||||
if (!params.data) return null
|
if (!params.data) return null
|
||||||
|
if (isFixedRow(params.data)) return getFixedRowSubtotal()
|
||||||
return addNumbers(
|
return addNumbers(
|
||||||
valueOrZero(params.data.investScale),
|
valueOrZero(params.data.investScale),
|
||||||
valueOrZero(params.data.landScale),
|
valueOrZero(params.data.landScale),
|
||||||
@@ -332,14 +470,7 @@ const columnDefs: ColDef<DetailRow>[] = [
|
|||||||
sortable: false,
|
sortable: false,
|
||||||
filter: false,
|
filter: false,
|
||||||
suppressMovable: true,
|
suppressMovable: true,
|
||||||
cellRenderer: (params: ICellRendererParams<DetailRow>) =>
|
cellRenderer: ActionCellRenderer
|
||||||
isFixedRow(params.data)
|
|
||||||
? ''
|
|
||||||
: `<div class="zxfw-action-wrap">
|
|
||||||
<button class="zxfw-action-btn" data-action="edit" title="编辑">✏️</button>
|
|
||||||
|
|
||||||
<button class="zxfw-action-btn" data-action="clear" title="清空(重置到默认状态)">🧹</button>
|
|
||||||
</div>`
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -353,7 +484,7 @@ const detailGridOptions: GridOptions<DetailRow> = {
|
|||||||
const btn = target?.closest('button[data-action]') as HTMLButtonElement | null
|
const btn = target?.closest('button[data-action]') as HTMLButtonElement | null
|
||||||
const action = btn?.dataset.action
|
const action = btn?.dataset.action
|
||||||
if (action === 'clear') {
|
if (action === 'clear') {
|
||||||
await clearRowValues(params.data)
|
requestClearRow(params.data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (action === 'edit') {
|
if (action === 'edit') {
|
||||||
@@ -457,7 +588,7 @@ const handlePickerOpenChange = (open: boolean) => {
|
|||||||
const confirmPicker = async () => {
|
const confirmPicker = async () => {
|
||||||
applySelection(pickerTempIds.value)
|
applySelection(pickerTempIds.value)
|
||||||
try {
|
try {
|
||||||
await fillPricingTotalsForSelectedRows()
|
// await fillPricingTotalsForSelectedRows()
|
||||||
await saveToIndexedDB()
|
await saveToIndexedDB()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('confirmPicker failed:', error)
|
console.error('confirmPicker failed:', error)
|
||||||
@@ -469,15 +600,7 @@ const clearPickerSelection = () => {
|
|||||||
pickerTempIds.value = []
|
pickerTempIds.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleServiceCode = (code: string, checked: boolean) => {
|
|
||||||
if (checked) {
|
|
||||||
if (!pickerTempIds.value.includes(code)) {
|
|
||||||
pickerTempIds.value = [...pickerTempIds.value, code]
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pickerTempIds.value = pickerTempIds.value.filter(item => item !== code)
|
|
||||||
}
|
|
||||||
|
|
||||||
const applyTempChecked = (code: string, checked: boolean) => {
|
const applyTempChecked = (code: string, checked: boolean) => {
|
||||||
const exists = pickerTempIds.value.includes(code)
|
const exists = pickerTempIds.value.includes(code)
|
||||||
@@ -608,7 +731,7 @@ const loadFromIndexedDB = async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fillPricingTotalsForSelectedRows()
|
// await fillPricingTotalsForSelectedRows()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('fillPricingTotalsForSelectedRows failed:', error)
|
console.error('fillPricingTotalsForSelectedRows failed:', error)
|
||||||
}
|
}
|
||||||
@@ -659,7 +782,8 @@ onBeforeUnmount(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="rootRef" class="space-y-6">
|
<TooltipProvider>
|
||||||
|
<div ref="rootRef" class="space-y-6">
|
||||||
<DialogRoot v-model:open="pickerOpen" @update:open="handlePickerOpenChange">
|
<DialogRoot v-model:open="pickerOpen" @update:open="handlePickerOpenChange">
|
||||||
<div class="rounded-lg border bg-card p-4 shadow-sm shrink-0">
|
<div class="rounded-lg border bg-card p-4 shadow-sm shrink-0">
|
||||||
<div class="mb-2 flex items-center justify-between gap-3">
|
<div class="mb-2 flex items-center justify-between gap-3">
|
||||||
@@ -668,13 +792,17 @@ onBeforeUnmount(() => {
|
|||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<input :value="selectedServiceText" readonly placeholder="请点击右侧“浏览”选择服务"
|
<input :value="selectedServiceText" readonly placeholder="请点击右侧“浏览”选择服务"
|
||||||
class="h-10 w-full rounded-md border bg-background px-3 text-sm text-foreground outline-none" />
|
class="h-10 w-full rounded-md border bg-background px-3 text-sm text-foreground outline-none" />
|
||||||
<DialogTrigger as-child>
|
<TooltipRoot>
|
||||||
<button type="button"
|
<TooltipTrigger as-child>
|
||||||
class="inline-flex h-10 w-10 items-center justify-center rounded-md border text-sm hover:bg-accent cursor-pointer"
|
<DialogTrigger as-child>
|
||||||
title="浏览服务词典">
|
<button type="button"
|
||||||
<Search class="h-4 w-4" />
|
class="inline-flex h-10 w-10 items-center justify-center rounded-md border text-sm hover:bg-accent cursor-pointer">
|
||||||
</button>
|
<Search class="h-4 w-4" />
|
||||||
</DialogTrigger>
|
</button>
|
||||||
|
</DialogTrigger>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="top">浏览服务词典</TooltipContent>
|
||||||
|
</TooltipRoot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<DialogPortal>
|
<DialogPortal>
|
||||||
@@ -754,5 +882,26 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
<AlertDialogRoot :open="clearConfirmOpen" @update:open="handleClearConfirmOpenChange">
|
||||||
|
<AlertDialogPortal>
|
||||||
|
<AlertDialogOverlay class="fixed inset-0 z-50 bg-black/45" />
|
||||||
|
<AlertDialogContent class="fixed left-1/2 top-1/2 z-[70] w-[92vw] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg border bg-background p-5 shadow-xl">
|
||||||
|
<AlertDialogTitle class="text-base font-semibold">确认清空服务数据</AlertDialogTitle>
|
||||||
|
<AlertDialogDescription class="mt-2 text-sm text-muted-foreground">
|
||||||
|
将清空“{{ pendingClearServiceName }}”的计价数据是否继续?
|
||||||
|
</AlertDialogDescription>
|
||||||
|
<div class="mt-4 flex items-center justify-end gap-2">
|
||||||
|
<AlertDialogCancel as-child>
|
||||||
|
<Button variant="outline">取消</Button>
|
||||||
|
</AlertDialogCancel>
|
||||||
|
<AlertDialogAction as-child>
|
||||||
|
<Button variant="destructive" @click="confirmClearRow">确认清空</Button>
|
||||||
|
</AlertDialogAction>
|
||||||
|
</div>
|
||||||
|
</AlertDialogContent>
|
||||||
|
</AlertDialogPortal>
|
||||||
|
</AlertDialogRoot>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</TooltipProvider>
|
||||||
</template>
|
</template>
|
||||||
+11
-3
@@ -485,7 +485,9 @@ const exportData = async () => {
|
|||||||
dataMenuOpen.value = false
|
dataMenuOpen.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const exportReport = async ()=>{
|
||||||
|
|
||||||
|
}
|
||||||
const triggerImport = () => {
|
const triggerImport = () => {
|
||||||
importFileRef.value?.click()
|
importFileRef.value?.click()
|
||||||
}
|
}
|
||||||
@@ -629,17 +631,23 @@ watch(
|
|||||||
v-if="dataMenuOpen"
|
v-if="dataMenuOpen"
|
||||||
class="absolute right-0 top-full mt-1 z-50 min-w-[108px] rounded-md border bg-background p-1 shadow-md"
|
class="absolute right-0 top-full mt-1 z-50 min-w-[108px] rounded-md border bg-background p-1 shadow-md"
|
||||||
>
|
>
|
||||||
|
<button
|
||||||
|
class="w-full cursor-pointer rounded px-3 py-1.5 text-left text-sm hover:bg-muted"
|
||||||
|
@click="triggerImport"
|
||||||
|
>
|
||||||
|
导入
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
class="w-full cursor-pointer rounded px-3 py-1.5 text-left text-sm hover:bg-muted"
|
class="w-full cursor-pointer rounded px-3 py-1.5 text-left text-sm hover:bg-muted"
|
||||||
@click="exportData"
|
@click="exportData"
|
||||||
>
|
>
|
||||||
导出
|
导出
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="w-full cursor-pointer rounded px-3 py-1.5 text-left text-sm hover:bg-muted"
|
class="w-full cursor-pointer rounded px-3 py-1.5 text-left text-sm hover:bg-muted"
|
||||||
@click="triggerImport"
|
@click="exportReport"
|
||||||
>
|
>
|
||||||
导入
|
导出报表
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
|
|||||||
+196
-2
@@ -1,8 +1,19 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onBeforeUnmount, ref, watch, type Component } from 'vue'
|
import { computed, onBeforeUnmount, ref, watch, type Component ,onMounted} from 'vue'
|
||||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
import {
|
||||||
|
DialogClose,
|
||||||
|
DialogContent,
|
||||||
|
DialogOverlay,
|
||||||
|
DialogPortal,
|
||||||
|
DialogRoot,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,DialogDescription
|
||||||
|
} from 'reka-ui'
|
||||||
|
import { Icon } from '@iconify/vue'
|
||||||
|
import { useWindowSize } from '@vueuse/core'
|
||||||
|
import { animate, AnimatePresence, Motion, useMotionValue, useMotionValueEvent, useTransform } from 'motion-v'
|
||||||
interface TypeLineCategory {
|
interface TypeLineCategory {
|
||||||
key: string
|
key: string
|
||||||
label: string
|
label: string
|
||||||
@@ -59,6 +70,7 @@ const activeComponent = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const copyBtnText = ref('复制')
|
const copyBtnText = ref('复制')
|
||||||
|
const sheetOpen = ref(false)
|
||||||
let copyBtnTimer: ReturnType<typeof setTimeout> | null = null
|
let copyBtnTimer: ReturnType<typeof setTimeout> | null = null
|
||||||
|
|
||||||
const handleCopySubtitle = async () => {
|
const handleCopySubtitle = async () => {
|
||||||
@@ -81,7 +93,91 @@ const handleCopySubtitle = async () => {
|
|||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (copyBtnTimer) clearTimeout(copyBtnTimer)
|
if (copyBtnTimer) clearTimeout(copyBtnTimer)
|
||||||
|
if (!root) return
|
||||||
|
root.style.scale = ''
|
||||||
|
root.style.translate = ''
|
||||||
|
root.style.borderRadius = ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
const inertiaTransition = {
|
||||||
|
type: 'inertia' as const,
|
||||||
|
bounceStiffness: 300,
|
||||||
|
bounceDamping: 40,
|
||||||
|
timeConstant: 300,
|
||||||
|
}
|
||||||
|
|
||||||
|
const staticTransition = {
|
||||||
|
duration: 0.5,
|
||||||
|
ease: [0.32, 0.72, 0, 1] as const,
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHEET_TOP_RATIO = 0.1
|
||||||
|
const SHEET_RADIUS = 12
|
||||||
|
const OFFICIAL_SITE_URL = 'http://www.zwgczx.com.cn/'
|
||||||
|
|
||||||
|
let root: HTMLElement | null = null
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
root = document.body.firstElementChild as HTMLElement | null
|
||||||
|
})
|
||||||
|
|
||||||
|
const { height, width } = useWindowSize()
|
||||||
|
|
||||||
|
const sheetTop = computed(() => Math.round(height.value * SHEET_TOP_RATIO))
|
||||||
|
const h = computed(() => Math.max(0, height.value - sheetTop.value))
|
||||||
|
const y = useMotionValue(h.value)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => h.value,
|
||||||
|
(nextHeight) => {
|
||||||
|
if (!sheetOpen.value) y.jump(nextHeight)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => sheetOpen.value,
|
||||||
|
(isOpen) => {
|
||||||
|
if (!isOpen) {
|
||||||
|
y.jump(h.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
y.jump(h.value)
|
||||||
|
animate(y, 0, staticTransition)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Scale the body down and adjust the border radius when the sheet is open.
|
||||||
|
const bodyScale = useTransform(
|
||||||
|
y,
|
||||||
|
[0, h.value],
|
||||||
|
[(width.value - sheetTop.value) / width.value, 1],
|
||||||
|
)
|
||||||
|
const bodyTranslate = useTransform(y, [0, h.value], [sheetTop.value - SHEET_RADIUS, 0])
|
||||||
|
const bodyBorderRadius = useTransform(y, [0, h.value], [SHEET_RADIUS, 0])
|
||||||
|
|
||||||
|
useMotionValueEvent(bodyScale, 'change', (v) => {
|
||||||
|
if (!root) return
|
||||||
|
root.style.scale = `${v}`
|
||||||
|
})
|
||||||
|
useMotionValueEvent(
|
||||||
|
bodyTranslate,
|
||||||
|
'change',
|
||||||
|
(v) => {
|
||||||
|
if (!root) return
|
||||||
|
root.style.translate = `0 ${v}px`
|
||||||
|
},
|
||||||
|
)
|
||||||
|
useMotionValueEvent(
|
||||||
|
bodyBorderRadius,
|
||||||
|
'change',
|
||||||
|
(v) => {
|
||||||
|
if (!root) return
|
||||||
|
root.style.borderRadius = `${v}px`
|
||||||
|
},
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -140,6 +236,104 @@ onBeforeUnmount(() => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<DialogRoot v-model:open="sheetOpen">
|
||||||
|
<DialogTrigger as-child>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="absolute left-4 right-4 bottom-4 flex cursor-pointer flex-col items-center gap-1.5 rounded-lg border bg-muted/35 px-3 py-2 text-center text-[12px] leading-5 text-foreground/85 shadow-sm transition-colors hover:bg-muted/55 hover:text-foreground"
|
||||||
|
>
|
||||||
|
<img src="/favicon.ico" alt="众为咨询" class="h-5 w-5 shrink-0 rounded-sm" />
|
||||||
|
<span>本网站由众为工程咨询有限公司提供免费技术支持</span>
|
||||||
|
</button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogPortal>
|
||||||
|
<AnimatePresence
|
||||||
|
multiple
|
||||||
|
as="div"
|
||||||
|
>
|
||||||
|
<DialogOverlay as-child>
|
||||||
|
<Motion
|
||||||
|
class="fixed inset-0 z-10 bg-black/45 backdrop-blur-[2px]"
|
||||||
|
:initial="{ opacity: 0 }"
|
||||||
|
:animate="{ opacity: 1 }"
|
||||||
|
:exit="{ opacity: 0 }"
|
||||||
|
:transition="staticTransition"
|
||||||
|
/>
|
||||||
|
</DialogOverlay>
|
||||||
|
|
||||||
|
<DialogContent as-child>
|
||||||
|
<Motion
|
||||||
|
class="fixed inset-x-0 bottom-0 z-20 overflow-hidden rounded-t-2xl border border-border/60 bg-card/95 shadow-2xl backdrop-blur-xl will-change-transform"
|
||||||
|
:style="{
|
||||||
|
y,
|
||||||
|
top: `${sheetTop}px`,
|
||||||
|
}"
|
||||||
|
drag="y"
|
||||||
|
:drag-constraints="{ top: 0 }"
|
||||||
|
@drag-end="(e, { offset, velocity }) => {
|
||||||
|
if (offset.y > h * 0.35 || velocity.y > 10) {
|
||||||
|
sheetOpen = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
animate(y, 0, { ...inertiaTransition, min: 0, max: 0 });
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="mx-auto mt-2 h-1.5 w-12 cursor-grab rounded-full bg-muted-foreground/35 active:cursor-grabbing" />
|
||||||
|
<div class="mx-auto flex h-full w-full max-w-2xl flex-col px-4 pb-5 pt-3">
|
||||||
|
<div class="mb-3">
|
||||||
|
<div class="flex justify-end">
|
||||||
|
<DialogClose class="inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-md border border-muted-foreground/30 text-muted-foreground transition-colors hover:border-foreground/40 hover:text-foreground">
|
||||||
|
<Icon icon="lucide:x" class="h-4 w-4" />
|
||||||
|
</DialogClose>
|
||||||
|
</div>
|
||||||
|
<DialogTitle class="mt-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<img src="/favicon.ico" alt="众为咨询" class="h-7 w-7 shrink-0 rounded-sm" />
|
||||||
|
<span class="text-2xl font-semibold leading-none">关于我们</span>
|
||||||
|
</div>
|
||||||
|
</DialogTitle>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DialogDescription class="mb-4 text-base text-muted-foreground">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<a
|
||||||
|
:href="OFFICIAL_SITE_URL"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="inline-flex cursor-pointer items-center font-medium text-foreground transition-colors hover:text-primary hover:underline"
|
||||||
|
>
|
||||||
|
众为工程咨询有限公司
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
:href="OFFICIAL_SITE_URL"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="inline-flex h-7 w-7 cursor-pointer items-center justify-center rounded-md border border-muted-foreground/30 text-muted-foreground transition-colors hover:border-foreground/40 hover:text-foreground"
|
||||||
|
aria-label="跳转到官网首页"
|
||||||
|
title="官网首页"
|
||||||
|
>
|
||||||
|
<Icon icon="lucide:arrow-up-right" class="h-4 w-4" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</DialogDescription>
|
||||||
|
|
||||||
|
<div class="space-y-4 overflow-y-auto pr-1 text-[15px] leading-7">
|
||||||
|
<p>
|
||||||
|
众为工程咨询有限公司 2009 年成立,专注工程造价与工程成本管控全过程咨询,是广东省政府审计入库优选单位。公司服务覆盖多领域、全类型客户,累计服务投资额超万亿元,深度参与港珠澳大桥、澳门大学横琴校区等国家级重点工程,参编三十余项国家及省市行业标准。
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
公司立足大湾区,布局全球,设有澳门公司、斯里兰卡分公司,具备跨境与海外项目服务能力,以十五年专业沉淀、万亿级项目经验,为客户提供精准、可靠的工程咨询服务。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Motion>
|
||||||
|
</DialogContent>
|
||||||
|
</AnimatePresence>
|
||||||
|
</DialogPortal>
|
||||||
|
</DialogRoot>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-88/100 min-h-0 h-full flex flex-col">
|
<div class="w-88/100 min-h-0 h-full flex flex-col">
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
import {
|
import { GridOptions, themeQuartz } from "ag-grid-community"
|
||||||
|
|
||||||
GridOptions,
|
|
||||||
themeQuartz
|
|
||||||
} from "ag-grid-community"
|
|
||||||
const borderConfig = {
|
const borderConfig = {
|
||||||
style: "solid", // 虚线改实线更简洁,也可保留 dotted 但建议用 solid
|
style: "solid", // 虚线改实线更简洁,也可保留 dotted 但建议用 solid
|
||||||
width: 0.3, // 更细的边框,减少视觉干扰
|
width: 0.3, // 更细的边框,减少视觉干扰
|
||||||
@@ -25,7 +21,6 @@ export const myTheme = themeQuartz.withParams({
|
|||||||
columnBorder: borderConfig,
|
columnBorder: borderConfig,
|
||||||
headerRowBorder: borderConfig,
|
headerRowBorder: borderConfig,
|
||||||
|
|
||||||
|
|
||||||
// 可选:偶数行背景色(轻微区分,更清新)
|
// 可选:偶数行背景色(轻微区分,更清新)
|
||||||
dataBackgroundColor: "#fefefe"
|
dataBackgroundColor: "#fefefe"
|
||||||
});
|
});
|
||||||
@@ -43,6 +38,8 @@ export const gridOptions: GridOptions<any> = {
|
|||||||
// },
|
// },
|
||||||
groupDefaultExpanded: -1,
|
groupDefaultExpanded: -1,
|
||||||
suppressFieldDotNotation: true,
|
suppressFieldDotNotation: true,
|
||||||
|
// Keep group expand/collapse state when rowData updates after edits/saves.
|
||||||
|
getRowId: params => String(params.data?.id ?? params.data?.path?.join('/') ?? ''),
|
||||||
getDataPath: data => data.path,
|
getDataPath: data => data.path,
|
||||||
getContextMenuItems: () => ['copy', 'paste', 'separator', 'export'],
|
getContextMenuItems: () => ['copy', 'paste', 'separator', 'export'],
|
||||||
defaultColDef: {
|
defaultColDef: {
|
||||||
|
|||||||
+39
-14
@@ -1,4 +1,5 @@
|
|||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
|
import { majorList, serviceList } from '@/sql'
|
||||||
|
|
||||||
const CONSULT_CATEGORY_FACTOR_KEY = 'xm-consult-category-factor-v1'
|
const CONSULT_CATEGORY_FACTOR_KEY = 'xm-consult-category-factor-v1'
|
||||||
const MAJOR_FACTOR_KEY = 'xm-major-factor-v1'
|
const MAJOR_FACTOR_KEY = 'xm-major-factor-v1'
|
||||||
@@ -13,27 +14,51 @@ type XmFactorState = {
|
|||||||
detailRows?: XmFactorRow[]
|
detailRows?: XmFactorRow[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FactorDictItem = {
|
||||||
|
defCoe?: number | null
|
||||||
|
}
|
||||||
|
|
||||||
|
type FactorDict = Record<string, FactorDictItem>
|
||||||
|
|
||||||
const toFiniteNumberOrNull = (value: unknown): number | null =>
|
const toFiniteNumberOrNull = (value: unknown): number | null =>
|
||||||
typeof value === 'number' && Number.isFinite(value) ? value : null
|
typeof value === 'number' && Number.isFinite(value) ? value : null
|
||||||
|
|
||||||
const resolveFactorValue = (row: Partial<XmFactorRow> | undefined): number | null => {
|
const buildStandardFactorMap = (dict: FactorDict): Map<string, number | null> => {
|
||||||
if (!row) return null
|
|
||||||
const budgetValue = toFiniteNumberOrNull(row.budgetValue)
|
|
||||||
if (budgetValue != null) return budgetValue
|
|
||||||
return toFiniteNumberOrNull(row.standardFactor)
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadFactorMap = async (storageKey: string): Promise<Map<string, number | null>> => {
|
|
||||||
const data = await localforage.getItem<XmFactorState>(storageKey)
|
|
||||||
const map = new Map<string, number | null>()
|
const map = new Map<string, number | null>()
|
||||||
for (const row of data?.detailRows || []) {
|
for (const [id, item] of Object.entries(dict)) {
|
||||||
if (!row?.id) continue
|
map.set(String(id), toFiniteNumberOrNull(item?.defCoe))
|
||||||
map.set(String(row.id), resolveFactorValue(row))
|
|
||||||
}
|
}
|
||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadConsultCategoryFactorMap = async () => loadFactorMap(CONSULT_CATEGORY_FACTOR_KEY)
|
const resolveFactorValue = (
|
||||||
|
row: Partial<XmFactorRow> | undefined,
|
||||||
|
fallbackStandard: number | null
|
||||||
|
): number | null => {
|
||||||
|
if (!row) return null
|
||||||
|
const budgetValue = toFiniteNumberOrNull(row.budgetValue)
|
||||||
|
if (budgetValue != null) return budgetValue
|
||||||
|
const standardFactor = toFiniteNumberOrNull(row.standardFactor)
|
||||||
|
if (standardFactor != null) return standardFactor
|
||||||
|
return fallbackStandard
|
||||||
|
}
|
||||||
|
|
||||||
export const loadMajorFactorMap = async () => loadFactorMap(MAJOR_FACTOR_KEY)
|
const loadFactorMap = async (
|
||||||
|
storageKey: string,
|
||||||
|
dict: FactorDict
|
||||||
|
): Promise<Map<string, number | null>> => {
|
||||||
|
const data = await localforage.getItem<XmFactorState>(storageKey)
|
||||||
|
const map = buildStandardFactorMap(dict)
|
||||||
|
for (const row of data?.detailRows || []) {
|
||||||
|
if (!row?.id) continue
|
||||||
|
const id = String(row.id)
|
||||||
|
map.set(id, resolveFactorValue(row, map.get(id) ?? null))
|
||||||
|
}
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
|
export const loadConsultCategoryFactorMap = async () =>
|
||||||
|
loadFactorMap(CONSULT_CATEGORY_FACTOR_KEY, serviceList as FactorDict)
|
||||||
|
|
||||||
|
export const loadMajorFactorMap = async () =>
|
||||||
|
loadFactorMap(MAJOR_FACTOR_KEY, majorList as FactorDict)
|
||||||
+817
-61
@@ -1,3 +1,4 @@
|
|||||||
|
// @ts-nocheck
|
||||||
import { roundTo, toDecimal } from '@/lib/decimal'
|
import { roundTo, toDecimal } from '@/lib/decimal'
|
||||||
|
|
||||||
export const majorList = {
|
export const majorList = {
|
||||||
@@ -67,44 +68,51 @@ export const serviceList = {
|
|||||||
};
|
};
|
||||||
//basicParam预算基数
|
//basicParam预算基数
|
||||||
|
|
||||||
export const taskList = {
|
export const taskList = {
|
||||||
0: { serviceID: 15, code: 'C4-1', name: '工程造价日常顾问', basicParam: '服务月份数', required: true, unit: '万元/月', conversion: 10000, maxPrice: 0.5, minPrice: 0.3, defPrice: 0.4, desc: '' },
|
0: { serviceID: 15, ref: 'C4-1', name: '工程造价日常顾问', basicParam: '服务月份数', required: true, unit: '万元/月', conversion: 10000, maxPrice: 0.5, minPrice: 0.3, defPrice: 0.4, desc: '' },
|
||||||
1: { serviceID: 15, code: 'C4-2', name: '工程造价专项顾问', basicParam: '服务项目的造价金额', required: true, unit: '%', conversion: 0.01, maxPrice: null, minPrice: null, defPrice: 0.01, desc: '适用于涉及造价费用类的顾问' },
|
1: { serviceID: 15, ref: 'C4-2', name: '工程造价专项顾问', basicParam: '服务项目的造价金额', required: true, unit: '%', conversion: 0.01, maxPrice: null, minPrice: null, defPrice: 0.01, desc: '适用于涉及造价费用类的顾问' },
|
||||||
2: { serviceID: 16, code: 'C5-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
2: { serviceID: 16, ref: 'C5-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
||||||
3: { serviceID: 16, code: 'C5-2-1', name: '文件编写工作', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 5, minPrice: 3, defPrice: 4, desc: '主编' },
|
3: { serviceID: 16, ref: 'C5-2-1', name: '文件编写工作', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 5, minPrice: 3, defPrice: 4, desc: '主编' },
|
||||||
4: { serviceID: 16, code: 'C5-2-2', name: '文件编写工作', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '参编' },
|
4: { serviceID: 16, ref: 'C5-2-2', name: '文件编写工作', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '参编' },
|
||||||
5: { serviceID: 16, code: 'C5-3-1', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
5: { serviceID: 16, ref: 'C5-3-1', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
||||||
6: { serviceID: 16, code: 'C5-3-2', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
6: { serviceID: 16, ref: 'C5-3-2', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
||||||
7: { serviceID: 16, code: 'C5-3-3', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
7: { serviceID: 16, ref: 'C5-3-3', name: '评审工作', basicParam: '评审次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
||||||
8: { serviceID: 17, code: 'C6-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
8: { serviceID: 17, ref: 'C6-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
||||||
9: { serviceID: 17, code: 'C6-2-1', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 50, minPrice: 20, defPrice: 35, desc: '国家级' },
|
9: { serviceID: 17, ref: 'C6-2-1', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 50, minPrice: 20, defPrice: 35, desc: '国家级' },
|
||||||
10: { serviceID: 17, code: 'C6-2-2', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 20, minPrice: 10, defPrice: 15, desc: '省部级' },
|
10: { serviceID: 17, ref: 'C6-2-2', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 20, minPrice: 10, defPrice: 15, desc: '省部级' },
|
||||||
11: { serviceID: 17, code: 'C6-2-3', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '其他级' },
|
11: { serviceID: 17, ref: 'C6-2-3', name: '研究及编写报告', basicParam: '文件份数', required: true, unit: '万元/份', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '其他级' },
|
||||||
12: { serviceID: 17, code: 'C6-3-1', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 80, minPrice: 50, defPrice: 65, desc: '复杂标准' },
|
12: { serviceID: 17, ref: 'C6-3-1', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 80, minPrice: 50, defPrice: 65, desc: '复杂标准' },
|
||||||
13: { serviceID: 17, code: 'C6-3-2', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 50, minPrice: 20, defPrice: 35, desc: '较复杂标准' },
|
13: { serviceID: 17, ref: 'C6-3-2', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 50, minPrice: 20, defPrice: 35, desc: '较复杂标准' },
|
||||||
14: { serviceID: 17, code: 'C6-3-3', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 20, minPrice: 10, defPrice: 15, desc: '一般标准' },
|
14: { serviceID: 17, ref: 'C6-3-3', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 20, minPrice: 10, defPrice: 15, desc: '一般标准' },
|
||||||
15: { serviceID: 17, code: 'C6-3-4', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '简单标准' },
|
15: { serviceID: 17, ref: 'C6-3-4', name: '标准与技术性指导文件的编制', basicParam: '文件与标准的数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '简单标准' },
|
||||||
16: { serviceID: 17, code: 'C6-4-1', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
16: { serviceID: 17, ref: 'C6-4-1', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
||||||
17: { serviceID: 17, code: 'C6-4-2', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
17: { serviceID: 17, ref: 'C6-4-2', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
||||||
18: { serviceID: 17, code: 'C6-4-3', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
18: { serviceID: 17, ref: 'C6-4-3', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
||||||
19: { serviceID: 17, code: 'C6-5-1', name: '培训与宣贯工作', basicParam: '项目数量', required: false, unit: '万元/次', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '培训与宣贯材料' },
|
19: { serviceID: 17, ref: 'C6-5-1', name: '培训与宣贯工作', basicParam: '项目数量', required: false, unit: '万元/次', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '培训与宣贯材料' },
|
||||||
20: { serviceID: 17, code: 'C6-5-2', name: '培训与宣贯工作', basicParam: '培训与宣贯次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '组织培训与宣贯' },
|
20: { serviceID: 17, ref: 'C6-5-2', name: '培训与宣贯工作', basicParam: '培训与宣贯次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '组织培训与宣贯' },
|
||||||
21: { serviceID: 17, code: 'C6-6', name: '测试与验证工作', basicParam: '', required: false, unit: '%', conversion: 0.01, maxPrice: 50, minPrice: 30, defPrice: 40, desc: '' },
|
21: { serviceID: 17, ref: 'C6-6', name: '测试与验证工作', basicParam: '', required: false, unit: '%', conversion: 0.01, maxPrice: 50, minPrice: 30, defPrice: 40, desc: '' },
|
||||||
22: { serviceID: 18, code: 'C7-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
22: { serviceID: 18, ref: 'C7-1', name: '组织与调研工作', basicParam: '调研次数', required: true, unit: '万元/次', conversion: 10000, maxPrice: 2, minPrice: 1, defPrice: 1.5, desc: '' },
|
||||||
23: { serviceID: 18, code: 'C7-2', name: '编制大纲', basicParam: '项目数量', required: true, unit: '万元/个', conversion: 10000, maxPrice: 3, minPrice: 2, defPrice: 2.5, desc: '包括技术与定额子目研究' },
|
23: { serviceID: 18, ref: 'C7-2', name: '编制大纲', basicParam: '项目数量', required: true, unit: '万元/个', conversion: 10000, maxPrice: 3, minPrice: 2, defPrice: 2.5, desc: '包括技术与定额子目研究' },
|
||||||
24: { serviceID: 18, code: 'C7-3', name: '数据采集与测定', basicParam: '采集组数', required: true, unit: '万元/组', conversion: 10000, maxPrice: 0.8, minPrice: 0.2, defPrice: 0.5, desc: '现场采集方式时计' },
|
24: { serviceID: 18, ref: 'C7-3', name: '数据采集与测定', basicParam: '采集组数', required: true, unit: '万元/组', conversion: 10000, maxPrice: 0.8, minPrice: 0.2, defPrice: 0.5, desc: '现场采集方式时计' },
|
||||||
25: { serviceID: 18, code: 'C7-4-1', name: '数据整理与分析', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 0.3, minPrice: 0.1, defPrice: 0.2, desc: '简单定额' },
|
25: { serviceID: 18, ref: 'C7-4-1', name: '数据整理与分析', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 0.3, minPrice: 0.1, defPrice: 0.2, desc: '简单定额' },
|
||||||
26: { serviceID: 18, code: 'C7-4-2', name: '数据整理与分析', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 3, minPrice: 0.3, defPrice: 1.65, desc: '复杂定额' },
|
26: { serviceID: 18, ref: 'C7-4-2', name: '数据整理与分析', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 3, minPrice: 0.3, defPrice: 1.65, desc: '复杂定额' },
|
||||||
27: { serviceID: 18, code: 'C7-5', name: '编写定额测定报告', basicParam: '项目数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 5, minPrice: 2, defPrice: 3.5, desc: '' },
|
27: { serviceID: 18, ref: 'C7-5', name: '编写定额测定报告', basicParam: '项目数量', required: true, unit: '万元/份', conversion: 10000, maxPrice: 5, minPrice: 2, defPrice: 3.5, desc: '' },
|
||||||
28: { serviceID: 18, code: 'C7-6-1', name: '编制定额文本和释义', basicParam: '基本费用', required: true, unit: '万元/份', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '20条定额子目内' },
|
28: { serviceID: 18, ref: 'C7-6-1', name: '编制定额文本和释义', basicParam: '基本费用', required: true, unit: '万元/份', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '20条定额子目内' },
|
||||||
29: { serviceID: 18, code: 'C7-6-2', name: '编制定额文本和释义', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 0.2, minPrice: 0.1, defPrice: 0.15, desc: '超过20条每增加1条' },
|
29: { serviceID: 18, ref: 'C7-6-2', name: '编制定额文本和释义', basicParam: '定额子目条数', required: true, unit: '万元/条', conversion: 10000, maxPrice: 0.2, minPrice: 0.1, defPrice: 0.15, desc: '超过20条每增加1条' },
|
||||||
30: { serviceID: 18, code: 'C7-7-1', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
30: { serviceID: 18, ref: 'C7-7-1', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 20, minPrice: 8, defPrice: 14, desc: '大型评审' },
|
||||||
31: { serviceID: 18, code: 'C7-7-2', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
31: { serviceID: 18, ref: 'C7-7-2', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 10, minPrice: 5, defPrice: 7.5, desc: '中型评审' },
|
||||||
32: { serviceID: 18, code: 'C7-7-3', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
32: { serviceID: 18, ref: 'C7-7-3', name: '评审与验收工作', basicParam: '评审与验收次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 6, minPrice: 3, defPrice: 4.5, desc: '小型评审' },
|
||||||
33: { serviceID: 18, code: 'C7-8-1', name: '培训与宣贯工作', basicParam: '项目数量', required: false, unit: '万元/次', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '培训与宣贯材料' },
|
33: { serviceID: 18, ref: 'C7-8-1', name: '培训与宣贯工作', basicParam: '项目数量', required: false, unit: '万元/次', conversion: 10000, maxPrice: 3, minPrice: 1, defPrice: 2, desc: '培训与宣贯材料' },
|
||||||
34:{ serviceID :18 ,code :'C7-8-2' ,name :'培训与宣贯工作' ,basicParam :'培训与宣贯次数' ,required :false ,unit :'万元/次' ,conversion :10000 ,maxPrice :1 ,minPrice :0.5 ,defPrice :0.75 ,desc :'组织培训与宣贯'},
|
34: { serviceID: 18, ref: 'C7-8-2', name: '培训与宣贯工作', basicParam: '培训与宣贯次数', required: false, unit: '万元/次', conversion: 10000, maxPrice: 1, minPrice: 0.5, defPrice: 0.75, desc: '组织培训与宣贯' },
|
||||||
35: { serviceID: 18, code: 'C7-9', name: '定额测试与验证', basicParam: '', required: false, unit: '%', conversion: 0.01, maxPrice: 50, minPrice: 30, defPrice: 40, desc: '' },
|
35: { serviceID: 18, ref: 'C7-9', name: '定额测试与验证', basicParam: '', required: false, unit: '%', conversion: 0.01, maxPrice: 50, minPrice: 30, defPrice: 40, desc: '' },
|
||||||
|
36: { serviceID: 19, ref: 'C8-1', name: 'Q≤10条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 500, desc: '' },
|
||||||
|
37: { serviceID: 19, ref: 'C8-2', name: '10条<Q≤30条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 400, desc: '' },
|
||||||
|
38: { serviceID: 19, ref: 'C8-3', name: '30条<Q≤50条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 300, desc: '' },
|
||||||
|
39: { serviceID: 19, ref: 'C8-4', name: '50条<Q≤100条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 200, desc: '' },
|
||||||
|
40: { serviceID: 19, ref: 'C8-5', name: 'Q>100条', basicParam: '价格信息数量', required: true, unit: '元/条', conversion: 1, maxPrice: null, minPrice: null, defPrice: 100, desc: '' }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const expertList = {
|
export const expertList = {
|
||||||
0: { code: 'C9-1-1', name: '技术员及其他', maxPrice: 800, minPrice: 600, defPrice: 700, manageCoe: 2.3 },
|
0: { code: 'C9-1-1', name: '技术员及其他', maxPrice: 800, minPrice: 600, defPrice: 700, manageCoe: 2.3 },
|
||||||
1: { code: 'C9-1-2', name: '助理工程师', maxPrice: 1000, minPrice: 800, defPrice: 900, manageCoe: 2.3 },
|
1: { code: 'C9-1-2', name: '助理工程师', maxPrice: 1000, minPrice: 800, defPrice: 900, manageCoe: 2.3 },
|
||||||
@@ -145,51 +153,799 @@ export const expertList = {
|
|||||||
{ code: 'C2-6', staLine: 5000, endLine: null, basic: { staPrice: 346000, rate: 20 }, optional: { staPrice: 69200, rate: 4 } },
|
{ code: 'C2-6', staLine: 5000, endLine: null, basic: { staPrice: 346000, rate: 20 }, optional: { staPrice: 69200, rate: 4 } },
|
||||||
];
|
];
|
||||||
|
|
||||||
// TODO: 补充信息服务规模计价区间后替换空数组
|
|
||||||
const infoServiceScaleCal: Array<{ staLine: number; endLine: number | null; staPrice: number; rate: number }> = []
|
const infoServiceScaleCal: Array<{ staLine: number; endLine: number | null; staPrice: number; rate: number }> = []
|
||||||
|
|
||||||
const inRange = (sv: number, staLine: number, endLine: number | null) =>
|
const inRange = (sv: number, staLine: number, endLine: number | null) =>
|
||||||
sv >= staLine && (endLine == null || sv <= endLine)
|
staLine < sv && (endLine == null || sv <= endLine)
|
||||||
|
|
||||||
export function getBasicFeeFromScale(scaleValue: unknown, scaleType: 'cost' | 'area' | 'amount') {
|
const calcScaleFee = (params: {
|
||||||
|
staPrice: number
|
||||||
|
sv: number
|
||||||
|
staLine: number
|
||||||
|
rate: number
|
||||||
|
multiplier?: number
|
||||||
|
}) => {
|
||||||
|
const multiplier = params.multiplier ?? 1
|
||||||
|
return roundTo(
|
||||||
|
toDecimal(params.staPrice).plus(
|
||||||
|
toDecimal(params.sv)
|
||||||
|
.minus(params.staLine)
|
||||||
|
.mul(multiplier)
|
||||||
|
.mul(params.rate)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBasicFeeFromScale1(scaleValue: unknown, scaleType: 'cost' | 'area' | 'amount') {
|
||||||
const sv = Number(scaleValue)
|
const sv = Number(scaleValue)
|
||||||
if (!Number.isFinite(sv) || sv <= 0) return null
|
if (!Number.isFinite(sv) || sv <= 0) return null
|
||||||
|
|
||||||
if (scaleType === 'cost') {// 造价规模
|
if (scaleType === 'cost') {
|
||||||
const targetRange = costScaleCal.find(f => inRange(sv, f.staLine, f.endLine))
|
const targetRange = costScaleCal.find(f => inRange(sv, f.staLine, f.endLine))
|
||||||
if (!targetRange) return null
|
if (!targetRange) return null
|
||||||
const delta = toDecimal(sv).minus(targetRange.staLine)
|
|
||||||
return {
|
return {
|
||||||
basic: roundTo(
|
basic: calcScaleFee({
|
||||||
toDecimal(targetRange.basic.staPrice).plus(delta.mul(10000).mul(targetRange.basic.rate))
|
staPrice: targetRange.basic.staPrice,
|
||||||
),
|
sv,
|
||||||
optional: roundTo(
|
staLine: targetRange.staLine,
|
||||||
toDecimal(targetRange.optional.staPrice).plus(delta.mul(10000).mul(targetRange.optional.rate))
|
rate: targetRange.basic.rate,
|
||||||
),
|
multiplier: 10000
|
||||||
|
}),
|
||||||
|
optional: calcScaleFee({
|
||||||
|
staPrice: targetRange.optional.staPrice,
|
||||||
|
sv,
|
||||||
|
staLine: targetRange.staLine,
|
||||||
|
rate: targetRange.optional.rate,
|
||||||
|
multiplier: 10000
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scaleType === 'area') {//用地
|
if (scaleType === 'area') {
|
||||||
const targetRange = areaScaleCal.find(f => inRange(sv, f.staLine, f.endLine))
|
const targetRange = areaScaleCal.find(f => inRange(sv, f.staLine, f.endLine))
|
||||||
if (!targetRange) return null
|
if (!targetRange) return null
|
||||||
const delta = toDecimal(sv).minus(targetRange.staLine)
|
|
||||||
return {
|
return {
|
||||||
basic: roundTo(
|
basic: calcScaleFee({
|
||||||
toDecimal(targetRange.basic.staPrice).plus(delta.mul(targetRange.basic.rate))
|
staPrice: targetRange.basic.staPrice,
|
||||||
),
|
sv,
|
||||||
optional: roundTo(
|
staLine: targetRange.staLine,
|
||||||
toDecimal(targetRange.optional.staPrice).plus(delta.mul(targetRange.optional.rate))
|
rate: targetRange.basic.rate
|
||||||
),
|
}),
|
||||||
|
optional: calcScaleFee({
|
||||||
|
staPrice: targetRange.optional.staPrice,
|
||||||
|
sv,
|
||||||
|
staLine: targetRange.staLine,
|
||||||
|
rate: targetRange.optional.rate
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const targetRange = infoServiceScaleCal.find(f => inRange(sv, f.staLine, f.endLine))
|
const targetRange = infoServiceScaleCal.find(f => inRange(sv, f.staLine, f.endLine))
|
||||||
if (!targetRange) return null
|
if (!targetRange) return null
|
||||||
const delta = toDecimal(sv).minus(targetRange.staLine)
|
|
||||||
return {
|
return {
|
||||||
basic: roundTo(
|
basic: calcScaleFee({
|
||||||
toDecimal(targetRange.staPrice).plus(delta.mul(targetRange.rate))
|
staPrice: targetRange.staPrice,
|
||||||
),
|
sv,
|
||||||
optional: 0,
|
staLine: targetRange.staLine,
|
||||||
|
rate: targetRange.rate
|
||||||
|
}),
|
||||||
|
optional: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getBasicFeeFromScale(scaleValue: unknown, scaleType: 'cost' | 'area' | 'amount') {
|
||||||
|
return getBasicFeeFromScale1(scaleValue, scaleType)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function exportFile(fileName, data) {
|
||||||
|
if (window.showSaveFilePicker) {
|
||||||
|
const handle = await window.showSaveFilePicker({
|
||||||
|
suggestedName: fileName,
|
||||||
|
types: [{
|
||||||
|
description: "Excel 文件",
|
||||||
|
accept: { "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [".xlsx"] }
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
// ecCom.WeaLoadingGlobal.start({
|
||||||
|
// tip: "下载中,结束前请勿打开文件...",
|
||||||
|
// });
|
||||||
|
try {
|
||||||
|
const workbook = await generateTemplate(data);
|
||||||
|
const buffer = await workbook.xlsx.writeBuffer();
|
||||||
|
const writable = await handle.createWritable();
|
||||||
|
await writable.write(buffer);
|
||||||
|
await writable.close();
|
||||||
|
// ecCom.WeaLoadingGlobal.destroy();
|
||||||
|
// antd.notification['success']({
|
||||||
|
// message: '下载成功!',
|
||||||
|
// });
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err:' + err);
|
||||||
|
// ecCom.WeaLoadingGlobal.destroy();
|
||||||
|
// antd.notification['error']({
|
||||||
|
// message: '下载失败!',
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const workbook = await generateTemplate(data);
|
||||||
|
const buffer = await workbook.xlsx.writeBuffer();
|
||||||
|
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||||
|
const url1 = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url1;
|
||||||
|
a.download = `${fileName}.xlsx`;
|
||||||
|
a.click();
|
||||||
|
URL.revokeObjectURL(url1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateTemplate(data) {
|
||||||
|
// 获取模板
|
||||||
|
let templateExcel = 'template20260226001test009';
|
||||||
|
let templateUrl = `https://oa.zwgczx.com/myExcelTemplate/${templateExcel}.xlsx`;
|
||||||
|
let buf = await (await fetch(templateUrl)).arrayBuffer();
|
||||||
|
let workbook = new ExcelJS.Workbook();
|
||||||
|
await workbook.xlsx.load(buf);
|
||||||
|
|
||||||
|
// 生成表格
|
||||||
|
let fm_sheet = workbook.getWorksheet('封面');
|
||||||
|
let ml_sheet = workbook.getWorksheet('目录');
|
||||||
|
let yz01_sheet = workbook.getWorksheet('预总01表');
|
||||||
|
let f01_sheet = workbook.getWorksheet('辅01表');
|
||||||
|
|
||||||
|
let now = new Date();
|
||||||
|
let year = now.getFullYear();
|
||||||
|
let month = now.getMonth() + 1;
|
||||||
|
let day = now.getDate();
|
||||||
|
|
||||||
|
fm_sheet.getRow(2).getCell(1).value = data.name;
|
||||||
|
fm_sheet.getRow(11).getCell(4).value = `${year} 年 ${month} 月 ${day} 日`;
|
||||||
|
|
||||||
|
let yz01Mod = (data.contracts.length + 1) % 4;
|
||||||
|
let yz01Num = (data.contracts.length + 1 - yz01Mod) / 4;
|
||||||
|
switch (yz01Mod) {
|
||||||
|
case 0:
|
||||||
|
yz01_sheet.spliceColumns(8, 15);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
yz01_sheet.spliceColumns(8, 11);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
yz01_sheet.spliceColumns(19, 4);
|
||||||
|
yz01_sheet.spliceColumns(8, 6);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
yz01_sheet.spliceColumns(14, 9);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (yz01Num == 0) {
|
||||||
|
yz01_sheet.spliceColumns(1, 7);
|
||||||
|
} else {
|
||||||
|
if (yz01Num > 1) {
|
||||||
|
for (let i = 0; i < yz01Num - 1; i++) {
|
||||||
|
insertAndCopyColumn(7 * (i + 1) + 1, [1, 2, 3, 4, 5, 6, 7], yz01_sheet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < yz01Num; i++) {
|
||||||
|
yz01_sheet.mergeCells(6, i * 7 + 2, 6, i * 7 + 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (yz01Mod > 0) {
|
||||||
|
yz01_sheet.mergeCells(6, yz01Num * 7 + 2, 6, yz01Num * 7 + 3 + yz01Mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
let f01Mod = (data.contracts.length) % 3;
|
||||||
|
let f01Num = (data.contracts.length - f01Mod) / 3;
|
||||||
|
switch (f01Mod) {
|
||||||
|
case 0:
|
||||||
|
f01_sheet.spliceColumns(11, 14);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
f01_sheet.spliceColumns(11, 8);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
f01_sheet.spliceColumns(19, 6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (f01Num == 0) {
|
||||||
|
f01_sheet.spliceColumns(1, 10);
|
||||||
|
} else {
|
||||||
|
if (f01Num > 1) {
|
||||||
|
for (let i = 0; i < f01Num - 1; i++) {
|
||||||
|
insertAndCopyColumn(10 * (i + 1) + 1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], f01_sheet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < f01Num; i++) {
|
||||||
|
f01_sheet.mergeCells(1, i * 10 + 1, 2, i * 10 + 1);
|
||||||
|
f01_sheet.mergeCells(1, i * 10 + 2, 2, i * 10 + 2);
|
||||||
|
f01_sheet.mergeCells(1, i * 10 + 3, 2, i * 10 + 3);
|
||||||
|
f01_sheet.mergeCells(1, i * 10 + 10, 2, i * 10 + 10);
|
||||||
|
f01_sheet.mergeCells(1, i * 10 + 4, 1, i * 10 + 5);
|
||||||
|
f01_sheet.mergeCells(1, i * 10 + 6, 1, i * 10 + 7);
|
||||||
|
f01_sheet.mergeCells(1, i * 10 + 8, 1, i * 10 + 9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (f01Mod > 0) {
|
||||||
|
f01_sheet.mergeCells(1, f01Num * 10 + 1, 2, f01Num * 10 + 1);
|
||||||
|
f01_sheet.mergeCells(1, f01Num * 10 + 2, 2, f01Num * 10 + 2);
|
||||||
|
f01_sheet.mergeCells(1, f01Num * 10 + 3, 2, f01Num * 10 + 3);
|
||||||
|
f01_sheet.mergeCells(1, f01Num * 10 + 2 * f01Mod + 4, 2, f01Num * 10 + 2 * f01Mod + 4);
|
||||||
|
f01_sheet.mergeCells(1, f01Num * 10 + 4, 1, f01Num * 10 + 5);
|
||||||
|
if (f01Mod == 2) f01_sheet.mergeCells(1, f01Num * 10 + 6, 1, f01Num * 10 + 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ml_slotRow = 13;
|
||||||
|
let ml_number = 1;
|
||||||
|
let allServices = [];
|
||||||
|
data.contracts.forEach((ci, index) => {
|
||||||
|
ci.method1 = [];
|
||||||
|
ci.method2 = [];
|
||||||
|
ci.method3 = [];
|
||||||
|
ci.method4 = [];
|
||||||
|
ci.services.forEach(si => {
|
||||||
|
if (si.method1) {
|
||||||
|
ci.method1.push(si.id);
|
||||||
|
}
|
||||||
|
if (si.method2) {
|
||||||
|
ci.method2.push(si.id);
|
||||||
|
}
|
||||||
|
if (si.method3) ci.method3.push(si.id);
|
||||||
|
if (si.method4) ci.method4.push(si.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
let ml_sourceRows = [ml_sheet.getRow(6)];
|
||||||
|
let sheet_1 = copyWorksheet(workbook, '预i-1表', `预${index + 1}-1表`);
|
||||||
|
let sheet_2;
|
||||||
|
let sheet_2_1;
|
||||||
|
let sheet_2_2;
|
||||||
|
let sheet_3;
|
||||||
|
let sheet_4;
|
||||||
|
let sheet_4_1;
|
||||||
|
if (ci.method1.length || ci.method2.length) {
|
||||||
|
ml_sourceRows.push(ml_sheet.getRow(7));
|
||||||
|
sheet_2 = copyWorksheet(workbook, '预i-2表', `预${index + 1}-2表`);
|
||||||
|
if (ci.method1.length) {
|
||||||
|
ml_sourceRows.push(ml_sheet.getRow(8));
|
||||||
|
sheet_2_1 = copyWorksheet(workbook, '预i-2-1表', `预${index + 1}-2-1表`);
|
||||||
|
}
|
||||||
|
if (ci.method2.length) {
|
||||||
|
ml_sourceRows.push(ml_sheet.getRow(9));
|
||||||
|
sheet_2_2 = copyWorksheet(workbook, '预i-2-2表', `预${index + 1}-2-2表`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ci.method3.length) {
|
||||||
|
ml_sourceRows.push(ml_sheet.getRow(10));
|
||||||
|
sheet_3 = copyWorksheet(workbook, '预i-3表', `预${index + 1}-3表`);
|
||||||
|
}
|
||||||
|
if (ci.method4.length) {
|
||||||
|
ml_sourceRows.push(ml_sheet.getRow(11));
|
||||||
|
ml_sourceRows.push(ml_sheet.getRow(12));
|
||||||
|
sheet_4 = copyWorksheet(workbook, '预i-4表', `预${index + 1}-4表`);
|
||||||
|
sheet_4_1 = copyWorksheet(workbook, '预i-4-1表', `预${index + 1}-4-1表`);
|
||||||
|
}
|
||||||
|
|
||||||
|
cusInsertRowFunc(ml_slotRow, ml_sourceRows, ml_sheet, () => ml_slotRow++, (targetCell, sourceCell, colNumber) => {
|
||||||
|
if (colNumber == 1) {
|
||||||
|
targetCell.value = ml_number++;
|
||||||
|
} else if (colNumber == 2) {
|
||||||
|
targetCell.value = sourceCell.value.replaceAll('第i合同', ci.name);
|
||||||
|
} else if (colNumber == 3) {
|
||||||
|
targetCell.value = sourceCell.value.replaceAll('i', index + 1);
|
||||||
|
} else {
|
||||||
|
targetCell.value = sourceCell.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let num_2 = 1;
|
||||||
|
let num_2_1 = 1;
|
||||||
|
let num_2_2 = 1;
|
||||||
|
let num_3 = 1;
|
||||||
|
let num_4 = 1;
|
||||||
|
let num_4_1 = 1;
|
||||||
|
ci.services.forEach((sobj, sindex) => {
|
||||||
|
let allServicesX = allServices.find(s => s.id == sobj.id);
|
||||||
|
if (allServicesX) {
|
||||||
|
allServicesX.contracts[index] = sobj.fee;
|
||||||
|
} else {
|
||||||
|
allServices.push({
|
||||||
|
id: sobj.id,
|
||||||
|
contracts: {
|
||||||
|
[index]: sobj.fee,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let serviceX = serviceList[sobj.id];
|
||||||
|
cusInsertRowFunc(4 + sindex, [sheet_1.getRow(3)], sheet_1, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = sindex + 1;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref;
|
||||||
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
|
targetRow.getCell(4).value = sobj.method1 ? sobj.method1.fee : '';
|
||||||
|
targetRow.getCell(5).value = sobj.method2 ? sobj.method2.fee : '';
|
||||||
|
targetRow.getCell(6).value = sobj.method3 ? sobj.method3.fee : '';
|
||||||
|
targetRow.getCell(7).value = sobj.method4 ? sobj.method4.fee : '';
|
||||||
|
targetRow.getCell(8).value = sobj.fee;
|
||||||
|
});
|
||||||
|
if (sobj.method1 || sobj.method2) {
|
||||||
|
let det1 = sobj.method1 ? sobj.method1.det.map(m => m.major) : [];
|
||||||
|
let det2 = sobj.method2 ? sobj.method2.det.map(m => m.major) : [];
|
||||||
|
let allDet = [...(new Set([...det1, ...det2]))].sort((a, b) => a - b).map(m => {
|
||||||
|
return {
|
||||||
|
major: m,
|
||||||
|
mth1: det1.includes(m) ? sobj.method1.det[det1.indexOf(m)] : null,
|
||||||
|
mth2: det2.includes(m) ? sobj.method2.det[det2.indexOf(m)] : null,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
cusInsertRowFunc(4 + num_2, [sheet_2.getRow(4)], sheet_2, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_2++;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref;
|
||||||
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
|
targetRow.getCell(4).value = '/';
|
||||||
|
targetRow.getCell(5).value = '/';
|
||||||
|
if (sobj.method1) {
|
||||||
|
targetRow.getCell(6).value = sobj.method1.basicFee;
|
||||||
|
targetRow.getCell(7).value = sobj.method1.fee;
|
||||||
|
cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_2_1++;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref;
|
||||||
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
|
targetRow.getCell(4).value = sobj.method1.cost;
|
||||||
|
targetRow.getCell(5).value = '/';
|
||||||
|
targetRow.getCell(6).value = sobj.method1.basicFee_basic;
|
||||||
|
targetRow.getCell(7).value = '/';
|
||||||
|
targetRow.getCell(8).value = sobj.method1.basicFee_optional;
|
||||||
|
targetRow.getCell(9).value = sobj.method1.basicFee;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (sobj.method2) {
|
||||||
|
targetRow.getCell(8).value = sobj.method2.basicFee;
|
||||||
|
targetRow.getCell(9).value = sobj.method2.fee;
|
||||||
|
cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_2_2++;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref;
|
||||||
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
|
targetRow.getCell(4).value = sobj.method2.area;
|
||||||
|
targetRow.getCell(5).value = '/';
|
||||||
|
targetRow.getCell(6).value = sobj.method2.basicFee_basic;
|
||||||
|
targetRow.getCell(7).value = '/';
|
||||||
|
targetRow.getCell(8).value = sobj.method2.basicFee_optional;
|
||||||
|
targetRow.getCell(9).value = sobj.method2.basicFee;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
allDet.forEach((m, mindex) => {
|
||||||
|
let majorX = majorList[m.major];
|
||||||
|
cusInsertRowFunc(4 + num_2, [sheet_2.getRow(4)], sheet_2, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_2++;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref + '-' + (mindex + 1);
|
||||||
|
targetRow.getCell(3).value = majorX.name;
|
||||||
|
if (m.mth1) {
|
||||||
|
targetRow.getCell(4).value = m.mth1.serviceCoe;
|
||||||
|
targetRow.getCell(5).value = m.mth1.majorCoe;
|
||||||
|
targetRow.getCell(6).value = m.mth1.basicFee;
|
||||||
|
targetRow.getCell(7).value = m.mth1.fee;
|
||||||
|
targetRow.getCell(8).value = 0;
|
||||||
|
targetRow.getCell(9).value = 0;
|
||||||
|
cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_2_1++;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref + '-' + (mindex + 1);
|
||||||
|
targetRow.getCell(3).value = majorX.name;
|
||||||
|
targetRow.getCell(4).value = m.mth1.cost;
|
||||||
|
targetRow.getCell(5).value = m.mth1.basicFormula;
|
||||||
|
targetRow.getCell(6).value = m.mth1.basicFee_basic;
|
||||||
|
targetRow.getCell(7).value = m.mth1.optionalFormula;
|
||||||
|
targetRow.getCell(8).value = m.mth1.basicFee_optional;
|
||||||
|
targetRow.getCell(9).value = m.mth1.basicFee;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
targetRow.getCell(4).value = m.mth2.serviceCoe;
|
||||||
|
targetRow.getCell(5).value = m.mth2.majorCoe;
|
||||||
|
targetRow.getCell(6).value = 0;
|
||||||
|
targetRow.getCell(7).value = 0;
|
||||||
|
targetRow.getCell(8).value = m.mth2.basicFee;
|
||||||
|
targetRow.getCell(9).value = m.mth2.fee;
|
||||||
|
cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_2_2++;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref + '-' + (mindex + 1);
|
||||||
|
targetRow.getCell(3).value = majorX.name;
|
||||||
|
targetRow.getCell(4).value = m.mth2.area;
|
||||||
|
targetRow.getCell(5).value = m.mth2.basicFormula;
|
||||||
|
targetRow.getCell(6).value = m.mth2.basicFee_basic;
|
||||||
|
targetRow.getCell(7).value = m.mth2.optionalFormula;
|
||||||
|
targetRow.getCell(8).value = m.mth2.basicFee_optional;
|
||||||
|
targetRow.getCell(9).value = m.mth2.basicFee;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (sobj.method3) {
|
||||||
|
cusInsertRowFunc(3 + num_3, [sheet_3.getRow(3)], sheet_3, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_3++;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref;
|
||||||
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
|
targetRow.getCell(4).value = '/';
|
||||||
|
targetRow.getCell(5).value = '/';
|
||||||
|
targetRow.getCell(6).value = '/';
|
||||||
|
targetRow.getCell(7).value = sobj.method3.basicFee;
|
||||||
|
targetRow.getCell(8).value = '/';
|
||||||
|
targetRow.getCell(9).value = sobj.method3.fee;
|
||||||
|
});
|
||||||
|
sobj.method3.det.forEach((tobj, tindex) => {
|
||||||
|
const taskX = taskList[tobj.task];
|
||||||
|
cusInsertRowFunc(3 + num_3, [sheet_3.getRow(3)], sheet_3, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_3++;
|
||||||
|
targetRow.getCell(2).value = taskX.ref;
|
||||||
|
targetRow.getCell(3).value = taskX.name + (taskX.desc ? `(${taskX.desc})` : '');
|
||||||
|
targetRow.getCell(4).value = taskX.basicParam;
|
||||||
|
targetRow.getCell(5).value = tobj.price;
|
||||||
|
targetRow.getCell(6).value = tobj.amount;
|
||||||
|
targetRow.getCell(7).value = tobj.basicFee;
|
||||||
|
targetRow.getCell(8).value = tobj.serviceCoe;
|
||||||
|
targetRow.getCell(9).value = tobj.fee;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (sobj.method4) {
|
||||||
|
cusInsertRowFunc(4 + num_4, [sheet_4.getRow(4)], sheet_4, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_4++;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref;
|
||||||
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
|
targetRow.getCell(4).value = sobj.method4.person_num;
|
||||||
|
targetRow.getCell(5).value = sobj.method4.work_day;
|
||||||
|
targetRow.getCell(6).value = sobj.method4.fee;
|
||||||
|
});
|
||||||
|
cusInsertRowFunc(5 + num_4_1, [sheet_4_1.getRow(5)], sheet_4_1, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_4_1++;
|
||||||
|
targetRow.getCell(2).value = serviceX.ref;
|
||||||
|
targetRow.getCell(3).value = serviceX.name;
|
||||||
|
targetRow.getCell(4).value = '/';
|
||||||
|
targetRow.getCell(5).value = '/';
|
||||||
|
targetRow.getCell(6).value = '/';
|
||||||
|
targetRow.getCell(7).value = sobj.method4.person_num;
|
||||||
|
targetRow.getCell(8).value = sobj.method4.work_day;
|
||||||
|
targetRow.getCell(9).value = sobj.method4.fee;
|
||||||
|
});
|
||||||
|
sobj.method4.det.forEach((eobj, eindex) => {
|
||||||
|
const expertX = expertList[eobj.expert];
|
||||||
|
cusInsertRowFunc(5 + num_4_1, [sheet_4_1.getRow(5)], sheet_4_1, (targetRow) => {
|
||||||
|
targetRow.getCell(1).value = num_4_1++;
|
||||||
|
targetRow.getCell(2).value = expertX.ref;
|
||||||
|
targetRow.getCell(3).value = expertX.name;
|
||||||
|
targetRow.getCell(4).value = `${expertX.minPrice}~${expertX.maxPrice}`;
|
||||||
|
targetRow.getCell(5).value = `${Math.round(expertX.minPrice * expertX.manageCoe)}~${Math.round(expertX.maxPrice * expertX.manageCoe)}`;
|
||||||
|
targetRow.getCell(6).value = eobj.price;
|
||||||
|
targetRow.getCell(7).value = eobj.person_num;
|
||||||
|
targetRow.getCell(8).value = eobj.work_day;
|
||||||
|
targetRow.getCell(9).value = eobj.fee;
|
||||||
|
targetRow.getCell(10).value = eobj.desc;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
allServices.sort((a, b) => a.id - b.id);
|
||||||
|
allServices.forEach((s, sindex) => {
|
||||||
|
const serviceX = serviceList[s.id];
|
||||||
|
cusInsertRowFunc(3 + sindex, [yz01_sheet.getRow(2)], yz01_sheet, (targetRow) => {
|
||||||
|
const sumCol = data.contracts.length;
|
||||||
|
let siSum = 0;
|
||||||
|
for (let i = 0; i < yz01Num; i++) {
|
||||||
|
targetRow.getCell(i * 7 + 1).value = sindex + 1;
|
||||||
|
targetRow.getCell(i * 7 + 2).value = serviceX.ref;
|
||||||
|
targetRow.getCell(i * 7 + 3).value = serviceX.name;
|
||||||
|
targetRow.getCell(i * 7 + 4).value = s.contracts[i * 4];
|
||||||
|
targetRow.getCell(i * 7 + 5).value = s.contracts[i * 4 + 1];
|
||||||
|
targetRow.getCell(i * 7 + 6).value = s.contracts[i * 4 + 2];
|
||||||
|
siSum = siSum + (Number(s.contracts[i * 4]) || 0 + Number(s.contracts[i * 4 + 1]) || 0 + Number(s.contracts[i * 4 + 2]) || 0);
|
||||||
|
if (i * 4 + 3 == sumCol) {
|
||||||
|
targetRow.getCell(i * 7 + 7).value = numberFormatter(siSum, 2);
|
||||||
|
} else {
|
||||||
|
targetRow.getCell(i * 7 + 7).value = s.contracts[i * 4 + 3];
|
||||||
|
siSum = siSum + (Number(s.contracts[i * 4 + 3]) || 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (yz01Mod) {
|
||||||
|
targetRow.getCell(yz01Num * 7 + 1).value = sindex + 1;
|
||||||
|
targetRow.getCell(yz01Num * 7 + 2).value = serviceX.ref;
|
||||||
|
targetRow.getCell(yz01Num * 7 + 3).value = serviceX.name;
|
||||||
|
if (yz01Mod == 1) {
|
||||||
|
targetRow.getCell(yz01Num * 7 + 4).value = numberFormatter(siSum, 2);
|
||||||
|
} else if (yz01Mod == 2) {
|
||||||
|
targetRow.getCell(yz01Num * 7 + 4).value = s.contracts[yz01Num * 4];
|
||||||
|
siSum = siSum + (Number(s.contracts[yz01Num * 4]) || 0);
|
||||||
|
targetRow.getCell(yz01Num * 7 + 5).value = numberFormatter(siSum, 2);
|
||||||
|
} else {
|
||||||
|
targetRow.getCell(yz01Num * 7 + 4).value = s.contracts[yz01Num * 4];
|
||||||
|
targetRow.getCell(yz01Num * 7 + 5).value = s.contracts[yz01Num * 4 + 1];
|
||||||
|
siSum = siSum + (Number(s.contracts[yz01Num * 4]) || 0 + Number(s.contracts[yz01Num * 4 + 1]) || 0);
|
||||||
|
targetRow.getCell(yz01Num * 7 + 6).value = numberFormatter(siSum, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ml_sheet.spliceRows(6, 6);
|
||||||
|
ml_sheet.spliceRows(6, 1);
|
||||||
|
ml_sheet.mergeCells(ml_slotRow - 7, 1, ml_slotRow - 7, 4);
|
||||||
|
|
||||||
|
workbook.removeWorksheet('预i-1表');
|
||||||
|
workbook.removeWorksheet('预i-2表');
|
||||||
|
workbook.removeWorksheet('预i-2-1表');
|
||||||
|
workbook.removeWorksheet('预i-2-2表');
|
||||||
|
workbook.removeWorksheet('预i-3表');
|
||||||
|
workbook.removeWorksheet('预i-4表');
|
||||||
|
workbook.removeWorksheet('预i-4-1表');
|
||||||
|
workbook.getWorksheet('辅01表').orderNo = ml_number + 2 + 10;
|
||||||
|
workbook.getWorksheet('辅02表').orderNo = ml_number + 3 + 10;
|
||||||
|
workbook.getWorksheet('辅03表').orderNo = ml_number + 4 + 10;
|
||||||
|
|
||||||
|
// workbook._worksheets.forEach(sheet => {
|
||||||
|
// if (sheet) {
|
||||||
|
// if (sheet.headerFooter.oddHeader) sheet.headerFooter.oddHeader = sheet.headerFooter.oddHeader.replace(/&([CLR])&/g, '&$1&"宋体"&');
|
||||||
|
// if (sheet.headerFooter.oddFooter) sheet.headerFooter.oddFooter = sheet.headerFooter.oddFooter.replace(/&([CLR])&/g, '&$1&"宋体"&');
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
window.workbook = workbook;
|
||||||
|
|
||||||
|
return workbook;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cusInsertRowFunc(insertRowNum, sourceRows, worksheet, RowFun, cellFun) {
|
||||||
|
// 插入行
|
||||||
|
let newRows = [];
|
||||||
|
for (let i = 0; i < sourceRows.length; i++) {
|
||||||
|
newRows.push([]);
|
||||||
|
}
|
||||||
|
worksheet.insertRows(insertRowNum, newRows);
|
||||||
|
|
||||||
|
for (let i = 0; i < sourceRows.length; i++) {
|
||||||
|
const sourceRow = sourceRows[i];
|
||||||
|
const targetRowNum = insertRowNum + i;
|
||||||
|
const targetRow = worksheet.getRow(targetRowNum);
|
||||||
|
targetRow.height = undefined;
|
||||||
|
sourceRow.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
||||||
|
const targetCell = targetRow.getCell(colNumber);
|
||||||
|
// targetCell.value = cell.value; // 复制内容
|
||||||
|
// 复制样式
|
||||||
|
if (cell.style) {
|
||||||
|
targetCell.style = { ...cell.style };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cellFun) {
|
||||||
|
cellFun(targetCell, cell, colNumber, targetRow, sourceRow);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (RowFun) {
|
||||||
|
RowFun(targetRow, sourceRow, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyWorksheet(workbook, sourceName, targetName) {
|
||||||
|
const source = workbook.getWorksheet(sourceName);
|
||||||
|
if (!source) throw new Error("Source sheet not found");
|
||||||
|
|
||||||
|
const target = workbook.addWorksheet(targetName, {
|
||||||
|
properties: { ...source.properties },
|
||||||
|
pageSetup: { ...source.pageSetup },
|
||||||
|
views: source.views ? JSON.parse(JSON.stringify(source.views)) : [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 复制页眉页脚(关键补充) */
|
||||||
|
if (source.headerFooter) {
|
||||||
|
target.headerFooter = JSON.parse(
|
||||||
|
JSON.stringify(source.headerFooter)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 复制合并单元格 */
|
||||||
|
Object.keys(source._merges).forEach(range => {
|
||||||
|
let rangeModel = source._merges[range].model;
|
||||||
|
target.mergeCells(rangeModel.top, rangeModel.left, rangeModel.bottom, rangeModel.right);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 复制列(宽度、样式) */
|
||||||
|
source.columns.forEach((col, i) => {
|
||||||
|
const targetCol = target.getColumn(i + 1);
|
||||||
|
targetCol.width = col.width;
|
||||||
|
targetCol.style = JSON.parse(JSON.stringify(col.style || {}));
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 复制行 & 单元格 */
|
||||||
|
source.eachRow({ includeEmpty: true }, (row, rowNumber) => {
|
||||||
|
const targetRow = target.getRow(rowNumber);
|
||||||
|
targetRow.height = undefined;
|
||||||
|
|
||||||
|
row.eachCell({ includeEmpty: true }, (cell, colNumber) => {
|
||||||
|
const targetCell = targetRow.getCell(colNumber);
|
||||||
|
|
||||||
|
// value(富文本/公式安全)
|
||||||
|
targetCell.value = cloneCellValue(cell.value);
|
||||||
|
|
||||||
|
// style(必须深拷贝)
|
||||||
|
targetCell.style = JSON.parse(JSON.stringify(cell.style || {}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertAndCopyColumn(insertAt, cols, ws) {
|
||||||
|
let insertAti = insertAt;
|
||||||
|
cols.forEach((col, index) => {
|
||||||
|
// 在 insertAti 位置插入空列
|
||||||
|
ws.spliceColumns(insertAti, 0, []);
|
||||||
|
|
||||||
|
// 插入后,col 可能需要偏移
|
||||||
|
const srcColIndex = col >= insertAti ? col + 1 + index : col;
|
||||||
|
|
||||||
|
// 复制列
|
||||||
|
copyColumn(insertAti, srcColIndex, ws);
|
||||||
|
|
||||||
|
insertAti++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyColumn(toCol, fromCol, ws) {
|
||||||
|
const srcCol = ws.getColumn(fromCol);
|
||||||
|
const dstCol = ws.getColumn(toCol);
|
||||||
|
|
||||||
|
// 列级属性
|
||||||
|
dstCol.width = srcCol.width;
|
||||||
|
dstCol.hidden = srcCol.hidden;
|
||||||
|
dstCol.style = JSON.parse(JSON.stringify(srcCol.style || {}));
|
||||||
|
|
||||||
|
// 单元格
|
||||||
|
srcCol.eachCell({ includeEmpty: true }, (cell, rowNumber) => {
|
||||||
|
const dstCell = ws.getRow(rowNumber).getCell(toCol);
|
||||||
|
dstCell.value = cloneCellValue(cell.value);
|
||||||
|
dstCell.style = JSON.parse(JSON.stringify(cell.style || {}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function cloneCellValue(value) {
|
||||||
|
if (value == null) return value;
|
||||||
|
|
||||||
|
if (typeof value === "object") {
|
||||||
|
return JSON.parse(JSON.stringify(value));
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let data1 = {
|
||||||
|
name: 'test001',
|
||||||
|
fee: 10000,
|
||||||
|
scale: [
|
||||||
|
{
|
||||||
|
major: 0,
|
||||||
|
cost: 100000,
|
||||||
|
area: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
major: 1,
|
||||||
|
cost: 100000,
|
||||||
|
area: 200,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
contracts: [
|
||||||
|
{
|
||||||
|
name: 'A合同段',
|
||||||
|
fee: 10000,
|
||||||
|
scale: [
|
||||||
|
{
|
||||||
|
major: 0,
|
||||||
|
cost: 100000,
|
||||||
|
area: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
major: 1,
|
||||||
|
cost: 100000,
|
||||||
|
area: 200,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
services: [
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
fee: 100000,
|
||||||
|
method1: { // 投资规模法
|
||||||
|
cost: 100000,
|
||||||
|
basicFee: 200,
|
||||||
|
basicFee_basic: 200,
|
||||||
|
basicFee_optional: 0,
|
||||||
|
fee: 250000,
|
||||||
|
det: [
|
||||||
|
{
|
||||||
|
major: 0,
|
||||||
|
cost: 100000,
|
||||||
|
basicFee: 200,
|
||||||
|
basicFormula: '856,000+(1,000,000,000-500,000,000)×1‰',
|
||||||
|
basicFee_basic: 200,
|
||||||
|
optionalFormula: '171,200+(1,000,000,000-500,000,000)×0.2‰',
|
||||||
|
basicFee_optional: 0,
|
||||||
|
serviceCoe: 1.1,
|
||||||
|
majorCoe: 1.2,
|
||||||
|
fee: 100000,
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
method2: { // 用地规模法
|
||||||
|
area: 1200,
|
||||||
|
basicFee: 200,
|
||||||
|
basicFee_basic: 200,
|
||||||
|
basicFee_optional: 0,
|
||||||
|
fee: 250000,
|
||||||
|
det: [
|
||||||
|
{
|
||||||
|
major: 0,
|
||||||
|
area: 1200,
|
||||||
|
basicFee: 200,
|
||||||
|
basicFormula: '106,000+(1,200-1,000)×60',
|
||||||
|
basicFee_basic: 200,
|
||||||
|
optionalFormula: '21,200+(1,200-1,000)×12',
|
||||||
|
basicFee_optional: 0,
|
||||||
|
serviceCoe: 1.1,
|
||||||
|
majorCoe: 1.2,
|
||||||
|
fee: 100000,
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
method3: { // 工作量法
|
||||||
|
basicFee: 200,
|
||||||
|
fee: 250000,
|
||||||
|
det: [
|
||||||
|
{
|
||||||
|
task: 0,
|
||||||
|
price: 100000,
|
||||||
|
amount: 10,
|
||||||
|
basicFee: 200,
|
||||||
|
serviceCoe: 1.1,
|
||||||
|
fee: 100000,
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
task: 1,
|
||||||
|
price: 100000,
|
||||||
|
amount: 10,
|
||||||
|
basicFee: 200,
|
||||||
|
serviceCoe: 1.1,
|
||||||
|
fee: 100000,
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
method4: { // 工时法
|
||||||
|
person_num: 10,
|
||||||
|
work_day: 10,
|
||||||
|
fee: 250000,
|
||||||
|
det: [
|
||||||
|
{
|
||||||
|
expert: 0,
|
||||||
|
price: 100000,
|
||||||
|
person_num: 10,
|
||||||
|
work_day: 3,
|
||||||
|
fee: 100000,
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
expert: 1,
|
||||||
|
price: 100000,
|
||||||
|
person_num: 10,
|
||||||
|
work_day: 3,
|
||||||
|
fee: 100000,
|
||||||
|
desc: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -231,5 +231,6 @@
|
|||||||
.xmMx .ag-cell.editable-cell-empty .ag-cell-value * {
|
.xmMx .ag-cell.editable-cell-empty .ag-cell-value * {
|
||||||
--ag-data-color: #94a3b8;
|
--ag-data-color: #94a3b8;
|
||||||
color: #94a3b8 !important;
|
color: #94a3b8 !important;
|
||||||
|
height:100%;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-US" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<title>Dialog Gesture Driven | Reka UI</title>
|
||||||
|
<meta name="description" content="An open-source library with unstyled, primitive components, accompanied by a variety of examples & use cases ready to be integrated into your projects.">
|
||||||
|
<meta name="generator" content="VitePress v1.6.3">
|
||||||
|
<link rel="preload stylesheet" href="/assets/style.BMneOzY2.css" as="style">
|
||||||
|
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
|
||||||
|
|
||||||
|
<script type="module" src="/assets/app.CpQGAlIw.js"></script>
|
||||||
|
<link rel="modulepreload" href="/assets/chunks/theme.dny5emIm.js">
|
||||||
|
<link rel="modulepreload" href="/assets/chunks/framework.CmFBNk3_.js">
|
||||||
|
<link rel="modulepreload" href="/assets/examples_dialog-gesture-driven.md.3-AGfNIC.lean.js">
|
||||||
|
<meta name="theme-color" content="#00C38A">
|
||||||
|
<link rel="icon" href="/logo.png">
|
||||||
|
<link rel="icon" href="/logo.svg" type="image/svg+xml">
|
||||||
|
<link rel="canonical" href="https://reka-ui.com">
|
||||||
|
<meta name="author" content="Zernonia, Khairul Haaziq, Mujahid Anuar, Max, Artem Melnyk, Eduard Predescu and Reka contributors">
|
||||||
|
<meta name="keywords" content="vue, nuxt, component-library, radix, radix-vue, reka-ui, typescript">
|
||||||
|
<meta property="og:title" content="Reka">
|
||||||
|
<meta property="og:description" content="An open-source library with unstyled, primitive components, accompanied by a variety of examples & use cases ready to be integrated into your projects.">
|
||||||
|
<meta property="og:url" content="https://reka-ui.com/">
|
||||||
|
<meta property="og:image" content="https://reka-ui.com/og.jpg">
|
||||||
|
<meta name="twitter:title" content="Reka">
|
||||||
|
<meta name="twitter:description" content="An open-source library with unstyled, primitive components, accompanied by a variety of examples & use cases ready to be integrated into your projects.">
|
||||||
|
<meta name="twitter:image" content="https://reka-ui.com/og.jpg">
|
||||||
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
|
<link rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'" href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap">
|
||||||
|
<noscript><link rel="stylesheet" crossorigin="anonymous" href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap" /></noscript>
|
||||||
|
<link rel="mask-icon" href="/logo.svg" color="#ffffff">
|
||||||
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180">
|
||||||
|
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"dark",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
||||||
|
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"><!--[--><div class="flex flex-col items-center min-h-screen h-full"><header class="w-full py-4 sticky top-0 z-20 transition-all duration-500 h-[68px] md:h-full bg-transparent backdrop-blur-0"><div class="max-w-[1440px] flex items-center justify-between mx-auto px-6"><div class="w-full justify-between md:justify-normal flex items-center gap-8"><a href="/" class="flex items-center gap-2"><img class="w-6 md:w-9" alt="Reka UI logo" src="/logo.svg"><span class="font-bold text-xl md:text-2xl">Reka</span></a><!--[--><button type="button" aria-haspopup="dialog" aria-expanded="false" data-state="closed" class="flex items-center space-x-2 text-md md:text-sm py-[7px] px-3 rounded-lg md:border border-muted md:bg-card hover:bg-muted text-muted-foreground"><!--[--><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" style="" width="1em" height="1em" viewBox="0 0 16 16"></svg><span class="hidden md:inline-flex w-24 lg:w-40 text-left">Search</span><span class="hidden md:inline-flex text-xs"><kbd>⌘ K</kbd></span><!--]--></button><!--v-if--><!--]--></div><!--[--><nav class="hidden lg:flex items-center"><!--[--><!--[--><a href="/docs/overview/getting-started" class="py-2 mx-3 text-sm font-semibold text-muted-foreground hover:text-foreground h-full inline-flex items-center">Docs</a><!--]--><!--[--><a href="/examples/checkbox-group" class="!text-primary py-2 mx-3 text-sm font-semibold text-muted-foreground hover:text-foreground h-full inline-flex items-center">Examples</a><!--]--><!--[--><a href="/showcase" class="py-2 mx-3 text-sm font-semibold text-muted-foreground hover:text-foreground h-full inline-flex items-center">Showcase</a><!--]--><!--[--><!--[--><!--[--><!--[--><button class="py-2 px-2 text-nowrap md:px-0 mx-0 md:mx-3 text-sm font-semibold text-muted-foreground hover:text-foreground h-full inline-flex items-center justify-between data-[state=open]:text-foreground" id="reka-dropdown-menu-trigger-v-1" type="button" aria-haspopup="menu" aria-expanded="false" data-state="closed"><!--[--><span>v2.8.2</span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="ml-1 text-lg" style="" width="1em" height="1em" viewBox="0 0 16 16"></svg><!--]--></button><!--v-if--><!--]--><!--]--><!--]--><!--]--><!--]--><div data-orientation="vertical" role="none" class="bg-muted h-4 w-px mx-4"><!--[--><!--]--></div><button class="w-11 h-6 flex bg-muted border border-muted-foreground/10 rounded-full relative flex-shrink-0" aria-label id="theme-toggle" role="switch" type="button" value="on" aria-checked="true" aria-required="false" data-state="checked"><!--[--><span data-state="checked" class="w-5 h-5 my-auto bg-background text-xs flex items-center justify-center text-muted-foreground border border-muted rounded-full !transition-transform translate-x-0.5 will-change-transform data-[state=checked]:translate-x-5"><!--[--><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" style="" width="1em" height="1em" viewBox="0 0 16 16"></svg><!--]--></span><!--]--><!--v-if--></button><div data-orientation="vertical" role="none" class="bg-muted h-4 w-px mx-4"><!--[--><!--]--></div><!--[--><a href="https://chat.unovue.com" aria-label="discord" target="_blank" class="w-9 h-9 bg-transparent text-muted-foreground hover:text-foreground hover:bg-muted flex items-center justify-center rounded-lg text-xl flex-shrink-0"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" style="" width="1em" height="1em" viewBox="0 0 16 16"></svg></a><a href="https://github.com/unovue/reka-ui" aria-label="github" target="_blank" class="w-9 h-9 bg-transparent text-muted-foreground hover:text-foreground hover:bg-muted flex items-center justify-center rounded-lg text-xl flex-shrink-0"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" style="" width="1em" height="1em" viewBox="0 0 16 16"></svg></a><!--]--></nav><div class="lg:hidden"><!--[--><!--[--><!--[--><button class="p-2 rounded-lg" id="reka-dropdown-menu-trigger-v-2" type="button" aria-haspopup="menu" aria-expanded="false" data-state="closed"><!--[--><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="text-lg" style="" width="1em" height="1em" viewBox="0 0 16 16"></svg><!--]--></button><!--v-if--><!--]--><!--]--><!--]--></div><!--]--></div></header><div class="max-w-[1440px] w-full h-full grow"><div class="w-full"><div class="z-0 w-full h-max absolute top-0 left-0 inset-0 pointer-events-none flex justify-center overflow-hidden"><div class="w-[108rem] flex-none flex justify-end"><img class="w-[90rem] flex-none max-w-none" decoding="async" src="/new-bg.png" alt="backdrop"></div></div><div class="border-y w-full h-12 sticky top-[4.25rem] z-10Line truncated
|
||||||
|
<script>window.__VP_HASH_MAP__=JSON.parse("{\"docs_components_accordion.md\":\"C33ZB1M7\",\"docs_components_alert-dialog.md\":\"DioEjGn3\",\"docs_components_aspect-ratio.md\":\"Cv7CxCfa\",\"docs_components_autocomplete.md\":\"Bwar3psY\",\"docs_components_avatar.md\":\"B26hfGuv\",\"docs_components_calendar.md\":\"BAt6S7MZ\",\"docs_components_checkbox.md\":\"SoQ8XpF9\",\"docs_components_collapsible.md\":\"DgWVFrwl\",\"docs_components_color-swatch-picker.md\":\"BoizDi9i\",\"docs_components_color-swatch.md\":\"BG7IGStm\",\"docs_components_combobox.md\":\"BDPYe6g6\",\"docs_components_context-menu.md\":\"DPGAeyb2\",\"docs_components_date-field.md\":\"DEGPR-vn\",\"docs_components_date-picker.md\":\"DvgwoKUn\",\"docs_components_date-range-field.md\":\"D4Ld6xMN\",\"docs_components_date-range-picker.md\":\"OWw5fMM3\",\"docs_components_dialog.md\":\"BxmwjuTs\",\"docs_components_dropdown-menu.md\":\"DOvfGYz4\",\"docs_components_editable.md\":\"SKjAD8js\",\"docs_components_hover-card.md\":\"oHcMYEoR\",\"docs_components_label.md\":\"BrbvMzN3\",\"docs_components_listbox.md\":\"CGO0aHN1\",\"docs_components_menubar.md\":\"BF0GyFf1\",\"docs_components_month-picker.md\":\"CNPWgzW4\",\"docs_components_month-range-picker.md\":\"DWMJWIJz\",\"docs_components_navigation-menu.md\":\"DZhZcqb_\",\"docs_components_number-field.md\":\"BTvlBWG-\",\"docs_components_pagination.md\":\"DYcxYpd0\",\"docs_components_pin-input.md\":\"BqLu0JBF\",\"docs_components_popover.md\":\"Dx7s5_TE\",\"docs_components_progress.md\":\"CXGdOtk5\",\"docs_components_radio-group.md\":\"1MRIfVjg\",\"docs_components_range-calendar.md\":\"CK3uQ_r4\",\"docs_components_scroll-area.md\":\"D5kAh49L\",\"docs_components_select.md\":\"I_chwbEx\",\"docs_components_separator.md\":\"BHQxCiPK\",\"docs_components_slider.md\":\"3lC8daxm\",\"docs_components_splitter.md\":\"Dqkj-xTE\",\"docs_components_stepper.md\":\"Cnp2m4Vd\",\"docs_components_switch.md\":\"UzzV_ylx\",\"docs_components_tabs.md\":\"CQ_4d6Pe\",\"docs_components_tags-input.md\":\"Csz-ELec\",\"docs_components_time-field.md\":\"B9YP0O_g\",\"docs_components_toast.md\":\"DMTHBbgW\",\"docs_components_toggle-group.md\":\"CmwhHzzF\",\"docs_components_toggle.md\":\"CQ2Ivccb\",\"docs_components_toolbar.md\":\"Df3hM2Qi\",\"docs_components_tooltip.md\":\"Bhv_Jf39\",\"docs_components_tree.md\":\"9LTBmBRi\",\"docs_components_year-picker.md\":\"63nH7pBC\",\"docs_components_year-range-picker.md\":\"BtN1CuM4\",\"docs_guides_animation.md\":\"DeV8tNd6\",\"docs_guides_composition.md\":\"DEyROfsE\",\"docs_guides_controlled-state.md\":\"BBXgd0P8\",\"docs_guides_dates.md\":\"Dy8WpC87\",\"docs_guides_i18n.md\":\"BI_3WJOd\",\"docs_guides_inject-context.md\":\"B6opSak9\",\"docs_guides_migration.md\":\"D4K8EIlQ\",\"docs_guides_namespaced-components.md\":\"dIhM8ZF6\",\"docs_guides_server-side-rendering.md\":\"BuQTNxdk\",\"docs_guides_styling.md\":\"CvcgUnLP\",\"docs_guides_virtualization.md\":\"C_v7OIte\",\"docs_overview_accessibility.md\":\"DHpAe0-q\",\"docs_overview_getting-started.md\":\"Bi74fDIw\",\"docs_overview_installation.md\":\"DNMbtp1Z\",\"docs_overview_introduction.md\":\"C7cZGLq8\",\"docs_overview_releases.md\":\"CTRcqgeR\",\"docs_utilities_config-provider.md\":\"Bq-JEzPn\",\"docs_utilities_focus-scope.md\":\"wo8dpp3t\",\"docs_utilities_presence.md\":\"DeRw9tc5\",\"docs_utilities_primitive.md\":\"BYXN4fSv\",\"docs_utilities_roving-focus.md\":\"BNYtQadJ\",\"docs_utilities_slot.md\":\"Mz4DbJd7\",\"docs_utilities_use-date-formatter.md\":\"DAfLd2oy\",\"docs_utilities_use-direction.md\":\"ByUpvALW\",\"docs_utilities_use-emit-as-props.md\":\"DmFt-lGq\",\"docs_utilities_use-filter.md\":\"DgTarmTU\",\"docs_utilities_use-forward-expose.md\":\"CDAy8Ppe\",\"docs_utilities_use-forward-props-emits.md\":\"Cx24cJNY\",\"docs_utilities_use-forward-props.md\":\"Dz4_IiEJ\",\"docs_utilities_use-id.md\":\"C_2s3jh3\",\"docs_utilities_use-locale.md\":\"XMhnCA47\",\"docs_utilities_visually-hidden.md\":\"BErjRumc\",\"examples.md\":\"C0CPyQPX\",\"examples_checkbox-group.md\":\"BK4cOtFR\",\"examples_combobox-tags-input.md\":\"CnGYA03h\",\"examples_combobox-textarea.md\":\"DlvmwmJN\",\"examples_date-picker-selection.md\":\"EbUJaOE6\",\"examples_date-picker-view-switching.md\":\"C8zA2aj8\",\"examples_dialog-command-menu.md\":\"J6BLSFfr\",\"examples_dialog-gesture-driven.md\":\"3-AGfNIC\",\"examples_listbox-transfer.md\":\"D7GNHZOe\",\"examples_progress-circular.md\":\"BGNpIvke\",\"examples_slider-number-field.md\":\"DZxINuzz\",\"examples_slider-tooltip.md\":\"Dy_dh3c-\",\"examples_tooltip-cursor.md\":\"DDY2vqmk\",\"index.md\":\"DO6daXaL\",\"meta_accordioncontent.md\":\"Dmr4v6ec\",\"meta_accordionheader.md\":\"UP1pU_Qc\",\"meta_accordionitem.md\":\"DX6gnYmC\",\"meta_accordionroot.md\":\"BfKB-JVC\",\"meta_accordiontrigger.md\":\"Dv5xubE_\",\"meta_alertdialogaction.md\":\"rLc3x65U\",\"meta_alertdialogcancel.md\":\"CRp5cNK3\",\"meta_alertdialogcontent.md\":\"D-1gFOHg\",\"meta_alertdialogdescription.md\":\"g_9_i3ak\",\"meta_alertdialogoverlay.md\":\"B3jXjgLine truncated
|
||||||
|
|
||||||
|
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v67327c56f0bb4ef8b305cae61679db8f1769101564043" integrity="sha512-rdcWY47ByXd76cbCFzznIcEaCN71jqkWBBqlwhF1SY7KubdLKZiEGeP7AyieKZlGP9hbY/MhGrwXzJC/HulNyg==" data-cf-beacon='{"version":"2024.11.0","token":"b7985468abd34854910b51518a3b2943","r":1,"server_timing":{"name":{"cfCacheStatus":true,"cfEdge":true,"cfExtPri":true,"cfL4":true,"cfOrigin":true,"cfSpeedBrain":true},"location_startswith":null}}' crossorigin="anonymous"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,528 @@
|
|||||||
|
import{c6 as qi,ac as Hi,ad as zi,ae as Xi,af as Yi,ai as Zi,I as Ji,ag as Qi,ah as _i,ab as tr}from"./chunks/theme.dny5emIm.js";import{i as er,p as nr,w as oo,H as We,a as ie,d as qe,L as re,Q as io,o as He,R as F,r as sr,O as ro,a4 as or,aD as ir,aE as rr,q as ao,aA as ar,B as lr,aC as ur,x as pr,aF as cr,I as dr,h as lo,N as fr,P as hr,y as mr,z as Se,e as b,u as j,a5 as f,U as yr,b as o,aa as et,c as gr,ai as vr}from"./chunks/framework.CmFBNk3_.js";const uo=e=>n=>typeof n=="string"&&n.startsWith(e),ze=uo("--"),Er=uo("var(--"),Xe=e=>Er(e)?br.test(e.split("/*")[0].trim()):!1,br=/var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu,Rt={};function po(e){for(const n in e)Rt[n]=e[n],ze(n)&&(Rt[n].isCSSVariable=!0)}function jt(e,n){const t=typeof e=="string"&&!n?`${e}Context`:n,s=Symbol(t);return[r=>{const l=er(s,r);if(l===void 0)throw new Error(`Injection \`${s.toString()}\` not found. Component must be used within ${Array.isArray(e)?`one of the following components: ${e.join(", ")}`:`\`${e}\``}`);return l},r=>(nr(s,r),r)]}const[xr,Tr]=jt("Motion"),[wr]=jt("LayoutGroup");function Sn(e){return e!==null&&typeof e=="object"&&typeof e.start=="function"}class _{constructor(n){this.state=n}beforeMount(){}mount(){}unmount(){}update(){}beforeUpdate(){}beforeUnmount(){}}function St(e,n,t){if(Array.isArray(e))return e.reduce((s,i)=>{const a=St(i,n,t);return a?{...s,...a}:s},{});if(typeof e=="object")return e;if(e&&n){const s=n[e];return typeof s=="function"?s(t):s}}function Fr(e,n){return typeof e!=typeof n?!0:Array.isArray(e)&&Array.isArray(n)?!Cr(e,n):e!==n}function Cr(e,n){const t=n.length;if(t!==e.length)return!1;for(let s=0;s<t;s++)if(n[s]!==e[s])return!1;return!0}function An(e){return e==null?void 0:e.startsWith("--")}const Sr=e=>e;function Ar(e){return typeof e=="number"}const Dr=["animate","circle","defs","desc","ellipse","g","image","line","filter","marker","mask","metadata","path","pattern","polygon","polyline","rect","stop","svg","switch","symbol","text","tspan","use","view","clipPath","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","foreignObject","linearGradient","radialGradient","textPath"],Pr=new Set(Dr);function co(e){return Pr.has(e)}class Vr{constructor(n){this.features=[];const{features:t=[],lazyMotionContext:s}=n.options,i=t.concat(s.features.value);this.features=i.map(r=>new r(n));const a=this.features;oo(s.features,r=>{r.forEach(l=>{if(!i.includes(l)){i.push(l);const u=new l(n);a.push(u),n.isMounted()&&(u.beforeMount(),u.mount())}})},{flush:"pre"})}mount(){this.features.forEach(n=>n.mount())}beforeMount(){this.features.forEach(n=>{var t;return(t=n.beforeMount)==null?void 0:t.call(n)})}unmount(){this.features.forEach(n=>n.unmount())}update(){this.features.forEach(n=>{var t;return(t=n.update)==null?void 0:t.call(n)})}beforeUpdate(){this.features.forEach(n=>n.beforeUpdate())}beforeUnmount(){this.features.forEach(n=>n.beforeUnmount())}}const mt=new WeakMap;function ue(e){const n=mt.get(e);n&&e.removeEventListener("motioncomplete",n),mt.delete(e)}const[Br,Mr]=jt("AnimatePresenceContext");function Rr(e){const n={initial:e.initial,custom:e.custom};oo(()=>e.custom,t=>{n.custom=t},{flush:"pre"}),Mr(n),We(()=>{n.initial=void 0})}function kr(e){return typeof e=="string"||e===!1||Array.isArray(e)}const $=e=>e,Wt=["setup","read","resolveKeyframes","preUpdate","update","preRender","render","postRender"];function Lr(e,n){let t=new Set,s=new Set,i=!1,a=!1;const r=new WeakSet;let l={delta:0,timestamp:0,isProcessing:!1};function u(p){r.has(p)&&(c.schedule(p),e()),p(l)}const c={schedule:(p,d=!1,m=!1)=>{const y=m&&i?t:s;return d&&r.add(p),y.has(p)||y.add(p),p},cancel:p=>{s.delete(p),r.delete(p)},process:p=>{if(l=p,i){a=!0;return}i=!0,[t,s]=[s,t],t.forEach(u),t.clear(),i=!1,a&&(a=!1,c.process(p))}};return c}const J={},Or=40;function fo(e,n){let t=!1,s=!0;const i={delta:0,timestamp:0,isProcessing:!1},a=()=>t=!0,r=Wt.reduce((x,A)=>(x[A]=Lr(a),x),{}),{setup:l,read:u,resolveKeyframes:c,preUpdate:p,update:d,preRender:m,render:h,postRender:y}=r,g=()=>{const x=J.useManualTiming?i.timestamp:performance.now();t=!1,J.useManualTiming||(i.delta=s?1e3/60:Math.max(Math.min(x-i.timestamp,Or),1)),i.timestamp=x,i.isProcessing=!0,l.process(i),u.process(i),c.process(i),p.process(i),d.process(i),m.process(i),h.process(i),y.process(i),i.isProcessing=!1,t&&n&&(s=!1,e(g))},v=()=>{t=!0,s=!0,i.isProcessing||e(g)};return{schedule:Wt.reduce((x,A)=>{const T=r[A];return x[A]=(D,M=!1,S=!1)=>(t||v(),T.schedule(D,M,S)),x},{}),cancel:x=>{for(let A=0;A<Wt.length;A++)r[Wt[A]].cancel(x)},state:i,steps:r}}const{schedule:V,cancel:Y,state:I,steps:pe}=fo(typeof requestAnimationFrame<"u"?requestAnimationFrame:$,!0),At=new WeaLine truncated
|
||||||
|
[data-motion-pop-id="${a.id}"] {
|
||||||
|
position: absolute !important;
|
||||||
|
width: ${u.width}px !important;
|
||||||
|
height: ${u.height}px !important;
|
||||||
|
top: ${u.top}px !important;
|
||||||
|
${c}px !important;
|
||||||
|
}
|
||||||
|
`)}function i(a){const r=n.get(a);r&&(n.delete(a),V.render(()=>{document.head.removeChild(r)}))}return{addPopStyle:s,removePopStyle:i,styles:n}}function Qs(e){return Promise.resolve().then(()=>{e()})}const Fc=qe({name:"AnimatePresence",inheritAttrs:!0,__name:"AnimatePresence",props:{mode:{default:"sync"},initial:{type:Boolean,default:!0},as:{},custom:{},onExitComplete:{},anchorX:{default:"left"}},setup(e){const n=e;Rr(n);const{addPopStyle:t,removePopStyle:s,styles:i}=wc(n);function a(p){let d=p;for(;d;){if(At.get(d))return d;d=d.firstElementChild}return null}function r(p){const d=At.get(p);d&&(s(d),d.isVShow=!0,ue(p),Qs(()=>{d.setActive("exit",!1)}))}const l=new Map;re(()=>{l.clear()});function u(p,d){var m;const h=a(p),y=At.get(h);if(!h||!y){d(),l.size===0&&((m=n.onExitComplete)==null||m.call(n));return}l.set(h,!0),ue(h),t(y);function g(v){var E,C;if((E=v==null?void 0:v.detail)!=null&&E.isExit){const x=y.visualElement.projection;if((x==null?void 0:x.animationProgress)>0&&!y.isSafeToRemove&&!y.isVShow)return;ue(h),l.delete(h),l.size===0&&((C=n.onExitComplete)==null||C.call(n)),i.has(y)?s(y):y.willUpdate("done"),d(),h.isConnected||y.unmount(!0)}}Qs(()=>{y.setActive("exit",!0),mt.set(h,g),h.addEventListener("motioncomplete",g)})}const c=ie(()=>n.mode!=="wait"?{tag:n.as}:{mode:n.mode==="wait"?"out-in":void 0});return(p,d)=>(He(),io(or(p.mode==="wait"?ir:rr),ro({css:!1},c.value,{appear:"",onEnter:r,onLeave:u}),{default:F(()=>[sr(p.$slots,"default")]),_:3},16))}});function _s(...e){const n=!Array.isArray(e[0]),t=n?0:-1,s=e[0+t],i=e[1+t],a=e[2+t],r=e[3+t],l=_o(i,a,r);return n?l(s):l}function oe(e){return(e==null?void 0:e.nodeType)===3||(e==null?void 0:e.nodeType)===8?oe(e.nextSibling):e}const[Cc]=jt("LazyMotionContext");function Sc(e){const n=xr(null),t=wr({}),s=Ki(),i=Br({}),a=Cc({features:ao([]),strict:!1}),r=ar();function l(){return t.id&&e.layoutId?`${t.id}-${e.layoutId}`:e.layoutId||void 0}function u(){return{...e,lazyMotionContext:a,layoutId:l(),transition:e.transition??s.value.transition,layoutGroup:t,motionConfig:s.value,inViewOptions:e.inViewOptions??s.value.inViewOptions,animatePresenceContext:i,initial:i.initial===!1?i.initial:e.initial===!0?void 0:e.initial}}function c(){return{...r,...u()}}const p=new Ir(c(),n);Tr(p);function d(){var h;const y=p.type==="svg",g={...r};Object.keys(r).forEach(C=>{O(r[C])&&(g[C]=r[C].get())});let v={...e.style,...y?{}:((h=p.visualElement)==null?void 0:h.latestValues)||p.baseTarget};if(y){const{attrs:C,style:x}=ta({...p.isMounted()?p.target:p.baseTarget,...v});(x.transform||C.transformOrigin)&&(x.transformOrigin=C.transformOrigin??"50% 50%",delete C.transformOrigin),x.transform&&(x.transformBox=x.transformBox??"fill-box",delete C.transformBox),Object.assign(g,C),v=x}e.drag&&e.dragListener!==!1&&Object.assign(v,{userSelect:"none",WebkitUserSelect:"none",WebkitTouchCallout:"none",touchAction:e.drag===!0?"none":`pan-${e.drag==="x"?"y":"x"}`});const E=Zr(v);return E&&(g.style=E),g}const m=lr().proxy;return ur(()=>{p.beforeMount()}),We(()=>{p.mount(oe(m.$el),c(),Dc(m))}),pr(()=>p.beforeUnmount()),re(()=>{const h=oe(m.$el);h!=null&&h.isConnected||p.unmount()}),cr(()=>{p.beforeUpdate()}),dr(()=>{p.update(c())}),{getProps:u,getAttrs:d,layoutGroup:t,state:p}}const Ac={ignoreStrict:{type:Boolean},forwardMotionProps:{type:Boolean,default:!1},asChild:{type:Boolean,default:!1},hover:{type:[String,Array,Object]},press:{type:[String,Array,Object]},inView:{type:[String,Array,Object]},focus:{type:[String,Array,Object]},whileDrag:{type:[String,Array,Object]},whileHover:{type:[String,Array,Object],default:({hover:e})=>e},whilePress:{type:[String,Array,Object],default:({press:e})=>e},whileInView:{type:[String,Array,Object],default:({inView:e})=>e},whileFocus:{type:[String,Array,Object],default:({focus:e})=>e},custom:{type:[String,Number,Object,Array]},initial:{type:[String,Array,Object,Boolean],default:void 0},animate:{type:[String,Array,Object],default:void 0},exit:{type:[String,Array,Object]},variants:{type:Object},inherit:{type:Boolean},style:{type:Object},transformTemplate:{type:Function},transition:{type:Object},layoutGroup:{type:Object},motionConfig:{type:Object},onAnimationComplete:{type:Function},onUpdate:{type:Function},layout:{type:[Boolean,String],default:!1},layoutId:{type:String,default:void 0},layoutScroll:{type:Boolean,default:!1},layoutRoot:{type:Boolean,default:!1},"data-framer-portal-id":{type:String},crossfade:{type:Boolean,default:!0},layoutDependency:{type:[String,Number,Object,Array]},onBeforeLayoutMeasure:{type:Function},onLayoutMeasure:{type:Function},onLayoutAnimationStart:{type:Function},onLayoutAnimationComplete:{type:Function},globalPressTarget:{type:Boolean},onPressStart:{type:Function},onPress:{type:Function},onPressCancel:{type:Function},onHoverStart:{type:Function},onHoverEnd:{type:Function},inViewOptions:{type:Object},onViewportEnter:{type:Function},onViewportLeave:{type:Function},drag:{type:[Boolean,String]},dragSnapToOrigin:{type:Boolean},dragDirecti
Line truncated
|
||||||
|
`)),t[72]||(t[72]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"import"),o("span",{style:{color:"#E1E4E8"}}," { Icon } "),o("span",{style:{color:"#F97583"}},"from"),o("span",{style:{color:"#9ECBFF"}}," '@iconify/vue'")],-1)),t[73]||(t[73]=f(`
|
||||||
|
`)),t[74]||(t[74]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"import"),o("span",{style:{color:"#E1E4E8"}}," { useWindowSize } "),o("span",{style:{color:"#F97583"}},"from"),o("span",{style:{color:"#9ECBFF"}}," '@vueuse/core'")],-1)),t[75]||(t[75]=f(`
|
||||||
|
`)),t[76]||(t[76]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"import"),o("span",{style:{color:"#E1E4E8"}}," { animate, AnimatePresence, Motion, useMotionValue, useMotionValueEvent, useTransform } "),o("span",{style:{color:"#F97583"}},"from"),o("span",{style:{color:"#9ECBFF"}}," 'motion-v'")],-1)),t[77]||(t[77]=f(`
|
||||||
|
`)),t[78]||(t[78]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"import"),o("span",{style:{color:"#E1E4E8"}}," { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogRoot, DialogTitle, DialogTrigger } "),o("span",{style:{color:"#F97583"}},"from"),o("span",{style:{color:"#9ECBFF"}}," 'reka-ui'")],-1)),t[79]||(t[79]=f(`
|
||||||
|
`)),t[80]||(t[80]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"import"),o("span",{style:{color:"#E1E4E8"}}," { computed, onMounted, ref } "),o("span",{style:{color:"#F97583"}},"from"),o("span",{style:{color:"#9ECBFF"}}," 'vue'")],-1)),t[81]||(t[81]=f(`
|
||||||
|
`)),t[82]||(t[82]=o("span",{class:"line"},null,-1)),t[83]||(t[83]=f(`
|
||||||
|
`)),t[84]||(t[84]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," inertiaTransition"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#E1E4E8"}}," {")],-1)),t[85]||(t[85]=f(`
|
||||||
|
`)),t[86]||(t[86]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," type: "),o("span",{style:{color:"#9ECBFF"}},"'inertia'"),o("span",{style:{color:"#F97583"}}," as"),o("span",{style:{color:"#F97583"}}," const"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[87]||(t[87]=f(`
|
||||||
|
`)),t[88]||(t[88]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," bounceStiffness: "),o("span",{style:{color:"#79B8FF"}},"300"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[89]||(t[89]=f(`
|
||||||
|
`)),t[90]||(t[90]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," bounceDamping: "),o("span",{style:{color:"#79B8FF"}},"40"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[91]||(t[91]=f(`
|
||||||
|
`)),t[92]||(t[92]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," timeConstant: "),o("span",{style:{color:"#79B8FF"}},"300"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[93]||(t[93]=f(`
|
||||||
|
`)),t[94]||(t[94]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}},"}")],-1)),t[95]||(t[95]=f(`
|
||||||
|
`)),t[96]||(t[96]=o("span",{class:"line"},null,-1)),t[97]||(t[97]=f(`
|
||||||
|
`)),t[98]||(t[98]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," staticTransition"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#E1E4E8"}}," {")],-1)),t[99]||(t[99]=f(`
|
||||||
|
`)),t[100]||(t[100]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," duration: "),o("span",{style:{color:"#79B8FF"}},"0.5"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[101]||(t[101]=f(`
|
||||||
|
`)),t[102]||(t[102]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," ease: ["),o("span",{style:{color:"#79B8FF"}},"0.32"),o("span",{style:{color:"#E1E4E8"}},", "),o("span",{style:{color:"#79B8FF"}},"0.72"),o("span",{style:{color:"#E1E4E8"}},", "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}},", "),o("span",{style:{color:"#79B8FF"}},"1"),o("span",{style:{color:"#E1E4E8"}},"],")],-1)),t[103]||(t[103]=f(`
|
||||||
|
`)),t[104]||(t[104]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}},"}")],-1)),t[105]||(t[105]=f(`
|
||||||
|
`)),t[106]||(t[106]=o("span",{class:"line"},null,-1)),t[107]||(t[107]=f(`
|
||||||
|
`)),t[108]||(t[108]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," SHEET_MARGIN"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#79B8FF"}}," 34")],-1)),t[109]||(t[109]=f(`
|
||||||
|
`)),t[110]||(t[110]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," SHEET_RADIUS"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#79B8FF"}}," 12")],-1)),t[111]||(t[111]=f(`
|
||||||
|
`)),t[112]||(t[112]=o("span",{class:"line"},null,-1)),t[113]||(t[113]=f(`
|
||||||
|
`)),t[114]||(t[114]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"let"),o("span",{style:{color:"#E1E4E8"}}," root"),o("span",{style:{color:"#F97583"}},":"),o("span",{style:{color:"#B392F0"}}," HTMLElement")],-1)),t[115]||(t[115]=f(`
|
||||||
|
`)),t[116]||(t[116]=o("span",{class:"line"},null,-1)),t[117]||(t[117]=f(`
|
||||||
|
`)),t[118]||(t[118]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}},"onMounted"),o("span",{style:{color:"#E1E4E8"}},"(() "),o("span",{style:{color:"#F97583"}},"=>"),o("span",{style:{color:"#E1E4E8"}}," {")],-1)),t[119]||(t[119]=f(`
|
||||||
|
`)),t[120]||(t[120]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," root "),o("span",{style:{color:"#F97583"}},"="),o("span",{style:{color:"#E1E4E8"}}," document.body.firstElementChild "),o("span",{style:{color:"#F97583"}},"as"),o("span",{style:{color:"#B392F0"}}," HTMLElement")],-1)),t[121]||(t[121]=f(`
|
||||||
|
`)),t[122]||(t[122]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}},"})")],-1)),t[123]||(t[123]=f(`
|
||||||
|
`)),t[124]||(t[124]=o("span",{class:"line"},null,-1)),t[125]||(t[125]=f(`
|
||||||
|
`)),t[126]||(t[126]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#E1E4E8"}}," { "),o("span",{style:{color:"#79B8FF"}},"height"),o("span",{style:{color:"#E1E4E8"}},", "),o("span",{style:{color:"#79B8FF"}},"width"),o("span",{style:{color:"#E1E4E8"}}," } "),o("span",{style:{color:"#F97583"}},"="),o("span",{style:{color:"#B392F0"}}," useWindowSize"),o("span",{style:{color:"#E1E4E8"}},"()")],-1)),t[127]||(t[127]=f(`
|
||||||
|
`)),t[128]||(t[128]=o("span",{class:"line"},null,-1)),t[129]||(t[129]=f(`
|
||||||
|
`)),t[130]||(t[130]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," open"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#B392F0"}}," ref"),o("span",{style:{color:"#E1E4E8"}},"("),o("span",{style:{color:"#79B8FF"}},"false"),o("span",{style:{color:"#E1E4E8"}},")")],-1)),t[131]||(t[131]=f(`
|
||||||
|
`)),t[132]||(t[132]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," h"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#B392F0"}}," computed"),o("span",{style:{color:"#E1E4E8"}},"(() "),o("span",{style:{color:"#F97583"}},"=>"),o("span",{style:{color:"#E1E4E8"}}," height.value "),o("span",{style:{color:"#F97583"}},"-"),o("span",{style:{color:"#79B8FF"}}," SHEET_MARGIN"),o("span",{style:{color:"#E1E4E8"}},")")],-1)),t[133]||(t[133]=f(`
|
||||||
|
`)),t[134]||(t[134]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," y"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#B392F0"}}," useMotionValue"),o("span",{style:{color:"#E1E4E8"}},"(h.value)")],-1)),t[135]||(t[135]=f(`
|
||||||
|
`)),t[136]||(t[136]=o("span",{class:"line"},null,-1)),t[137]||(t[137]=f(`
|
||||||
|
`)),t[138]||(t[138]=o("span",{class:"line"},[o("span",{style:{color:"#6A737D"}},"// Scale the body down and adjust the border radius when the sheet is open.")],-1)),t[139]||(t[139]=f(`
|
||||||
|
`)),t[140]||(t[140]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," bodyScale"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#B392F0"}}," useTransform"),o("span",{style:{color:"#E1E4E8"}},"(")],-1)),t[141]||(t[141]=f(`
|
||||||
|
`)),t[142]||(t[142]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," y,")],-1)),t[143]||(t[143]=f(`
|
||||||
|
`)),t[144]||(t[144]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," ["),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}},", h.value],")],-1)),t[145]||(t[145]=f(`
|
||||||
|
`)),t[146]||(t[146]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," [(width.value "),o("span",{style:{color:"#F97583"}},"-"),o("span",{style:{color:"#79B8FF"}}," SHEET_MARGIN"),o("span",{style:{color:"#E1E4E8"}},") "),o("span",{style:{color:"#F97583"}},"/"),o("span",{style:{color:"#E1E4E8"}}," width.value, "),o("span",{style:{color:"#79B8FF"}},"1"),o("span",{style:{color:"#E1E4E8"}},"],")],-1)),t[147]||(t[147]=f(`
|
||||||
|
`)),t[148]||(t[148]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}},")")],-1)),t[149]||(t[149]=f(`
|
||||||
|
`)),t[150]||(t[150]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," bodyTranslate"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#B392F0"}}," useTransform"),o("span",{style:{color:"#E1E4E8"}},"(y, ["),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}},", h.value], ["),o("span",{style:{color:"#79B8FF"}},"SHEET_MARGIN"),o("span",{style:{color:"#F97583"}}," -"),o("span",{style:{color:"#79B8FF"}}," SHEET_RADIUS"),o("span",{style:{color:"#E1E4E8"}},", "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}},"])")],-1)),t[151]||(t[151]=f(`
|
||||||
|
`)),t[152]||(t[152]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}},"const"),o("span",{style:{color:"#79B8FF"}}," bodyBorderRadius"),o("span",{style:{color:"#F97583"}}," ="),o("span",{style:{color:"#B392F0"}}," useTransform"),o("span",{style:{color:"#E1E4E8"}},"(y, ["),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}},", h.value], ["),o("span",{style:{color:"#79B8FF"}},"SHEET_RADIUS"),o("span",{style:{color:"#E1E4E8"}},", "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}},"])")],-1)),t[153]||(t[153]=f(`
|
||||||
|
`)),t[154]||(t[154]=o("span",{class:"line"},null,-1)),t[155]||(t[155]=f(`
|
||||||
|
`)),t[156]||(t[156]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}},"useMotionValueEvent"),o("span",{style:{color:"#E1E4E8"}},"(bodyScale, "),o("span",{style:{color:"#9ECBFF"}},"'change'"),o("span",{style:{color:"#E1E4E8"}},", "),o("span",{style:{color:"#FFAB70"}},"v"),o("span",{style:{color:"#F97583"}}," =>"),o("span",{style:{color:"#E1E4E8"}}," root.style.scale "),o("span",{style:{color:"#F97583"}},"="),o("span",{style:{color:"#9ECBFF"}}," `${"),o("span",{style:{color:"#E1E4E8"}},"v"),o("span",{style:{color:"#9ECBFF"}},"}`"),o("span",{style:{color:"#E1E4E8"}},")")],-1)),t[157]||(t[157]=f(`
|
||||||
|
`)),t[158]||(t[158]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}},"useMotionValueEvent"),o("span",{style:{color:"#E1E4E8"}},"(")],-1)),t[159]||(t[159]=f(`
|
||||||
|
`)),t[160]||(t[160]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," bodyTranslate,")],-1)),t[161]||(t[161]=f(`
|
||||||
|
`)),t[162]||(t[162]=o("span",{class:"line"},[o("span",{style:{color:"#9ECBFF"}}," 'change'"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[163]||(t[163]=f(`
|
||||||
|
`)),t[164]||(t[164]=o("span",{class:"line"},[o("span",{style:{color:"#FFAB70"}}," v"),o("span",{style:{color:"#F97583"}}," =>"),o("span",{style:{color:"#E1E4E8"}}," root.style.translate "),o("span",{style:{color:"#F97583"}},"="),o("span",{style:{color:"#9ECBFF"}}," `0 ${"),o("span",{style:{color:"#E1E4E8"}},"v"),o("span",{style:{color:"#9ECBFF"}},"}px`"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[165]||(t[165]=f(`
|
||||||
|
`)),t[166]||(t[166]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}},")")],-1)),t[167]||(t[167]=f(`
|
||||||
|
`)),t[168]||(t[168]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}},"useMotionValueEvent"),o("span",{style:{color:"#E1E4E8"}},"(")],-1)),t[169]||(t[169]=f(`
|
||||||
|
`)),t[170]||(t[170]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," bodyBorderRadius,")],-1)),t[171]||(t[171]=f(`
|
||||||
|
`)),t[172]||(t[172]=o("span",{class:"line"},[o("span",{style:{color:"#9ECBFF"}}," 'change'"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[173]||(t[173]=f(`
|
||||||
|
`)),t[174]||(t[174]=o("span",{class:"line"},[o("span",{style:{color:"#FFAB70"}}," v"),o("span",{style:{color:"#F97583"}}," =>"),o("span",{style:{color:"#E1E4E8"}}," root.style.borderRadius "),o("span",{style:{color:"#F97583"}},"="),o("span",{style:{color:"#9ECBFF"}}," `${"),o("span",{style:{color:"#E1E4E8"}},"v"),o("span",{style:{color:"#9ECBFF"}},"}px`"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[175]||(t[175]=f(`
|
||||||
|
`)),t[176]||(t[176]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}},")")],-1)),t[177]||(t[177]=f(`
|
||||||
|
`)),t[178]||(t[178]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}},"</"),o("span",{style:{color:"#85E89D"}},"script"),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[179]||(t[179]=f(`
|
||||||
|
`)),t[180]||(t[180]=o("span",{class:"line"},null,-1)),t[181]||(t[181]=f(`
|
||||||
|
`)),t[182]||(t[182]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}},"<"),o("span",{style:{color:"#85E89D"}},"template"),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[183]||(t[183]=f(`
|
||||||
|
`)),o("span",Kc,[t[2]||(t[2]=o("span",{style:{color:"#E1E4E8"}}," <",-1)),o("span",Gc,[b(l,{name:"DialogRoot"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "defaultOpen",
|
||||||
|
"description": "<p>The open state of the dialog when it is initially rendered. Use when you do not need to control its open state.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false,
|
||||||
|
"default": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "modal",
|
||||||
|
"description": "<p>The modality of the dialog When set to <code>true</code>, <br>\\ninteraction with outside elements will be disabled and only dialog content will be visible to screen readers.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false,
|
||||||
|
"default": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "open",
|
||||||
|
"description": "<p>The controlled open state of the dialog. Can be binded as <code>v-model:open</code>.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`}),b(r,{title:"emits",data:`[
|
||||||
|
{
|
||||||
|
"name": "update:open",
|
||||||
|
"description": "<p>Event handler called when the open state of the dialog changes.</p>\\n",
|
||||||
|
"type": "[value: boolean]"
|
||||||
|
}
|
||||||
|
]`}),b(r,{title:"slots",data:`[
|
||||||
|
{
|
||||||
|
"name": "open",
|
||||||
|
"description": "<p>Current open state</p>\\n",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "close",
|
||||||
|
"description": "<p>Close the dialog</p>\\n",
|
||||||
|
"type": "(): void"
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[1]||(t[1]=f("DialogRoot"))]),_:1,__:[1]})]),t[3]||(t[3]=o("span",{style:{color:"#B392F0"}}," v-model",-1)),t[4]||(t[4]=o("span",{style:{color:"#E1E4E8"}},":",-1)),t[5]||(t[5]=o("span",{style:{color:"#B392F0"}},"open",-1)),t[6]||(t[6]=o("span",{style:{color:"#E1E4E8"}},"=",-1)),t[7]||(t[7]=o("span",{style:{color:"#9ECBFF"}},'"',-1)),t[8]||(t[8]=o("span",{style:{color:"#E1E4E8"}},"open",-1)),t[9]||(t[9]=o("span",{style:{color:"#9ECBFF"}},'"',-1)),t[10]||(t[10]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[184]||(t[184]=f(`
|
||||||
|
`)),o("span",Wc,[t[12]||(t[12]=o("span",{style:{color:"#E1E4E8"}}," <",-1)),o("span",qc,[b(l,{name:"DialogTrigger"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"button\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[11]||(t[11]=f("DialogTrigger"))]),_:1,__:[11]})]),t[13]||(t[13]=o("span",{style:{color:"#B392F0"}}," class",-1)),t[14]||(t[14]=o("span",{style:{color:"#E1E4E8"}},"=",-1)),t[15]||(t[15]=o("span",{style:{color:"#9ECBFF"}},'"dark:text-white inline-flex items-center bg-background dark:bg-muted px-3 py-2 rounded-lg text-sm border border-muted-foreground/30"',-1)),t[16]||(t[16]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[185]||(t[185]=f(`
|
||||||
|
`)),t[186]||(t[186]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," Open sheet")],-1)),t[187]||(t[187]=f(`
|
||||||
|
`)),o("span",Hc,[t[18]||(t[18]=o("span",{style:{color:"#E1E4E8"}}," </",-1)),o("span",zc,[b(l,{name:"DialogTrigger"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"button\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[17]||(t[17]=f("DialogTrigger"))]),_:1,__:[17]})]),t[19]||(t[19]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[188]||(t[188]=f(`
|
||||||
|
`)),t[189]||(t[189]=o("span",{class:"line"},null,-1)),t[190]||(t[190]=f(`
|
||||||
|
`)),o("span",Xc,[t[21]||(t[21]=o("span",{style:{color:"#E1E4E8"}}," <",-1)),o("span",Yc,[b(l,{name:"DialogPortal"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "defer",
|
||||||
|
"description": "<p>Defer the resolving of a Teleport target until other parts of the\\napplication have mounted (requires Vue 3.5.0+)</p>\\n<p><a href=\\"https://vuejs.org/guide/built-ins/teleport.html#deferred-teleport\\" target=\\"_blank\\">reference</a></p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "disabled",
|
||||||
|
"description": "<p>Disable teleport and render the component inline</p>\\n<p><a href=\\"https://vuejs.org/guide/built-ins/teleport.html#disabling-teleport\\" target=\\"_blank\\">reference</a></p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "forceMount",
|
||||||
|
"description": "<p>Used to force mounting when more control is needed. Useful when\\ncontrolling animation with Vue animation libraries.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "to",
|
||||||
|
"description": "<p>Vue native teleport component prop <code>:to</code></p>\\n<p><a href=\\"https://vuejs.org/guide/built-ins/teleport.html#basic-usage\\" target=\\"_blank\\">reference</a></p>\\n",
|
||||||
|
"type": "string | HTMLElement",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[20]||(t[20]=f("DialogPortal"))]),_:1,__:[20]})]),t[22]||(t[22]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[191]||(t[191]=f(`
|
||||||
|
`)),t[192]||(t[192]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," <"),o("span",{style:{color:"#85E89D"}},"AnimatePresence")],-1)),t[193]||(t[193]=f(`
|
||||||
|
`)),t[194]||(t[194]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}}," multiple")],-1)),t[195]||(t[195]=f(`
|
||||||
|
`)),t[196]||(t[196]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}}," as"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"div"')],-1)),t[197]||(t[197]=f(`
|
||||||
|
`)),t[198]||(t[198]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," >")],-1)),t[199]||(t[199]=f(`
|
||||||
|
`)),o("span",Zc,[t[24]||(t[24]=o("span",{style:{color:"#E1E4E8"}}," <",-1)),o("span",Jc,[b(l,{name:"DialogOverlay"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"div\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "forceMount",
|
||||||
|
"description": "<p>Used to force mounting when more control is needed. Useful when\\ncontrolling animation with Vue animation libraries.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[23]||(t[23]=f("DialogOverlay"))]),_:1,__:[23]})]),t[25]||(t[25]=o("span",{style:{color:"#B392F0"}}," as-child",-1)),t[26]||(t[26]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[200]||(t[200]=f(`
|
||||||
|
`)),t[201]||(t[201]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," <"),o("span",{style:{color:"#85E89D"}},"Motion")],-1)),t[202]||(t[202]=f(`
|
||||||
|
`)),t[203]||(t[203]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}}," class"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"fixed inset-0 z-10 bg-background/60"')],-1)),t[204]||(t[204]=f(`
|
||||||
|
`)),t[205]||(t[205]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"initial"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"{ opacity: "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}}," }"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[206]||(t[206]=f(`
|
||||||
|
`)),t[207]||(t[207]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"animate"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"{ opacity: "),o("span",{style:{color:"#79B8FF"}},"1"),o("span",{style:{color:"#E1E4E8"}}," }"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[208]||(t[208]=f(`
|
||||||
|
`)),t[209]||(t[209]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"exit"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"{ opacity: "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}}," }"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[210]||(t[210]=f(`
|
||||||
|
`)),t[211]||(t[211]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"transition"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"staticTransition"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[212]||(t[212]=f(`
|
||||||
|
`)),t[213]||(t[213]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," />")],-1)),t[214]||(t[214]=f(`
|
||||||
|
`)),o("span",Qc,[t[28]||(t[28]=o("span",{style:{color:"#E1E4E8"}}," </",-1)),o("span",_c,[b(l,{name:"DialogOverlay"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"div\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "forceMount",
|
||||||
|
"description": "<p>Used to force mounting when more control is needed. Useful when\\ncontrolling animation with Vue animation libraries.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[27]||(t[27]=f("DialogOverlay"))]),_:1,__:[27]})]),t[29]||(t[29]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[215]||(t[215]=f(`
|
||||||
|
`)),t[216]||(t[216]=o("span",{class:"line"},null,-1)),t[217]||(t[217]=f(`
|
||||||
|
`)),o("span",td,[t[31]||(t[31]=o("span",{style:{color:"#E1E4E8"}}," <",-1)),o("span",ed,[b(l,{name:"DialogContent"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"div\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "disableOutsidePointerEvents",
|
||||||
|
"description": "<p>When <code>true</code>, hover/focus/click interactions will be disabled on elements outside\\nthe <code>DismissableLayer</code>. Users will need to click twice on outside elements to\\ninteract with them: once to close the <code>DismissableLayer</code>, and again to trigger the element.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "forceMount",
|
||||||
|
"description": "<p>Used to force mounting when more control is needed. Useful when\\ncontrolling animation with Vue animation libraries.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`}),b(r,{title:"emits",data:`[
|
||||||
|
{
|
||||||
|
"name": "closeAutoFocus",
|
||||||
|
"description": "<p>Event handler called when auto-focusing on close.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: Event]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "escapeKeyDown",
|
||||||
|
"description": "<p>Event handler called when the escape key is down.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: KeyboardEvent]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "focusOutside",
|
||||||
|
"description": "<p>Event handler called when the focus moves outside of the <code>DismissableLayer</code>.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: FocusOutsideEvent]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "interactOutside",
|
||||||
|
"description": "<p>Event handler called when an interaction happens outside the <code>DismissableLayer</code>.\\nSpecifically, when a <code>pointerdown</code> event happens outside or focus moves outside of it.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: PointerDownOutsideEvent | FocusOutsideEvent]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "openAutoFocus",
|
||||||
|
"description": "<p>Event handler called when auto-focusing on open.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: Event]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pointerDownOutside",
|
||||||
|
"description": "<p>Event handler called when a <code>pointerdown</code> event happens outside of the <code>DismissableLayer</code>.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: PointerDownOutsideEvent]"
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[30]||(t[30]=f("DialogContent"))]),_:1,__:[30]})]),t[32]||(t[32]=o("span",{style:{color:"#B392F0"}}," as-child",-1)),t[33]||(t[33]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[218]||(t[218]=f(`
|
||||||
|
`)),t[219]||(t[219]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," <"),o("span",{style:{color:"#85E89D"}},"Motion")],-1)),t[220]||(t[220]=f(`
|
||||||
|
`)),t[221]||(t[221]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}}," class"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"bg-card dark:bg-stone-900 fixed inset-0 z-20 bottom-0 w-full rounded-t-xl shadow-lg will-change-transform"')],-1)),t[222]||(t[222]=f(`
|
||||||
|
`)),t[223]||(t[223]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"initial"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"{ y: h }"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[224]||(t[224]=f(`
|
||||||
|
`)),t[225]||(t[225]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"animate"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"{ y: "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}}," }"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[226]||(t[226]=f(`
|
||||||
|
`)),t[227]||(t[227]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"exit"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"{ y: h }"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[228]||(t[228]=f(`
|
||||||
|
`)),t[229]||(t[229]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"transition"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"staticTransition"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[230]||(t[230]=f(`
|
||||||
|
`)),t[231]||(t[231]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"style"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"{")],-1)),t[232]||(t[232]=f(`
|
||||||
|
`)),t[233]||(t[233]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," y,")],-1)),t[234]||(t[234]=f(`
|
||||||
|
`)),t[235]||(t[235]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," top: "),o("span",{style:{color:"#9ECBFF"}},"`${"),o("span",{style:{color:"#79B8FF"}},"SHEET_MARGIN"),o("span",{style:{color:"#9ECBFF"}},"}px`"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[236]||(t[236]=f(`
|
||||||
|
`)),t[237]||(t[237]=o("span",{class:"line"},[o("span",{style:{color:"#6A737D"}}," // Extra padding at the bottom to account for rubber band scrolling.")],-1)),t[238]||(t[238]=f(`
|
||||||
|
`)),t[239]||(t[239]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," paddingBottom: "),o("span",{style:{color:"#9ECBFF"}},"`${"),o("span",{style:{color:"#E1E4E8"}},"height"),o("span",{style:{color:"#9ECBFF"}},"}px`"),o("span",{style:{color:"#E1E4E8"}},",")],-1)),t[240]||(t[240]=f(`
|
||||||
|
`)),t[241]||(t[241]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," }"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[242]||(t[242]=f(`
|
||||||
|
`)),t[243]||(t[243]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}}," drag"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"y"')],-1)),t[244]||(t[244]=f(`
|
||||||
|
`)),t[245]||(t[245]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," :"),o("span",{style:{color:"#B392F0"}},"drag-constraints"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"{ top: "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}}," }"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[246]||(t[246]=f(`
|
||||||
|
`)),t[247]||(t[247]=o("span",{class:"line"},null,-1)),t[248]||(t[248]=f(`
|
||||||
|
`)),t[249]||(t[249]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," @"),o("span",{style:{color:"#B392F0"}},"drag-end"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"'),o("span",{style:{color:"#E1E4E8"}},"("),o("span",{style:{color:"#FFAB70"}},"e"),o("span",{style:{color:"#E1E4E8"}},", { "),o("span",{style:{color:"#FFAB70"}},"offset"),o("span",{style:{color:"#E1E4E8"}},", "),o("span",{style:{color:"#FFAB70"}},"velocity"),o("span",{style:{color:"#E1E4E8"}}," }) "),o("span",{style:{color:"#F97583"}},"=>"),o("span",{style:{color:"#E1E4E8"}}," {")],-1)),t[250]||(t[250]=f(`
|
||||||
|
`)),t[251]||(t[251]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}}," if"),o("span",{style:{color:"#E1E4E8"}}," (offset.y "),o("span",{style:{color:"#F97583"}},">"),o("span",{style:{color:"#E1E4E8"}}," height "),o("span",{style:{color:"#F97583"}},"*"),o("span",{style:{color:"#79B8FF"}}," 0.75"),o("span",{style:{color:"#F97583"}}," ||"),o("span",{style:{color:"#E1E4E8"}}," velocity.y "),o("span",{style:{color:"#F97583"}},">"),o("span",{style:{color:"#79B8FF"}}," 10"),o("span",{style:{color:"#E1E4E8"}},") {")],-1)),t[252]||(t[252]=f(`
|
||||||
|
`)),t[253]||(t[253]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," open "),o("span",{style:{color:"#F97583"}},"="),o("span",{style:{color:"#79B8FF"}}," false"),o("span",{style:{color:"#E1E4E8"}},";")],-1)),t[254]||(t[254]=f(`
|
||||||
|
`)),t[255]||(t[255]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," }")],-1)),t[256]||(t[256]=f(`
|
||||||
|
`)),t[257]||(t[257]=o("span",{class:"line"},[o("span",{style:{color:"#F97583"}}," else"),o("span",{style:{color:"#E1E4E8"}}," {")],-1)),t[258]||(t[258]=f(`
|
||||||
|
`)),t[259]||(t[259]=o("span",{class:"line"},[o("span",{style:{color:"#B392F0"}}," animate"),o("span",{style:{color:"#E1E4E8"}},"(y, "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}},", { "),o("span",{style:{color:"#F97583"}},"..."),o("span",{style:{color:"#E1E4E8"}},"inertiaTransition, min: "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}},", max: "),o("span",{style:{color:"#79B8FF"}},"0"),o("span",{style:{color:"#E1E4E8"}}," });")],-1)),t[260]||(t[260]=f(`
|
||||||
|
`)),t[261]||(t[261]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," }")],-1)),t[262]||(t[262]=f(`
|
||||||
|
`)),t[263]||(t[263]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," }"),o("span",{style:{color:"#9ECBFF"}},'"')],-1)),t[264]||(t[264]=f(`
|
||||||
|
`)),t[265]||(t[265]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," >")],-1)),t[266]||(t[266]=f(`
|
||||||
|
`)),t[267]||(t[267]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," <"),o("span",{style:{color:"#85E89D"}},"div"),o("span",{style:{color:"#B392F0"}}," class"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"mx-auto w-12 mt-2 h-1.5 rounded-full bg-gray-300 dark:bg-gray-400"'),o("span",{style:{color:"#FDAEB7","font-style":"italic"}}," /"),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[268]||(t[268]=f(`
|
||||||
|
`)),t[269]||(t[269]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," <"),o("span",{style:{color:"#85E89D"}},"div"),o("span",{style:{color:"#B392F0"}}," class"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"px-4 pb-4 outline-hidden max-w-xl mx-auto"'),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[270]||(t[270]=f(`
|
||||||
|
`)),t[271]||(t[271]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," <"),o("span",{style:{color:"#85E89D"}},"div"),o("span",{style:{color:"#B392F0"}}," class"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"flex justify-end"'),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[272]||(t[272]=f(`
|
||||||
|
`)),o("span",nd,[t[35]||(t[35]=o("span",{style:{color:"#E1E4E8"}}," <",-1)),o("span",sd,[b(l,{name:"DialogClose"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"button\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[34]||(t[34]=f("DialogClose"))]),_:1,__:[34]})]),t[36]||(t[36]=o("span",{style:{color:"#B392F0"}}," class",-1)),t[37]||(t[37]=o("span",{style:{color:"#E1E4E8"}},"=",-1)),t[38]||(t[38]=o("span",{style:{color:"#9ECBFF"}},'"dark:text-white inline-flex items-center bg-background dark: p-2 rounded-full text-sm border border-muted-foreground/30"',-1)),t[39]||(t[39]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[273]||(t[273]=f(`
|
||||||
|
`)),t[274]||(t[274]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," <"),o("span",{style:{color:"#85E89D"}},"Icon"),o("span",{style:{color:"#B392F0"}}," icon"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"lucide:x"'),o("span",{style:{color:"#E1E4E8"}}," />")],-1)),t[275]||(t[275]=f(`
|
||||||
|
`)),o("span",od,[t[41]||(t[41]=o("span",{style:{color:"#E1E4E8"}}," </",-1)),o("span",id,[b(l,{name:"DialogClose"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"button\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[40]||(t[40]=f("DialogClose"))]),_:1,__:[40]})]),t[42]||(t[42]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[276]||(t[276]=f(`
|
||||||
|
`)),t[277]||(t[277]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," </"),o("span",{style:{color:"#85E89D"}},"div"),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[278]||(t[278]=f(`
|
||||||
|
`)),o("span",rd,[t[44]||(t[44]=o("span",{style:{color:"#E1E4E8"}}," <",-1)),o("span",ad,[b(l,{name:"DialogTitle"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"h2\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[43]||(t[43]=f("DialogTitle"))]),_:1,__:[43]})]),t[45]||(t[45]=o("span",{style:{color:"#B392F0"}}," class",-1)),t[46]||(t[46]=o("span",{style:{color:"#E1E4E8"}},"=",-1)),t[47]||(t[47]=o("span",{style:{color:"#9ECBFF"}},'"text-3xl font-semibold mb-4"',-1)),t[48]||(t[48]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[279]||(t[279]=f(`
|
||||||
|
`)),t[280]||(t[280]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," Modal sheet")],-1)),t[281]||(t[281]=f(`
|
||||||
|
`)),o("span",ld,[t[50]||(t[50]=o("span",{style:{color:"#E1E4E8"}}," </",-1)),o("span",ud,[b(l,{name:"DialogTitle"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"h2\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[49]||(t[49]=f("DialogTitle"))]),_:1,__:[49]})]),t[51]||(t[51]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[282]||(t[282]=f(`
|
||||||
|
`)),o("span",pd,[t[53]||(t[53]=o("span",{style:{color:"#E1E4E8"}}," <",-1)),o("span",cd,[b(l,{name:"DialogDescription"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"p\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[52]||(t[52]=f("DialogDescription"))]),_:1,__:[52]})]),t[54]||(t[54]=o("span",{style:{color:"#B392F0"}}," class",-1)),t[55]||(t[55]=o("span",{style:{color:"#E1E4E8"}},"=",-1)),t[56]||(t[56]=o("span",{style:{color:"#9ECBFF"}},'"text-lg mb-4"',-1)),t[57]||(t[57]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[283]||(t[283]=f(`
|
||||||
|
`)),t[284]||(t[284]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," This is a dialog with a custom modal overlay built with Reka UI and Motion-v.")],-1)),t[285]||(t[285]=f(`
|
||||||
|
`)),o("span",dd,[t[59]||(t[59]=o("span",{style:{color:"#E1E4E8"}}," </",-1)),o("span",fd,[b(l,{name:"DialogDescription"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"p\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[58]||(t[58]=f("DialogDescription"))]),_:1,__:[58]})]),t[60]||(t[60]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[286]||(t[286]=f(`
|
||||||
|
`)),t[287]||(t[287]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," <"),o("span",{style:{color:"#85E89D"}},"p"),o("span",{style:{color:"#B392F0"}}," class"),o("span",{style:{color:"#E1E4E8"}},"="),o("span",{style:{color:"#9ECBFF"}},'"text-lg"'),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[288]||(t[288]=f(`
|
||||||
|
`)),t[289]||(t[289]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," Lorem ipsum dolor sit amet, consectetur adipiscing elit.")],-1)),t[290]||(t[290]=f(`
|
||||||
|
`)),t[291]||(t[291]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," Aenean sit amet nisl blandit, pellentesque eros eu,")],-1)),t[292]||(t[292]=f(`
|
||||||
|
`)),t[293]||(t[293]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," scelerisque eros. Sed cursus urna at nunc lacinia dapibus.")],-1)),t[294]||(t[294]=f(`
|
||||||
|
`)),t[295]||(t[295]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," </"),o("span",{style:{color:"#85E89D"}},"p"),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[296]||(t[296]=f(`
|
||||||
|
`)),t[297]||(t[297]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," </"),o("span",{style:{color:"#85E89D"}},"div"),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[298]||(t[298]=f(`
|
||||||
|
`)),t[299]||(t[299]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," </"),o("span",{style:{color:"#85E89D"}},"Motion"),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[300]||(t[300]=f(`
|
||||||
|
`)),o("span",hd,[t[62]||(t[62]=o("span",{style:{color:"#E1E4E8"}}," </",-1)),o("span",md,[b(l,{name:"DialogContent"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "as",
|
||||||
|
"description": "<p>The element or component this component should render as. Can be overwritten by <code>asChild</code>.</p>\\n",
|
||||||
|
"type": "AsTag | Component",
|
||||||
|
"required": false,
|
||||||
|
"default": "\\"div\\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asChild",
|
||||||
|
"description": "<p>Change the default rendered element for the one passed as a child, merging their props and behavior.</p>\\n<p>Read our <a href=\\"https://www.reka-ui.com/docs/guides/composition\\">Composition</a> guide for more details.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "disableOutsidePointerEvents",
|
||||||
|
"description": "<p>When <code>true</code>, hover/focus/click interactions will be disabled on elements outside\\nthe <code>DismissableLayer</code>. Users will need to click twice on outside elements to\\ninteract with them: once to close the <code>DismissableLayer</code>, and again to trigger the element.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "forceMount",
|
||||||
|
"description": "<p>Used to force mounting when more control is needed. Useful when\\ncontrolling animation with Vue animation libraries.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`}),b(r,{title:"emits",data:`[
|
||||||
|
{
|
||||||
|
"name": "closeAutoFocus",
|
||||||
|
"description": "<p>Event handler called when auto-focusing on close.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: Event]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "escapeKeyDown",
|
||||||
|
"description": "<p>Event handler called when the escape key is down.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: KeyboardEvent]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "focusOutside",
|
||||||
|
"description": "<p>Event handler called when the focus moves outside of the <code>DismissableLayer</code>.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: FocusOutsideEvent]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "interactOutside",
|
||||||
|
"description": "<p>Event handler called when an interaction happens outside the <code>DismissableLayer</code>.\\nSpecifically, when a <code>pointerdown</code> event happens outside or focus moves outside of it.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: PointerDownOutsideEvent | FocusOutsideEvent]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "openAutoFocus",
|
||||||
|
"description": "<p>Event handler called when auto-focusing on open.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: Event]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pointerDownOutside",
|
||||||
|
"description": "<p>Event handler called when a <code>pointerdown</code> event happens outside of the <code>DismissableLayer</code>.\\nCan be prevented.</p>\\n",
|
||||||
|
"type": "[event: PointerDownOutsideEvent]"
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[61]||(t[61]=f("DialogContent"))]),_:1,__:[61]})]),t[63]||(t[63]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[301]||(t[301]=f(`
|
||||||
|
`)),t[302]||(t[302]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}}," </"),o("span",{style:{color:"#85E89D"}},"AnimatePresence"),o("span",{style:{color:"#E1E4E8"}},">")],-1)),t[303]||(t[303]=f(`
|
||||||
|
`)),o("span",yd,[t[65]||(t[65]=o("span",{style:{color:"#E1E4E8"}}," </",-1)),o("span",gd,[b(l,{name:"DialogPortal"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "defer",
|
||||||
|
"description": "<p>Defer the resolving of a Teleport target until other parts of the\\napplication have mounted (requires Vue 3.5.0+)</p>\\n<p><a href=\\"https://vuejs.org/guide/built-ins/teleport.html#deferred-teleport\\" target=\\"_blank\\">reference</a></p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "disabled",
|
||||||
|
"description": "<p>Disable teleport and render the component inline</p>\\n<p><a href=\\"https://vuejs.org/guide/built-ins/teleport.html#disabling-teleport\\" target=\\"_blank\\">reference</a></p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "forceMount",
|
||||||
|
"description": "<p>Used to force mounting when more control is needed. Useful when\\ncontrolling animation with Vue animation libraries.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "to",
|
||||||
|
"description": "<p>Vue native teleport component prop <code>:to</code></p>\\n<p><a href=\\"https://vuejs.org/guide/built-ins/teleport.html#basic-usage\\" target=\\"_blank\\">reference</a></p>\\n",
|
||||||
|
"type": "string | HTMLElement",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[64]||(t[64]=f("DialogPortal"))]),_:1,__:[64]})]),t[66]||(t[66]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[304]||(t[304]=f(`
|
||||||
|
`)),o("span",vd,[t[68]||(t[68]=o("span",{style:{color:"#E1E4E8"}}," </",-1)),o("span",Ed,[b(l,{name:"DialogRoot"},{content:F(({})=>[b(r,{title:"props",data:`[
|
||||||
|
{
|
||||||
|
"name": "defaultOpen",
|
||||||
|
"description": "<p>The open state of the dialog when it is initially rendered. Use when you do not need to control its open state.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false,
|
||||||
|
"default": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "modal",
|
||||||
|
"description": "<p>The modality of the dialog When set to <code>true</code>, <br>\\ninteraction with outside elements will be disabled and only dialog content will be visible to screen readers.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false,
|
||||||
|
"default": "true"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "open",
|
||||||
|
"description": "<p>The controlled open state of the dialog. Can be binded as <code>v-model:open</code>.</p>\\n",
|
||||||
|
"type": "boolean",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]`}),b(r,{title:"emits",data:`[
|
||||||
|
{
|
||||||
|
"name": "update:open",
|
||||||
|
"description": "<p>Event handler called when the open state of the dialog changes.</p>\\n",
|
||||||
|
"type": "[value: boolean]"
|
||||||
|
}
|
||||||
|
]`}),b(r,{title:"slots",data:`[
|
||||||
|
{
|
||||||
|
"name": "open",
|
||||||
|
"description": "<p>Current open state</p>\\n",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "close",
|
||||||
|
"description": "<p>Close the dialog</p>\\n",
|
||||||
|
"type": "(): void"
|
||||||
|
}
|
||||||
|
]`})]),default:F(()=>[t[67]||(t[67]=f("DialogRoot"))]),_:1,__:[67]})]),t[69]||(t[69]=o("span",{style:{color:"#E1E4E8"}},">",-1))]),t[305]||(t[305]=f(`
|
||||||
|
`)),t[306]||(t[306]=o("span",{class:"line"},[o("span",{style:{color:"#E1E4E8"}},"</"),o("span",{style:{color:"#85E89D"}},"template"),o("span",{style:{color:"#E1E4E8"}},">")],-1))])])])]),default:F(()=>[b(Uc)]),_:1}),b(p,null,{default:F(()=>[t[310]||(t[310]=o("h3",{id:"dialog",tabindex:"-1",class:"group relative border-none mb-4 lg:-ml-2 lg:pl-2 lg:pr-2 w-max"},[f("Dialog "),o("a",{class:"header-anchor [&_span]:focus:opacity-100 [&_span_>_span]:focus:outline",href:"#dialog","aria-label":'Permalink to "Dialog"'},[o("span",{class:"absolute top-0 -ml-8 hidden items-center border-0 opacity-0 group-hover:opacity-100 focus:opacity-100 lg:flex"},[f(""),o("span",{class:"flex h-6 w-6 items-center justify-center rounded-md outline-2 outline-primary text-green-400 shadow-sm hover:text-green-700 hover:shadow dark:bg-primary/20 dark:text-primary/80 dark:shadow-none dark:hover:bg-primary/40 dark:hover:text-primary"},[o("svg",{width:"12",height:"12",fill:"none","aria-hidden":"true"},[o("path",{d:"M3.75 1v10M8.25 1v10M1 3.75h10M1 8.25h10",stroke:"currentColor","stroke-width":"1.5","stroke-linecap":"round"})])])])])],-1)),b(c,{type:"info",title:"Credit"},{default:F(()=>t[309]||(t[309]=[o("p",null,[f("Inspired by "),o("a",{href:"https://react-spectrum.adobe.com/react-aria/examples/framer-modal-sheet.html",target:"_blank",rel:"noreferrer"},"React Aria")],-1)])),_:1,__:[309]})]),_:1,__:[310]})])}}});export{Sd as __pageData,Ad as default};
|
||||||
|
|
||||||
@@ -0,0 +1,351 @@
|
|||||||
|
1 <script setup lang="ts">
|
||||||
|
2 import { computed, onBeforeUnmount, ref, watch, type Component ,onMounted} from 'vue'
|
||||||
|
3 import { ScrollArea } from '@/components/ui/scroll-area'
|
||||||
|
4 import { Button } from '@/components/ui/button'
|
||||||
|
5 import {
|
||||||
|
6 DialogClose,
|
||||||
|
7 DialogContent,
|
||||||
|
8 DialogOverlay,
|
||||||
|
9 DialogPortal,
|
||||||
|
10 DialogRoot,
|
||||||
|
11 DialogTitle,
|
||||||
|
12 DialogTrigger,DialogDescription
|
||||||
|
13 } from 'reka-ui'
|
||||||
|
14 import { Icon } from '@iconify/vue'
|
||||||
|
15 import { useWindowSize } from '@vueuse/core'
|
||||||
|
16 import { animate, AnimatePresence, Motion, useMotionValue, useMotionValueEvent, useTransform } from 'motion-v'
|
||||||
|
17 interface TypeLineCategory {
|
||||||
|
18 key: string
|
||||||
|
19 label: string
|
||||||
|
20 component: Component
|
||||||
|
21 }
|
||||||
|
22
|
||||||
|
23 const props = withDefaults(
|
||||||
|
24 defineProps<{
|
||||||
|
25 scene?: string
|
||||||
|
26 title?: string
|
||||||
|
27 subtitle?: string
|
||||||
|
28 copyText?: string
|
||||||
|
29 categories: TypeLineCategory[]
|
||||||
|
30 storageKey?: string
|
||||||
|
31 defaultCategory?: string
|
||||||
|
32 }>(),
|
||||||
|
33 {
|
||||||
|
34 scene: 'default',
|
||||||
|
35 title: '配置',
|
||||||
|
36 subtitle: '',
|
||||||
|
37 copyText: '',
|
||||||
|
38 storageKey: '',
|
||||||
|
39 defaultCategory: ''
|
||||||
|
40 }
|
||||||
|
41 )
|
||||||
|
42
|
||||||
|
43 const cacheKey = computed(() => props.storageKey || `type-line-active-cat-${props.scene}`)
|
||||||
|
44
|
||||||
|
45 const resolveInitialCategory = () => {
|
||||||
|
46 const defaultKey = props.defaultCategory || props.categories[0]?.key || ''
|
||||||
|
47 const savedKey = sessionStorage.getItem(cacheKey.value)
|
||||||
|
48 const validSavedKey = props.categories.some(item => item.key === savedKey)
|
||||||
|
49 return validSavedKey ? (savedKey as string) : defaultKey
|
||||||
|
50 }
|
||||||
|
51
|
||||||
|
52 const activeCategory = ref(resolveInitialCategory())
|
||||||
|
53
|
||||||
|
54 watch(
|
||||||
|
55 () => [props.categories, props.defaultCategory, cacheKey.value],
|
||||||
|
56 () => {
|
||||||
|
57 activeCategory.value = resolveInitialCategory()
|
||||||
|
58 },
|
||||||
|
59 { deep: true }
|
||||||
|
60 )
|
||||||
|
61
|
||||||
|
62 const switchCategory = (cat: string) => {
|
||||||
|
63 activeCategory.value = cat
|
||||||
|
64 sessionStorage.setItem(cacheKey.value, cat)
|
||||||
|
65 }
|
||||||
|
66
|
||||||
|
67 const activeComponent = computed(() => {
|
||||||
|
68 const selected = props.categories.find(item => item.key === activeCategory.value)
|
||||||
|
69 return selected?.component || props.categories[0]?.component || null
|
||||||
|
70 })
|
||||||
|
71
|
||||||
|
72 const copyBtnText = ref('复制')
|
||||||
|
73 const sheetOpen = ref(false)
|
||||||
|
74 let copyBtnTimer: ReturnType<typeof setTimeout> | null = null
|
||||||
|
75
|
||||||
|
76 const handleCopySubtitle = async () => {
|
||||||
|
77 const text = (props.copyText || '').trim()
|
||||||
|
78 if (!text) return
|
||||||
|
79
|
||||||
|
80 try {
|
||||||
|
81 await navigator.clipboard.writeText(text)
|
||||||
|
82 copyBtnText.value = '已复制'
|
||||||
|
83 } catch (error) {
|
||||||
|
84 console.error('copy failed:', error)
|
||||||
|
85 copyBtnText.value = '复制失败'
|
||||||
|
86 }
|
||||||
|
87
|
||||||
|
88 if (copyBtnTimer) clearTimeout(copyBtnTimer)
|
||||||
|
89 copyBtnTimer = setTimeout(() => {
|
||||||
|
90 copyBtnText.value = '复制'
|
||||||
|
91 }, 1200)
|
||||||
|
92 }
|
||||||
|
93
|
||||||
|
94 onBeforeUnmount(() => {
|
||||||
|
95 if (copyBtnTimer) clearTimeout(copyBtnTimer)
|
||||||
|
96 if (!root) return
|
||||||
|
97 root.style.scale = ''
|
||||||
|
98 root.style.translate = ''
|
||||||
|
99 root.style.borderRadius = ''
|
||||||
|
100 })
|
||||||
|
101
|
||||||
|
102 //
|
||||||
|
103
|
||||||
|
104
|
||||||
|
105 const inertiaTransition = {
|
||||||
|
106 type: 'inertia' as const,
|
||||||
|
107 bounceStiffness: 300,
|
||||||
|
108 bounceDamping: 40,
|
||||||
|
109 timeConstant: 300,
|
||||||
|
110 }
|
||||||
|
111
|
||||||
|
112 const staticTransition = {
|
||||||
|
113 duration: 0.5,
|
||||||
|
114 ease: [0.32, 0.72, 0, 1] as const,
|
||||||
|
115 }
|
||||||
|
116
|
||||||
|
117 const SHEET_TOP_RATIO = 0.1
|
||||||
|
118 const SHEET_RADIUS = 12
|
||||||
|
119 const OFFICIAL_SITE_URL = '/'
|
||||||
|
120
|
||||||
|
121 let root: HTMLElement | null = null
|
||||||
|
122
|
||||||
|
123 onMounted(() => {
|
||||||
|
124 root = document.body.firstElementChild as HTMLElement | null
|
||||||
|
125 })
|
||||||
|
126
|
||||||
|
127 const { height, width } = useWindowSize()
|
||||||
|
128
|
||||||
|
129 const sheetTop = computed(() => Math.round(height.value * SHEET_TOP_RATIO))
|
||||||
|
130 const h = computed(() => Math.max(0, height.value - sheetTop.value))
|
||||||
|
131 const y = useMotionValue(h.value)
|
||||||
|
132
|
||||||
|
133 watch(
|
||||||
|
134 () => h.value,
|
||||||
|
135 (nextHeight) => {
|
||||||
|
136 if (!sheetOpen.value) y.jump(nextHeight)
|
||||||
|
137 }
|
||||||
|
138 )
|
||||||
|
139
|
||||||
|
140 watch(
|
||||||
|
141 () => sheetOpen.value,
|
||||||
|
142 (isOpen) => {
|
||||||
|
143 if (!isOpen) {
|
||||||
|
144 y.jump(h.value)
|
||||||
|
145 return
|
||||||
|
146 }
|
||||||
|
147 y.jump(h.value)
|
||||||
|
148 animate(y, 0, staticTransition)
|
||||||
|
149 }
|
||||||
|
150 )
|
||||||
|
151
|
||||||
|
152 // Scale the body down and adjust the border radius when the sheet is open.
|
||||||
|
153 const bodyScale = useTransform(
|
||||||
|
154 y,
|
||||||
|
155 [0, h.value],
|
||||||
|
156 [(width.value - sheetTop.value) / width.value, 1],
|
||||||
|
157 )
|
||||||
|
158 const bodyTranslate = useTransform(y, [0, h.value], [sheetTop.value - SHEET_RADIUS, 0])
|
||||||
|
159 const bodyBorderRadius = useTransform(y, [0, h.value], [SHEET_RADIUS, 0])
|
||||||
|
160
|
||||||
|
161 useMotionValueEvent(bodyScale, 'change', (v) => {
|
||||||
|
162 if (!root) return
|
||||||
|
163 root.style.scale = `${v}`
|
||||||
|
164 })
|
||||||
|
165 useMotionValueEvent(
|
||||||
|
166 bodyTranslate,
|
||||||
|
167 'change',
|
||||||
|
168 (v) => {
|
||||||
|
169 if (!root) return
|
||||||
|
170 root.style.translate = `0 ${v}px`
|
||||||
|
171 },
|
||||||
|
172 )
|
||||||
|
173 useMotionValueEvent(
|
||||||
|
174 bodyBorderRadius,
|
||||||
|
175 'change',
|
||||||
|
176 (v) => {
|
||||||
|
177 if (!root) return
|
||||||
|
178 root.style.borderRadius = `${v}px`
|
||||||
|
179 },
|
||||||
|
180 )
|
||||||
|
181 </script>
|
||||||
|
182
|
||||||
|
183 <template>
|
||||||
|
184 <div class="flex h-full w-full bg-background">
|
||||||
|
185 <div class="w-12/100 border-r p-6 flex flex-col gap-8 relative">
|
||||||
|
186 <div v-if="props.title || props.subtitle" class="space-y-1">
|
||||||
|
187 <div v-if="props.title" class="font-bold text-base leading-6 text-primary break-words">
|
||||||
|
188 {{ props.title }}
|
||||||
|
189 </div>
|
||||||
|
190 <div
|
||||||
|
191 v-if="props.subtitle"
|
||||||
|
192 class="flex flex-wrap items-center gap-2 text-xs leading-5 text-muted-foreground"
|
||||||
|
193 >
|
||||||
|
194 <span class="break-all">{{ props.subtitle }}</span>
|
||||||
|
195 <Button
|
||||||
|
196 v-if="props.copyText"
|
||||||
|
197 type="button"
|
||||||
|
198 variant="outline"
|
||||||
|
199 size="sm"
|
||||||
|
200 class="h-6 rounded-md px-2 text-[11px]"
|
||||||
|
201 @click.stop="handleCopySubtitle"
|
||||||
|
202 >
|
||||||
|
203 {{ copyBtnText }}
|
||||||
|
204 </Button>
|
||||||
|
205 </div>
|
||||||
|
206 </div>
|
||||||
|
207
|
||||||
|
208 <div class="flex flex-col gap-10 relative">
|
||||||
|
209 <div class="absolute left-[11px] top-2 bottom-2 w-[2px] bg-muted"></div>
|
||||||
|
210
|
||||||
|
211 <div
|
||||||
|
212 v-for="item in props.categories"
|
||||||
|
213 :key="item.key"
|
||||||
|
214 class="relative flex items-center gap-4 cursor-pointer group"
|
||||||
|
215 @click="switchCategory(item.key)"
|
||||||
|
216 >
|
||||||
|
217 <div
|
||||||
|
218 :class="[
|
||||||
|
219 'z-10 w-6 h-6 rounded-full border-2 flex items-center justify-center transition-all',
|
||||||
|
220 activeCategory === item.key
|
||||||
|
221 ? 'bg-primary border-primary scale-110'
|
||||||
|
222 : 'bg-background border-muted-foreground'
|
||||||
|
223 ]"
|
||||||
|
224 >
|
||||||
|
225 <div v-if="activeCategory === item.key" class="w-2 h-2 bg-background rounded-full"></div>
|
||||||
|
226 </div>
|
||||||
|
227 <span
|
||||||
|
228 :class="[
|
||||||
|
229 'text-sm transition-colors',
|
||||||
|
230 activeCategory === item.key
|
||||||
|
231 ? 'font-bold text-primary'
|
||||||
|
232 : 'text-muted-foreground group-hover:text-foreground'
|
||||||
|
233 ]"
|
||||||
|
234 >
|
||||||
|
235 {{ item.label }}
|
||||||
|
236 </span>
|
||||||
|
237 </div>
|
||||||
|
238 </div>
|
||||||
|
239
|
||||||
|
240 <DialogRoot v-model:open="sheetOpen">
|
||||||
|
241 <DialogTrigger as-child>
|
||||||
|
242 <button
|
||||||
|
243 type="button"
|
||||||
|
244 class="absolute left-4 right-4 bottom-4 flex flex-col items-center gap-1.5 rounded-lg border bg-muted/35 px-3 py-2 text-center text-[12px] leading-5 text-foreground/85 shadow-sm hover:bg-muted/55 hover:text-foreground transition-colors"
|
||||||
|
245 >
|
||||||
|
246 <img src="/favicon.ico" alt="众为咨询" class="h-5 w-5 shrink-0 rounded-sm" />
|
||||||
|
247 <span>本网站由众为工程咨询有限公司提供免费技术支持</span>
|
||||||
|
248 </button>
|
||||||
|
249 </DialogTrigger>
|
||||||
|
250 <DialogPortal>
|
||||||
|
251 <AnimatePresence
|
||||||
|
252 multiple
|
||||||
|
253 as="div"
|
||||||
|
254 >
|
||||||
|
255 <DialogOverlay as-child>
|
||||||
|
256 <Motion
|
||||||
|
257 class="fixed inset-0 z-10 bg-black/45 backdrop-blur-[2px]"
|
||||||
|
258 :initial="{ opacity: 0 }"
|
||||||
|
259 :animate="{ opacity: 1 }"
|
||||||
|
260 :exit="{ opacity: 0 }"
|
||||||
|
261 :transition="staticTransition"
|
||||||
|
262 />
|
||||||
|
263 </DialogOverlay>
|
||||||
|
264
|
||||||
|
265 <DialogContent as-child>
|
||||||
|
266 <Motion
|
||||||
|
267 class="fixed inset-x-0 bottom-0 z-20 overflow-hidden rounded-t-2xl border border-border/60 bg-card/95 shadow-2xl backdrop-blur-xl will-change-transform"
|
||||||
|
268 :style="{
|
||||||
|
269 y,
|
||||||
|
270 top: `${sheetTop}px`,
|
||||||
|
271 }"
|
||||||
|
272 drag="y"
|
||||||
|
273 :drag-constraints="{ top: 0 }"
|
||||||
|
274 @drag-end="(e, { offset, velocity }) => {
|
||||||
|
275 if (offset.y > h * 0.35 || velocity.y > 10) {
|
||||||
|
276 sheetOpen = false;
|
||||||
|
277 }
|
||||||
|
278 else {
|
||||||
|
279 animate(y, 0, { ...inertiaTransition, min: 0, max: 0 });
|
||||||
|
280 }
|
||||||
|
281 }"
|
||||||
|
282 >
|
||||||
|
283 <div class="mx-auto mt-2 h-1.5 w-12 rounded-full bg-muted-foreground/35" />
|
||||||
|
284 <div class="mx-auto flex h-full w-full max-w-2xl flex-col px-4 pb-5 pt-3">
|
||||||
|
285 <div class="mb-3 flex items-center justify-between gap-3">
|
||||||
|
286 <DialogTitle class="m-0">
|
||||||
|
287 <div class="flex items-center gap-3">
|
||||||
|
288 <img src="/favicon.ico" alt="众为咨询" class="h-7 w-7 shrink-0 rounded-sm" />
|
||||||
|
289 <span class="text-2xl font-semibold leading-none">关于我们</span>
|
||||||
|
290 </div>
|
||||||
|
291 </DialogTitle>
|
||||||
|
292 <div class="flex items-center gap-2">
|
||||||
|
293 <a
|
||||||
|
294 :href="OFFICIAL_SITE_URL"
|
||||||
|
295 target="_blank"
|
||||||
|
296 rel="noopener noreferrer"
|
||||||
|
297 class="inline-flex h-8 w-8 items-center justify-center rounded-md border border-muted-foreground/30 text-muted-foreground transition-colors hover:border-foreground/40 hover:text-foreground"
|
||||||
|
298 aria-label="跳转到官网首页"
|
||||||
|
299 title="官网首页"
|
||||||
|
300 >
|
||||||
|
301 <Icon icon="lucide:arrow-up-right" class="h-4 w-4" />
|
||||||
|
302 </a>
|
||||||
|
303 <DialogClose class="inline-flex h-8 w-8 items-center justify-center rounded-md border border-muted-foreground/30 text-muted-foreground transition-colors hover:border-foreground/40 hover:text-foreground">
|
||||||
|
304 <Icon icon="lucide:x" class="h-4 w-4" />
|
||||||
|
305 </DialogClose>
|
||||||
|
306 </div>
|
||||||
|
307 </div>
|
||||||
|
308
|
||||||
|
309 <DialogDescription class="mb-4 text-base text-muted-foreground">
|
||||||
|
310 <p class="font-medium text-foreground">众为工程咨询有限公司</p>
|
||||||
|
311 </DialogDescription>
|
||||||
|
312
|
||||||
|
313 <div class="space-y-4 overflow-y-auto pr-1 text-[15px] leading-7">
|
||||||
|
314 <p>
|
||||||
|
315 众为工程咨询有限公司长期专注于工程咨询与数字化服务,致力于为客户提供高效、可靠、可持续的解决方案。
|
||||||
|
316 </p>
|
||||||
|
317 <p>
|
||||||
|
318 我们围绕咨询管理、数据治理、系统建设与运维支持,持续提升项目交付质量,帮助客户降低沟通成本、提升协同效率。
|
||||||
|
319 </p>
|
||||||
|
320 <p>
|
||||||
|
321 本网站由众为工程咨询有限公司提供免费技术支持,如需商务合作或技术咨询,请与我们联系。
|
||||||
|
322 </p>
|
||||||
|
323 </div>
|
||||||
|
324 </div>
|
||||||
|
325 </Motion>
|
||||||
|
326 </DialogContent>
|
||||||
|
327 </AnimatePresence>
|
||||||
|
328 </DialogPortal>
|
||||||
|
329 </DialogRoot>
|
||||||
|
330
|
||||||
|
331 </div>
|
||||||
|
332
|
||||||
|
333 <div class="w-88/100 min-h-0 h-full flex flex-col">
|
||||||
|
334 <ScrollArea class="h-full w-full min-h-0 rightMain">
|
||||||
|
335 <div class="p-3 h-full min-h-0 flex flex-col">
|
||||||
|
336 <keep-alive>
|
||||||
|
337 <component :is="activeComponent" />
|
||||||
|
338 </keep-alive>
|
||||||
|
339 </div>
|
||||||
|
340 </ScrollArea>
|
||||||
|
341 </div>
|
||||||
|
342 </div>
|
||||||
|
343 </template>
|
||||||
|
344 <style scoped>
|
||||||
|
345 /* 核心修改:添加 :deep() 穿透 scoped 作用域 */
|
||||||
|
346 :deep(.rightMain > div > div) {
|
||||||
|
347 height: 100%;
|
||||||
|
348 min-height: 0;
|
||||||
|
349 box-sizing: border-box;
|
||||||
|
350 }
|
||||||
|
351 </style>
|
||||||
Reference in new issue
Block a user