This is embarassing but what I did wrong is that I checked each letter in the key to see if it had a special character rather than checking each character in the message. I replaced encode with this:
encode :: String -> String -> Int -> String
encode _ [] _ = "...End of message"
encode [] _ _ = "Invalid decoder word!"
encode word (x:xs) y
| x `elem` ['a'..'z'] = [encodex (calcOffset word y) x] ++ encode word xs (y+1)
| x `elem` ['A'..'Z'] = [encodex (calcOffset word y) x] ++ encode word xs (y+1)
| otherwise = [x] ++ encode word xs y
where wordpos = y `mod` length word
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…