From cc716e30748ac729c72d1e873d662c5aa079f321 Mon Sep 17 00:00:00 2001 From: CareyWong Date: Thu, 28 May 2020 00:42:14 +0800 Subject: [PATCH] =?UTF-8?q?-=20Add=201.=20=E5=A2=9E=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E7=9F=AD=E9=93=BE=E6=8E=A5=E5=8F=A3=EF=BC=8C?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E7=9F=AD=E9=93=BE=202.=20=E7=9F=AD=E9=93=BE=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E6=97=B6=E8=87=AA=E5=8A=A8=E7=BB=AD=E6=9C=9F1D=EF=BC=8C?= =?UTF-8?q?=E6=AF=8F=E5=A4=A9=E5=85=81=E8=AE=B8=E7=BB=AD=E6=9C=9F1?= =?UTF-8?q?=E6=AC=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 64 +++++++++++++++++++++++++++++++++++++---------- public/index.html | 7 +++++- 2 files changed, 57 insertions(+), 14 deletions(-) diff --git a/main.go b/main.go index c0513fd..25ca9a7 100644 --- a/main.go +++ b/main.go @@ -35,6 +35,11 @@ const defaultPort int = 8002 const defaultExpire = 90 const defaultRedisConfig = "127.0.0.1:6379" +const defaultLockPrefix = "myurls:lock:" +const defaultRenewal = 1 + +const secondsPerDay = 24 * 3600 + var redisPool *redis.Pool var redisPoolConfig *redisPoolConf var redisClient redis.Conn @@ -83,6 +88,7 @@ func main() { } longUrl := context.PostForm("longUrl") + shortKey := context.PostForm("shortKey") if longUrl == "" { res.Message = "longUrl为空" context.JSON(400, *res) @@ -91,25 +97,34 @@ func main() { _longUrl, _ := base64.StdEncoding.DecodeString(longUrl) longUrl = string(_longUrl) - - shortKey := longToShort(longUrl, *ttl*24*3600) - if shortKey == "" { - res.Code = 0 - res.Message = "短链接生成失败" - context.JSON(500, *res) - return - } - - log.Println(longUrl, shortKey) - res.LongUrl = longUrl + // 根据有没有填写 short key,分别执行 + if shortKey != "" { + redisClient := redisPool.Get() + + // 检测短链是否已存在 + _exists, _ := redis.String(redisClient.Do("get", shortKey)) + if _exists != "" && _exists != longUrl { + res.Message = "短链接已存在,请更换key" + context.JSON(400, *res) + return + } + + // 存储 + _, _ = redisClient.Do("set", shortKey, longUrl) + + } else { + shortKey = longToShort(longUrl, *ttl*secondsPerDay) + } + protocol := "http://" if *https != 0 { protocol = "https://" } res.ShortUrl = protocol + *domain + "/" + shortKey + context.Header("Access-Control-Allow-Origin", "*") context.JSON(200, *res) }) @@ -133,6 +148,12 @@ func shortToLong(shortKey string) string { defer redisClient.Close() longUrl, _ := redis.String(redisClient.Do("get", shortKey)) + + // 获取到长链接后,续命1天。每天仅允许续命1次。 + if longUrl != "" { + renew(shortKey) + } + return longUrl } @@ -153,7 +174,7 @@ func longToShort(longUrl string, ttl int) string { // 重试三次 var shortKey string for i := 0; i < 3; i++ { - shortKey = generate(6) + shortKey = generate(7) _existsLongUrl, _ := redis.String(redisClient.Do("get", shortKey)) if _existsLongUrl == "" { @@ -165,7 +186,7 @@ func longToShort(longUrl string, ttl int) string { _, _ = redisClient.Do("mset", shortKey, longUrl, longUrl, shortKey) _, _ = redisClient.Do("expire", shortKey, ttl) - _, _ = redisClient.Do("expire", longUrl, ttl) + _, _ = redisClient.Do("expire", longUrl, secondsPerDay) } return shortKey @@ -205,3 +226,20 @@ func initRedisPool() { }, } } + +func renew(shortKey string) { + redisClient = redisPool.Get() + defer redisClient.Close() + + // 加锁 + lockKey := defaultLockPrefix + shortKey + lock, _ := redis.Int(redisClient.Do("setnx", lockKey, 1)) + if lock == 1 { + // 设置锁过期时间 + _, _ = redisClient.Do("expire", lockKey, defaultRenewal*secondsPerDay) + + // 续命 + ttl, _ := redis.Int(redisClient.Do("ttl", shortKey)) + _, _ = redisClient.Do("expire", shortKey, ttl+defaultRenewal*secondsPerDay) + } +} diff --git a/public/index.html b/public/index.html index 638476a..ebdf281 100644 --- a/public/index.html +++ b/public/index.html @@ -23,7 +23,7 @@ - + @@ -71,6 +71,7 @@ let data = new FormData(); data.append("longUrl", btoa(this.longUrl)); + data.append("shortKey", this.shortUrl.indexOf('http') < 0 ? this.shortUrl : ''); axios.post(backend + '/short', data, { header: { "Content-Type": "application/form-data; charset=utf-8" @@ -80,6 +81,7 @@ if (res.data.Code === 1 && res.data.ShortUrl !== "") { this.shortUrl = res.data.ShortUrl; this.$copyText(this.shortUrl) + this.$refs.shortUrl.disabled = true this.$message.success("短链接已复制到剪贴板"); } else { this.$message.error("短链接获取失败:" + res.data.Message); @@ -119,6 +121,9 @@ onCopy() { this.$message.success("Copied!"); }, + changeDisableStatus(event) { + this.$refs.shortUrl.disabled = false + } }, })