diff --git a/apps/server/src/routes/license.tsx b/apps/server/src/routes/license.tsx
index 0da359e..5106af9 100644
--- a/apps/server/src/routes/license.tsx
+++ b/apps/server/src/routes/license.tsx
@@ -14,6 +14,7 @@ export const Route = createFileRoute('/license')({
function License() {
const [licenseInput, setLicenseInput] = useState('')
const [copySuccess, setCopySuccess] = useState(false)
+ const [showDeactivateConfirm, setShowDeactivateConfirm] = useState(false)
const queryClient = useQueryClient()
// 获取激活状态
@@ -32,11 +33,26 @@ function License() {
},
})
+ // 反激活 mutation
+ const deactivateMutation = useMutation({
+ ...orpc.license.deactivate.mutationOptions(),
+ onSuccess: () => {
+ queryClient.invalidateQueries({
+ queryKey: orpc.license.getActivation.key(),
+ })
+ setShowDeactivateConfirm(false)
+ },
+ })
+
const handleActivate = () => {
if (!licenseInput.trim()) return
activateMutation.mutate({ license: licenseInput.trim() })
}
+ const handleDeactivate = () => {
+ deactivateMutation.mutate()
+ }
+
const handleCopyFingerprint = async () => {
try {
await navigator.clipboard.writeText(data.fingerprint)
@@ -352,6 +368,62 @@ function License() {
)}
+
+ {!showDeactivateConfirm ? (
+
+ ) : (
+
+
+
+ 确定要反激活吗?此操作会清除当前 License。
+
+
+
+
+
+ {deactivateMutation.isError && (
+
+ 反激活失败,请重试
+
+ )}
+
+ )}
) : (
diff --git a/apps/server/src/server/api/contracts/license.contract.ts b/apps/server/src/server/api/contracts/license.contract.ts
index ce86419..7d7220e 100644
--- a/apps/server/src/server/api/contracts/license.contract.ts
+++ b/apps/server/src/server/api/contracts/license.contract.ts
@@ -12,3 +12,7 @@ export const getActivation = oc.input(z.void()).output(
export const activate = oc
.input(z.object({ license: z.string().min(1) }))
.output(z.object({ success: z.boolean() }))
+
+export const deactivate = oc
+ .input(z.void())
+ .output(z.object({ success: z.boolean() }))
diff --git a/apps/server/src/server/api/routers/license.router.ts b/apps/server/src/server/api/routers/license.router.ts
index 43ab10a..6188b8e 100644
--- a/apps/server/src/server/api/routers/license.router.ts
+++ b/apps/server/src/server/api/routers/license.router.ts
@@ -43,3 +43,25 @@ export const activate = os.license.activate
return { success: true }
})
+
+export const deactivate = os.license.deactivate
+ .use(dbProvider)
+ .handler(async ({ context }) => {
+ await ensureLicenseActivationInitialized()
+
+ const record = await context.db.query.licenseActivationTable.findFirst()
+
+ if (!record) {
+ throw new Error('License activation record not found')
+ }
+
+ await context.db
+ .update(licenseActivationTable)
+ .set({
+ license: null,
+ licenseActivatedAt: null,
+ })
+ .where(eq(licenseActivationTable.id, record.id))
+
+ return { success: true }
+ })