diff --git a/package-lock.json b/package-lock.json
index f1b9ee7..ef8292c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2733,6 +2733,70 @@
}
}
},
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
+ "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
+ "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
+ "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
+ "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/@esbuild/darwin-arm64": {
"version": "0.20.2",
"cpu": [
@@ -2747,6 +2811,294 @@
"node": ">=12"
}
},
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
+ "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
+ "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
+ "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
+ "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
+ "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
+ "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
+ "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
+ "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
+ "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
+ "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
+ "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
+ "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
+ "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
+ "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
+ "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
+ "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/@intlify/core-base": {
"version": "9.1.9",
"license": "MIT",
@@ -7284,15 +7636,6 @@
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC"
},
- "node_modules/growly": {
- "version": "1.3.0",
- "resolved": "https://registry.npmmirror.com/growly/-/growly-1.3.0.tgz",
- "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
@@ -7599,24 +7942,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-docker": {
- "version": "2.2.1",
- "resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz",
- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "bin": {
- "is-docker": "cli.js"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -7704,21 +8029,6 @@
"license": "MIT",
"peer": true
},
- "node_modules/is-wsl": {
- "version": "2.2.0",
- "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz",
- "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "is-docker": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/isbinaryfile": {
"version": "5.0.4",
"resolved": "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-5.0.4.tgz",
@@ -9151,36 +9461,6 @@
"license": "MIT",
"peer": true
},
- "node_modules/node-notifier": {
- "version": "9.0.1",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "dependencies": {
- "growly": "^1.3.0",
- "is-wsl": "^2.2.0",
- "semver": "^7.3.2",
- "shellwords": "^0.1.1",
- "uuid": "^8.3.0",
- "which": "^2.0.2"
- }
- },
- "node_modules/node-notifier/node_modules/semver": {
- "version": "7.7.1",
- "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.1.tgz",
- "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
- "dev": true,
- "license": "ISC",
- "optional": true,
- "peer": true,
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/node-releases": {
"version": "2.0.19",
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz",
@@ -10599,15 +10879,6 @@
"node": ">=8"
}
},
- "node_modules/shellwords": {
- "version": "0.1.1",
- "resolved": "https://registry.npmmirror.com/shellwords/-/shellwords-0.1.1.tgz",
- "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true
- },
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.1.0.tgz",
@@ -11545,16 +11816,6 @@
"node": ">= 0.4.0"
}
},
- "node_modules/uuid": {
- "version": "8.3.2",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "peer": true,
- "bin": {
- "uuid": "dist/bin/uuid"
- }
- },
"node_modules/v8-to-istanbul": {
"version": "8.1.1",
"dev": true,
diff --git a/src/components/app/AppNoticeBar.vue b/src/components/app/AppNoticeBar.vue
new file mode 100644
index 0000000..df8ca88
--- /dev/null
+++ b/src/components/app/AppNoticeBar.vue
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+ {{ text }}
+
+
+
+
+
+
+
diff --git a/src/components/app/InlineState.vue b/src/components/app/InlineState.vue
new file mode 100644
index 0000000..512b2ff
--- /dev/null
+++ b/src/components/app/InlineState.vue
@@ -0,0 +1,78 @@
+
+
+ {{ text }}
+
+
+
+
+
+
+
diff --git a/src/components/app/UsageDescription.vue b/src/components/app/UsageDescription.vue
new file mode 100644
index 0000000..f78c2c8
--- /dev/null
+++ b/src/components/app/UsageDescription.vue
@@ -0,0 +1,36 @@
+
+
+ {{ index + 1 }}. {{ tip }}
+
+
+
+
+
+
diff --git a/src/components/home/HomeFeatureCard.vue b/src/components/home/HomeFeatureCard.vue
new file mode 100644
index 0000000..98bf021
--- /dev/null
+++ b/src/components/home/HomeFeatureCard.vue
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+
+ {{ title }}
+ {{ tag }}
+
+ {{ description }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/home/HomeHeroCard.vue b/src/components/home/HomeHeroCard.vue
new file mode 100644
index 0000000..4c3774f
--- /dev/null
+++ b/src/components/home/HomeHeroCard.vue
@@ -0,0 +1,240 @@
+
+
+
+ {{ eyebrow }}
+ {{ title }}
+ {{ subtitle }}
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/mail/MailCard.vue b/src/components/mail/MailCard.vue
new file mode 100644
index 0000000..4788f3e
--- /dev/null
+++ b/src/components/mail/MailCard.vue
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
+ 联系人
+ {{ maskedRecipient }}
+
+
+
+ {{ mail.content }}
+
+
+
+ {{ mail.status === sentStatus ? "发送" : "提交" }}于
+ {{ displayTime }}
+
+
+
+
+
+
+
+
diff --git a/src/components/mail/MailListState.vue b/src/components/mail/MailListState.vue
new file mode 100644
index 0000000..70af098
--- /dev/null
+++ b/src/components/mail/MailListState.vue
@@ -0,0 +1,159 @@
+
+
+
+
+
+
+
+
+
+
+ 还没有消息
+ {{ emptyText }}
+
+
+
+
+
+ {{ noMoreText }}
+
+
+
+
+
+
+
diff --git a/src/components/planning/PlanCard.vue b/src/components/planning/PlanCard.vue
new file mode 100644
index 0000000..492135f
--- /dev/null
+++ b/src/components/planning/PlanCard.vue
@@ -0,0 +1,187 @@
+
+
+
+
+
+
+ {{ plan.cycleName }}
+
+
+
+
+
+ {{ plan.socialTypeName }}
+ {{ maskedAccount }}
+
+
+
+ {{ plan.content }}
+
+
+
+ 下次传送
+ {{ nextRunTime }}
+
+
+
+
+
+
+
diff --git a/src/components/profile/ProfileHeader.vue b/src/components/profile/ProfileHeader.vue
new file mode 100644
index 0000000..f7d5761
--- /dev/null
+++ b/src/components/profile/ProfileHeader.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
diff --git a/src/components/profile/ProfileMenuSection.vue b/src/components/profile/ProfileMenuSection.vue
new file mode 100644
index 0000000..c1de679
--- /dev/null
+++ b/src/components/profile/ProfileMenuSection.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
diff --git a/src/components/reply/ReplyCard.vue b/src/components/reply/ReplyCard.vue
new file mode 100644
index 0000000..a418338
--- /dev/null
+++ b/src/components/reply/ReplyCard.vue
@@ -0,0 +1,203 @@
+
+
+
+
+
+
+
+ {{ sourceMeta.text }}
+
+ {{ displayTime }}
+
+
+
+ 来自
+ {{ maskedPhone }}
+
+
+
+
+ {{ reply.replyMessage }}
+
+
+
+
+
+
+
+
+
diff --git a/src/config/form.ts b/src/config/form.ts
new file mode 100644
index 0000000..8781f5a
--- /dev/null
+++ b/src/config/form.ts
@@ -0,0 +1,58 @@
+export const APP_NOTICE = {
+ text: "B站10分日本动漫已消失,9.9分仅剩12部,这一部动漫包揽三席!",
+};
+
+export const MESSAGE_USAGE_TIPS = [
+ "填写对方手机号码,系统将向该号码发送短信",
+ "可选择未来的发送时间,不选则立即发送",
+ "使用AI文案美化功能可自动生成不同类型的短信内容",
+ "短信按20字一条计费,发送前可预览效果",
+];
+
+export const SOCIAL_TYPE_OPTIONS = [
+ { text: "手机短信", value: 1, inputType: "number" },
+ { text: "微信", value: 2, inputType: "text" },
+ { text: "QQ", value: 3, inputType: "number" },
+ { text: "钉钉", value: 4, inputType: "text" },
+ { text: "企业微信", value: 5, inputType: "text" },
+ { text: "其他", value: 6, inputType: "text" },
+];
+
+export const MESSAGE_TEMPLATES = [
+ {
+ typeId: 1,
+ type: "表白",
+ desc: "表达喜欢和心意,语气真诚不过度施压",
+ content: "有些话我想认真告诉你:遇见你以后,我开始期待每一次聊天和见面。我喜欢你,也尊重你的想法,只希望这份心意能被你看见。",
+ },
+ {
+ typeId: 2,
+ type: "道歉",
+ desc: "承认问题、表达歉意,减少争辩感",
+ content: "对不起,之前是我没有处理好自己的情绪,也没有站在你的角度考虑。我知道一句道歉不能立刻弥补什么,但我真心希望你能看到我的歉意。",
+ },
+ {
+ typeId: 3,
+ type: "祝福",
+ desc: "适合生日、纪念日和特殊日子的温柔问候",
+ content: "今天想把祝福送给你。愿你接下来的日子顺利、开心,也愿所有美好的事情都慢慢靠近你。",
+ },
+ {
+ typeId: 4,
+ type: "问候",
+ desc: "轻量关心,不打扰也不冒犯",
+ content: "只是想问候你一下,希望你最近一切都好。天气变化记得照顾好自己,也希望你每天都能轻松一点。",
+ },
+ {
+ typeId: 5,
+ type: "晚安",
+ desc: "适合夜晚发送,柔和表达惦记",
+ content: "晚安。希望你今晚能睡个好觉,把今天的疲惫都放下。明天醒来,也能拥有一点新的开心。",
+ },
+ {
+ typeId: 6,
+ type: "思念",
+ desc: "表达想念,但保留体面和边界",
+ content: "有些时刻还是会想起你,想起我们曾经一起经历过的片段。我没有想打扰你,只是想让你知道,我依然珍惜那些回忆。",
+ },
+];
diff --git a/src/config/home.ts b/src/config/home.ts
new file mode 100644
index 0000000..fb6d672
--- /dev/null
+++ b/src/config/home.ts
@@ -0,0 +1,113 @@
+import callingIcon from "@/assets/1.svg";
+import manualIcon from "@/assets/2.svg";
+
+import { APP_ROUTES } from "./routes";
+
+export interface HomeFeatureCardConfig {
+ id: number;
+ title: string;
+ description: string;
+ iconPath: string;
+ buttonText: string;
+ route?: string;
+ buttonClass?: string;
+ iconClass?: string;
+ disabledTip?: string;
+ tag?: string;
+}
+
+export const HOME_HERO = {
+ eyebrow: "匿名短信 · 匿名电话",
+ title: "有些话,换一种方式认真说",
+ subtitle: "被拉黑、想道歉、想告白、想送祝福时,用更克制的方式把心意送达。",
+ highlights: ["匿名代发", "发送前预览", "定时送达"],
+ image: "/static/images/love.png",
+ actionText: "写一条匿名短信",
+ actionRoute: APP_ROUTES.sending,
+ secondaryText: "人工传话",
+ secondaryRoute: APP_ROUTES.manual,
+};
+
+export const HOME_PRIMARY_FEATURES: HomeFeatureCardConfig[] = [
+ {
+ id: 1,
+ title: "人工传话",
+ description: "真人协助传达,更适合认真道歉和重要告白",
+ iconPath: manualIcon,
+ buttonText: "去传话",
+ route: APP_ROUTES.manual,
+ iconClass: "icon-wrapper-orange",
+ buttonClass: "color-button",
+ tag: "更有温度",
+ },
+ {
+ id: 2,
+ title: "匿名电话",
+ description: "适合紧急和解、重要解释,先确认意愿再沟通",
+ iconPath: callingIcon,
+ buttonText: "去拨打",
+ route: APP_ROUTES.calling,
+ iconClass: "icon-wrapper-blue",
+ buttonClass: "color-button",
+ disabledTip: "此通道正在维护中,暂时禁用!",
+ tag: "即将开放",
+ },
+];
+
+export const HOME_ADDITIONAL_FEATURES: HomeFeatureCardConfig[] = [
+ {
+ id: 3,
+ title: "定时短信",
+ description: "生日、纪念日、晚安问候可提前设置",
+ iconPath: "/static/images/cat.png",
+ buttonText: "去设置",
+ route: APP_ROUTES.planning,
+ tag: "不怕错过",
+ },
+ {
+ id: 4,
+ title: "AI文案美化",
+ description: "把冲动的话改得更真诚、更体面",
+ iconPath: "/static/images/cat.png",
+ buttonText: "去优化",
+ route: APP_ROUTES.sending,
+ tag: "降低冒犯",
+ },
+ {
+ id: 5,
+ title: "收到回复",
+ description: "回复统一收进信箱,避免错过对方回应",
+ iconPath: "/static/images/cat.png",
+ buttonText: "去查看",
+ route: APP_ROUTES.reply,
+ tag: "及时查看",
+ },
+];
+
+export const HOME_FEATURE_STYLE_CLASSES = {
+ icon: ["icon-wrapper-green", "icon-wrapper-purple", "icon-wrapper-red"],
+ button: ["green-button", "purple-button", "red-button"],
+};
+
+export const HOME_SCENARIOS = [
+ {
+ title: "被拉黑后道歉",
+ description: "把重点放在承担责任,不反复打扰。",
+ },
+ {
+ title: "鼓起勇气告白",
+ description: "先表达心意,给对方留出选择空间。",
+ },
+ {
+ title: "生日和纪念日祝福",
+ description: "定时发送,适合不方便直接联系的时刻。",
+ },
+];
+
+export const HOME_STEPS = [
+ "选择短信、人工传话或电话",
+ "填写联系人和想说的话",
+ "预览确认后再发送",
+];
+
+export const HOME_GUARDRAILS = ["尊重对方意愿", "不鼓励频繁打扰", "内容发送前可检查"];
diff --git a/src/config/mail.ts b/src/config/mail.ts
new file mode 100644
index 0000000..34dd125
--- /dev/null
+++ b/src/config/mail.ts
@@ -0,0 +1,104 @@
+import emptyImage from "@/assets/nodata.svg";
+
+export enum MailStatus {
+ PENDING = 0,
+ SENT = 1,
+ FAILED = 2,
+}
+
+export interface Mail {
+ id: number;
+ orderNumber: string;
+ recipient: string;
+ content: string;
+ sendTime: string;
+ submitTime: string;
+ status: MailStatus;
+ price: number;
+ isNew: boolean;
+}
+
+export const MAIL_DETAIL_PAGE = "/pages/mailbox/detail";
+
+export const MAIL_TABS = [
+ { name: "全部" },
+ { name: "待发送" },
+ { name: "已发送" },
+ { name: "发送失败" },
+];
+
+export const MAIL_EMPTY_IMAGE = emptyImage;
+
+export const MAIL_STATUS_META: Record = {
+ [MailStatus.PENDING]: {
+ text: "待发送",
+ className: "status-pending",
+ },
+ [MailStatus.SENT]: {
+ text: "已发送",
+ className: "status-sent",
+ },
+ [MailStatus.FAILED]: {
+ text: "发送失败",
+ className: "status-failed",
+ },
+};
+
+export const MOCK_MAIL_CONTENTS = [
+ "有些话想认真说一次,不打扰你,只希望你知道我的歉意。",
+ "之前没有照顾好你的感受,对不起。愿你之后都能轻松一点。",
+ "如果还有机会,我想把没说好的话认真补上。",
+ "这条短信只是想把心意说清楚,不给你压力。",
+];
+
+export const MOCK_PHONE_PREFIXES = ["135", "136", "138", "151", "166", "171", "188", "199"];
+
+export const maskRecipient = (recipient: string): string => {
+ if (!recipient) return "";
+
+ const value = String(recipient).trim();
+
+ if (value.length <= 7) {
+ return value.replace(/^(.{2}).*(.{1})$/, "$1****$2");
+ }
+
+ return `${value.slice(0, 3)}****${value.slice(-4)}`;
+};
+
+export const formatMailTime = (timeString: string): string => {
+ if (!timeString || typeof timeString !== "string") {
+ return String(timeString || "");
+ }
+
+ const date = new Date(timeString.replace(" ", "T"));
+
+ if (Number.isNaN(date.getTime())) {
+ return timeString;
+ }
+
+ const now = new Date();
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ const hours = String(date.getHours()).padStart(2, "0");
+ const minutes = String(date.getMinutes()).padStart(2, "0");
+
+ if (year === now.getFullYear()) {
+ return `${month}月${day}日 ${hours}:${minutes}`;
+ }
+
+ return `${year}年${month}月${day}日 ${hours}:${minutes}`;
+};
+
+export const serializeMail = (mail: Mail): string => encodeURIComponent(JSON.stringify(mail));
+
+export const deserializeMail = (payload?: string): Mail | null => {
+ if (!payload) return null;
+
+ try {
+ return JSON.parse(decodeURIComponent(payload)) as Mail;
+ } catch (error) {
+ console.error("解析短信详情失败", error);
+ return null;
+ }
+};
diff --git a/src/config/planning.ts b/src/config/planning.ts
new file mode 100644
index 0000000..2c7e9c8
--- /dev/null
+++ b/src/config/planning.ts
@@ -0,0 +1,143 @@
+import { SOCIAL_TYPE_OPTIONS } from "@/config/form";
+import { maskRecipient } from "@/config/mail";
+
+export type PlanCycleType = "daily" | "weekly" | "monthly";
+export type PlanStatus = "inProgress" | "completed" | "paused";
+
+export interface PlanCycleOption {
+ type: PlanCycleType;
+ name: string;
+ desc: string;
+}
+
+export interface PlanSubmitPayload {
+ cycleType: PlanCycleType;
+ cycleName: string;
+ socialType: number;
+ socialTypeName: string;
+ socialAccount: string;
+ content: string;
+}
+
+export interface PlanItem {
+ id: string;
+ cycleType: PlanCycleType;
+ cycleName: string;
+ socialTypeName: string;
+ socialAccount: string;
+ content: string;
+ nextRunTime: string;
+ createdAt: string;
+ status: PlanStatus;
+}
+
+export const PLAN_CYCLE_OPTIONS: PlanCycleOption[] = [
+ {
+ type: "daily",
+ name: "每天",
+ desc: "每天定时传达一次",
+ },
+ {
+ type: "weekly",
+ name: "每周",
+ desc: "每周固定传达一次",
+ },
+ {
+ type: "monthly",
+ name: "每月",
+ desc: "每月固定传达一次",
+ },
+];
+
+export const PLAN_STATUS_TABS = [
+ { name: "全部", value: "all" },
+ { name: "进行中", value: "inProgress" },
+ { name: "已完成", value: "completed" },
+] as const;
+
+export const PLAN_STATUS_META: Record = {
+ inProgress: {
+ text: "进行中",
+ className: "status-running",
+ },
+ completed: {
+ text: "已完成",
+ className: "status-done",
+ },
+ paused: {
+ text: "已暂停",
+ className: "status-paused",
+ },
+};
+
+export const PLAN_SOCIAL_OPTIONS = SOCIAL_TYPE_OPTIONS.filter((item) => item.value !== 6);
+
+export const MOCK_PLAN_LIST: PlanItem[] = [
+ {
+ id: "PL250503001",
+ cycleType: "daily",
+ cycleName: "每天",
+ socialTypeName: "手机短信",
+ socialAccount: "19878384602",
+ content: "每天都想轻轻问候你一下,希望你今天也能顺利一点。",
+ nextRunTime: "2026-05-04 20:00:00",
+ createdAt: "2026-05-03 18:30:00",
+ status: "inProgress",
+ },
+ {
+ id: "PL250502002",
+ cycleType: "weekly",
+ cycleName: "每周",
+ socialTypeName: "微信",
+ socialAccount: "moonlight_520",
+ content: "每周给你留一句温柔的话,不催促,只表达我的在意。",
+ nextRunTime: "2026-05-09 21:00:00",
+ createdAt: "2026-05-02 21:12:00",
+ status: "inProgress",
+ },
+ {
+ id: "PL250501003",
+ cycleType: "monthly",
+ cycleName: "每月",
+ socialTypeName: "QQ",
+ socialAccount: "1289045216",
+ content: "这个月也想认真祝你平安顺利,愿你越来越轻松。",
+ nextRunTime: "2026-06-01 09:30:00",
+ createdAt: "2026-05-01 09:18:00",
+ status: "inProgress",
+ },
+ {
+ id: "PL250430004",
+ cycleType: "daily",
+ cycleName: "每天",
+ socialTypeName: "手机短信",
+ socialAccount: "13677268104",
+ content: "晚安,愿你今晚能睡得安心一点。",
+ nextRunTime: "2026-04-30 23:00:00",
+ createdAt: "2026-04-28 22:10:00",
+ status: "completed",
+ },
+ {
+ id: "PL250428005",
+ cycleType: "weekly",
+ cycleName: "每周",
+ socialTypeName: "企业微信",
+ socialAccount: "yanxi_2026",
+ content: "想把没说好的话慢慢说清楚,也尊重你的节奏。",
+ nextRunTime: "2026-05-05 19:30:00",
+ createdAt: "2026-04-28 16:02:00",
+ status: "paused",
+ },
+];
+
+export const maskSocialAccount = (account: string): string => {
+ if (/^1\d{10}$/.test(account)) {
+ return maskRecipient(account);
+ }
+
+ if (account.length <= 6) {
+ return account;
+ }
+
+ return `${account.slice(0, 3)}***${account.slice(-3)}`;
+};
diff --git a/src/config/profile.ts b/src/config/profile.ts
new file mode 100644
index 0000000..56336c5
--- /dev/null
+++ b/src/config/profile.ts
@@ -0,0 +1,77 @@
+import { APP_ROUTES } from "./routes";
+
+export const PROFILE_INFO = {
+ avatar: "/static/images/cat.png",
+ username: "GT-呆河马",
+ userId: "10086",
+};
+
+export const PROFILE_STATS = [
+ {
+ label: "可用余额",
+ value: "¥26.80",
+ },
+ {
+ label: "收到回复",
+ value: "2",
+ route: APP_ROUTES.reply,
+ },
+ {
+ label: "执行计划",
+ value: "3",
+ route: APP_ROUTES.planned,
+ },
+] as const;
+
+export const PROFILE_QUICK_ACTIONS = [
+ {
+ title: "发匿名短信",
+ desc: "快速写一条短信",
+ icon: "信",
+ route: APP_ROUTES.sending,
+ },
+ {
+ title: "人工传话",
+ desc: "更柔和地表达",
+ icon: "传",
+ route: APP_ROUTES.manual,
+ },
+ {
+ title: "创建计划",
+ desc: "定期传达心意",
+ icon: "计",
+ route: APP_ROUTES.planning,
+ },
+ {
+ title: "我的信箱",
+ desc: "查看发送记录",
+ icon: "箱",
+ route: APP_ROUTES.mailbox,
+ },
+] as const;
+
+export const PROFILE_MENU_GROUPS = [
+ [
+ {
+ label: "隐私与安全",
+ action: "privacy",
+ },
+ {
+ label: "使用须知",
+ action: "notice",
+ },
+ {
+ label: "联系我们",
+ action: "copyWechat",
+ },
+ ],
+] as const;
+
+export const CONTACT_CONFIG = {
+ wechatId: "I18888",
+ copySuccessText: "微信号已复制",
+ copyFailText: "复制失败,请重试",
+};
+
+export const PROFILE_NOTICE_TEXT = "请真诚表达,避免频繁打扰对方。";
+export const PROFILE_PRIVACY_TEXT = "平台会保护你的提交信息,仅用于完成传话服务。";
diff --git a/src/config/reply.ts b/src/config/reply.ts
new file mode 100644
index 0000000..3173d78
--- /dev/null
+++ b/src/config/reply.ts
@@ -0,0 +1,101 @@
+export interface ReplyItem {
+ id: string;
+ contactPhone: string;
+ originalMessage: string;
+ replyMessage: string;
+ replyTime: string;
+ source: "sms" | "manual";
+ unread: boolean;
+}
+
+export const REPLY_PAGE_SIZE = 6;
+
+export const REPLY_SOURCE_META: Record = {
+ sms: {
+ text: "短信回复",
+ className: "source-sms",
+ },
+ manual: {
+ text: "人工传话",
+ className: "source-manual",
+ },
+};
+
+export const MOCK_REPLY_LIST: ReplyItem[] = [
+ {
+ id: "RP250503001",
+ contactPhone: "19878384602",
+ originalMessage: "有些话想认真说一次,不打扰你,只希望你知道我的歉意。",
+ replyMessage: "我收到了。谢谢你愿意认真说这些,我需要一点时间想想。",
+ replyTime: "2026-05-03 20:12:00",
+ source: "sms",
+ unread: true,
+ },
+ {
+ id: "RP250503002",
+ contactPhone: "13993621665",
+ originalMessage: "之前没有照顾好你的感受,对不起。愿你之后都能轻松一点。",
+ replyMessage: "我已经看到了,也希望你之后能真的慢慢变好。",
+ replyTime: "2026-05-03 18:35:00",
+ source: "manual",
+ unread: true,
+ },
+ {
+ id: "RP250502003",
+ contactPhone: "18826830915",
+ originalMessage: "如果还有机会,我想把没说好的话认真补上。",
+ replyMessage: "先不用急着见面,等彼此都平静一点再说吧。",
+ replyTime: "2026-05-02 21:08:00",
+ source: "sms",
+ unread: false,
+ },
+ {
+ id: "RP250501004",
+ contactPhone: "15188340219",
+ originalMessage: "这条短信只是想把心意说清楚,不给你压力。",
+ replyMessage: "谢谢你的祝福,我也希望我们都能好好生活。",
+ replyTime: "2026-05-01 09:46:00",
+ source: "sms",
+ unread: false,
+ },
+ {
+ id: "RP250430005",
+ contactPhone: "13677268104",
+ originalMessage: "对不起,之前的争吵我也有很多没有处理好的地方。",
+ replyMessage: "我知道了。过去的事情先放一放吧,别再互相消耗了。",
+ replyTime: "2026-04-30 22:20:00",
+ source: "manual",
+ unread: false,
+ },
+ {
+ id: "RP250429006",
+ contactPhone: "19945201866",
+ originalMessage: "想把晚安认真补给你,也想把歉意说清楚。",
+ replyMessage: "晚安。也祝你以后能遇到更好的自己。",
+ replyTime: "2026-04-29 23:17:00",
+ source: "sms",
+ unread: false,
+ },
+ {
+ id: "RP250428007",
+ contactPhone: "16690438152",
+ originalMessage: "我不会再频繁打扰,只是想最后认真表达一次。",
+ replyMessage: "收到。谢谢你尊重我的节奏。",
+ replyTime: "2026-04-28 16:02:00",
+ source: "manual",
+ unread: false,
+ },
+];
+
+export const serializeReply = (reply: ReplyItem): string => encodeURIComponent(JSON.stringify(reply));
+
+export const deserializeReply = (payload?: string): ReplyItem | null => {
+ if (!payload) return null;
+
+ try {
+ return JSON.parse(decodeURIComponent(payload)) as ReplyItem;
+ } catch (error) {
+ console.error("解析回复详情失败", error);
+ return null;
+ }
+};
diff --git a/src/config/routes.ts b/src/config/routes.ts
new file mode 100644
index 0000000..22ab7ef
--- /dev/null
+++ b/src/config/routes.ts
@@ -0,0 +1,32 @@
+export const APP_ROUTES = {
+ home: "/pages/index/index",
+ mailbox: "/pages/mailbox/index",
+ mine: "/pages/mine/index",
+ sending: "/pages/sending/index",
+ manual: "/pages/manual/index",
+ calling: "/pages/calling/index",
+ planning: "/pages/planning/index",
+ planned: "/pages/planning/planned",
+ reply: "/pages/reply/index",
+} as const;
+
+export const TAB_BAR_ITEMS = [
+ {
+ pagePath: "pages/index/index",
+ text: "写信",
+ iconPath: "static/images/send.png",
+ selectedIconPath: "static/images/send-active.png",
+ },
+ {
+ pagePath: "pages/mailbox/index",
+ text: "信箱",
+ iconPath: "static/images/mailbox.png",
+ selectedIconPath: "static/images/mailbox-active.png",
+ },
+ {
+ pagePath: "pages/mine/index",
+ text: "我的",
+ iconPath: "static/images/mine.png",
+ selectedIconPath: "static/images/mine-active.png",
+ },
+] as const;
diff --git a/src/pages.json b/src/pages.json
index 7c62524..541e66b 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -35,6 +35,19 @@
}
}
},
+ {
+ "path": "pages/mailbox/detail",
+ "style": {
+ // #ifdef H5
+ "titleNView": false,
+ // #endif
+ "navigationBarTitleText": "短信详情",
+ "mp-alipay": {
+ "titleBarColor": "#FFFFFF",
+ "titleColor": "#000000"
+ }
+ }
+ },
{
"path": "pages/mine/index",
"style": {
@@ -113,6 +126,19 @@
}
}
},
+ {
+ "path": "pages/reply/detail",
+ "style": {
+ // #ifdef H5
+ "titleNView": false,
+ // #endif
+ "navigationBarTitleText": "回复详情",
+ "mp-alipay": {
+ "titleBarColor": "#FFFFFF",
+ "titleColor": "#000000"
+ }
+ }
+ },
{
"path": "pages/planning/planned",
"style": {
@@ -134,10 +160,14 @@
"backgroundColor": "#F8F8F8"
},
"tabBar": {
- "color": "#999",
- "selectedColor": "#00c853",
+ "color": "#7a7f87",
+ "selectedColor": "#18b566",
"backgroundColor": "#ffffff",
- "borderStyle": "white",
+ "borderStyle": "black",
+ "height": "56px",
+ "fontSize": "12px",
+ "iconWidth": "24px",
+ "spacing": "4px",
"list": [
{
"pagePath": "pages/index/index",
diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue
index d826273..2a47712 100644
--- a/src/pages/index/index.vue
+++ b/src/pages/index/index.vue
@@ -1,334 +1,343 @@
+
-
-
- 很多遗憾&源于当初没有勇敢
-
-
-
-
-
-
- 分手挽回, 生日祝福、
- 道歉、告白、时空信也
- 可以发送哦
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 人工传话
- 成功率更高,更有仪式感
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 和解电话
- 被拉黑也能打通的电话
-
-
-
-
-
-
+
+
+
-
-
+
-
-
-
-
-
-
-
-
- {{ card.title }}
- {{ card.description }}
-
-
-
-
-
+
+
-
-
- 加载中...
-
-
-
-
- {{ loadError }}
-
+
+
+
+
+ {{ scenario.title }}
+ {{ scenario.description }}
+
+
-
+
+
+
+
+
+ {{ index + 1 }}
+ {{ step }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item }}
+
+
-
-
\ No newline at end of file
+
+.step-text {
+ display: block;
+ margin-top: 18rpx;
+ color: #3a4354;
+ font-size: 24rpx;
+ line-height: 1.45;
+}
+
+.additional-cards {
+ margin-top: 32rpx;
+}
+
+.guardrail-bar {
+ display: flex;
+ flex-wrap: wrap;
+ margin-top: 24rpx;
+ padding: 18rpx 20rpx;
+ border-radius: 24rpx;
+ background: rgba(255, 255, 255, 0.66);
+ border: 1rpx solid rgba(255, 255, 255, 0.82);
+ box-shadow: 0 8rpx 22rpx rgba(83, 96, 130, 0.05);
+}
+
+.guardrail-item {
+ color: #7b8493;
+ font-size: 22rpx;
+ line-height: 1.3;
+ margin-right: 20rpx;
+ margin-bottom: 6rpx;
+}
+
diff --git a/src/pages/mailbox/detail.vue b/src/pages/mailbox/detail.vue
new file mode 100644
index 0000000..56a6b48
--- /dev/null
+++ b/src/pages/mailbox/detail.vue
@@ -0,0 +1,475 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ statusMeta.text }}
+
+ #{{ currentMail.orderNumber }}
+
+ {{ statusTitle }}
+ {{ statusDesc }}
+
+
+
+
+
+
+
+ {{ currentMail.content }}
+
+
+
+
+
+
+ 联系人
+ {{ maskedRecipient }}
+
+
+ 提交时间
+ {{ submitTime }}
+
+
+ 发送时间
+ {{ sendTime }}
+
+
+ 费用
+ ¥{{ currentMail.price.toFixed(2) }}
+
+
+
+
+
+
+
+ 已提交
+ {{ submitTime }}
+
+
+
+
+
+ {{ currentMail.status === failedStatus ? "发送失败" : "等待发送" }}
+ {{ sendTime }}
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/mailbox/index.vue b/src/pages/mailbox/index.vue
index dd6a668..176ff0a 100644
--- a/src/pages/mailbox/index.vue
+++ b/src/pages/mailbox/index.vue
@@ -1,22 +1,33 @@
-
-
+
+
-
-
-
-
- ↓
- {{ refreshing ? '刷新中...' : '下拉可以刷新' }}
+
-
-
+
+ {{ tab.name }}
+
+
+
+
+ ↓
+ {{ refreshing ? "刷新中..." : "下拉可以刷新" }}
+
+
+
-
-
-
-
-
-
-
-
-
-
-
- 联系人:
- {{mail.recipient}}
-
-
- {{formatContent(mail.content)}}
-
-
-
-
-
- {{ mail.status === MailStatus.SENT ? '发送' : '提交' }}于
- {{ formatTime(mail.status === MailStatus.SENT ? mail.sendTime : mail.submitTime) }}
-
-
-
-
-
+
+
- {{loadMoreButtonText}}
+ {{ loadMoreButtonText }}
-
-
-
-
-
-
-
-
-
-
- 已经到底了
-
-
-
-
-
-
- 暂无短信
-
+
+
-
-
\ No newline at end of file
+
diff --git a/src/pages/manual/index.vue b/src/pages/manual/index.vue
index dacd6c7..66a2039 100644
--- a/src/pages/manual/index.vue
+++ b/src/pages/manual/index.vue
@@ -1,469 +1,543 @@
-
-
-
-
-
-
-
- B站10分日本动漫已消失,9.9分仅剩12部,这一部动漫包揽三席!
-
-
+
+
+
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/src/pages/mine/index.vue b/src/pages/mine/index.vue
index f916bef..758cb1b 100644
--- a/src/pages/mine/index.vue
+++ b/src/pages/mine/index.vue
@@ -1,248 +1,322 @@
-
-
-
\ No newline at end of file
+
+.button-hover {
+ opacity: 0.76;
+}
+
diff --git a/src/pages/planning/index.vue b/src/pages/planning/index.vue
index b24f04d..ec8a1e0 100644
--- a/src/pages/planning/index.vue
+++ b/src/pages/planning/index.vue
@@ -1,1356 +1,653 @@
-
-
-
-
-
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/src/pages/planning/planned.vue b/src/pages/planning/planned.vue
index 7de99b0..e864415 100644
--- a/src/pages/planning/planned.vue
+++ b/src/pages/planning/planned.vue
@@ -1,446 +1,324 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 手机号:
- {{ item.phoneNumber }}
-
-
- 计划周期:
- {{ item.planCycle }}
-
-
- 开始时间:
- {{ item.startTime }}
-
-
+
+
+
+
+
+
+
+
+ {{ tab.name }}
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
- 加载中...
-
-
-
- --- 已经到底了 ---
+
+
+
+ 已经到底了
+
+
+
+
+ 计
+ 暂无计划
+ 创建后会在这里看到计划执行状态
+
+
+
+
+
+
+
+
-
-
-
- 暂无相关计划数据
-
-
\ No newline at end of file
+
+.empty-title {
+ color: #263044;
+ font-size: 32rpx;
+ font-weight: 700;
+}
+
+.empty-desc {
+ margin-top: 10rpx;
+ color: #8c96a8;
+ font-size: 24rpx;
+}
+
diff --git a/src/pages/reply/detail.vue b/src/pages/reply/detail.vue
new file mode 100644
index 0000000..1a1ec67
--- /dev/null
+++ b/src/pages/reply/detail.vue
@@ -0,0 +1,306 @@
+
+
+
+
+
+
+
+
+ {{ replyTime }}
+
+
+
+ 发送内容
+
+
+ {{ currentReply.originalMessage }}
+
+
+
+
+ 回
+
+
+ 回复内容
+
+
+ {{ currentReply.replyMessage }}
+
+
+
+
+
+
+
+ 联系人
+ {{ maskedContact }}
+
+
+ 回复时间
+ {{ replyTime }}
+
+
+ 记录编号
+ #{{ currentReply.id }}
+
+
+
+
+
+
+
+
diff --git a/src/pages/reply/index.vue b/src/pages/reply/index.vue
index 0ca9f02..bfddacd 100644
--- a/src/pages/reply/index.vue
+++ b/src/pages/reply/index.vue
@@ -1,852 +1,292 @@
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
- {{ item.contactPhone }}
-
-
-
- {{ item.message }}
-
- 查看详情
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
- 加载中...
+
+
+
+ 已经到底了
+
-
-
- — 已经到底了 —
+
+
+
+
+ 信
+ 还没有收到回复
+ 对方回复后,会在这里第一时间展示
+
+
+
+
+
+
-
-
-
-
-
-
- 暂无回复数据
- 您收到的回复将会显示在这里
-
-
-
-
-
-
-
-
-
-
-
- 联系人
-
- {{ currentContact }}
-
-
-
-
- 消息内容
-
-
-
- {{ currentContent }}
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+.empty-desc {
+ margin-top: 10rpx;
+ color: #8c96a8;
+ font-size: 24rpx;
+}
+
diff --git a/src/pages/sending/index.vue b/src/pages/sending/index.vue
index 3bdef72..e83a243 100644
--- a/src/pages/sending/index.vue
+++ b/src/pages/sending/index.vue
@@ -1,390 +1,481 @@
-
-
-
-
-
-
-
- B站10分日本动漫已消失,9.9分仅剩12部,这一部动漫包揽三席!
-
-
+
+
+
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+