import json, subprocess, tempfile, os
|
from urllib.parse import quote
|
|
# 中文查询参数必须预先百分号编码:Windows 下 curl 会把 argv 里的中文按 GBK 转码,
|
# 直接写中文进 URL 会变成乱码查不到数据(与请求体同样的坑,请求体走 --data-binary @文件)。
|
def q(text):
|
return quote(text, encoding='utf-8')
|
|
def kw(value):
|
# 方括号必须百分号编码(参数名前端的 tansParams 就是 encodeURIComponent(键)),
|
# 原样写 params[keyword]= 会被 Tomcat 以 400 Bad Request 拒掉
|
return 'params%5Bkeyword%5D=' + q(value)
|
|
def api(method, url, body=None):
|
cmd = ['sh', '.tmp_api.sh', method, url]
|
tmp = None
|
if body is not None:
|
fd, tmp = tempfile.mkstemp(suffix='.json')
|
with os.fdopen(fd, 'w', encoding='utf-8') as f:
|
json.dump(body, f, ensure_ascii=False)
|
cmd.append(tmp)
|
out = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8').stdout.strip()
|
if tmp:
|
os.remove(tmp)
|
try:
|
return json.loads(out)
|
except Exception:
|
return {'raw': out}
|
|
def show(tag, res, keys=None):
|
if 'code' in res:
|
msg = res.get('msg')
|
extra = ''
|
if keys:
|
extra = ' | ' + str({k: res.get('data', {}) and (res['data'][k] if isinstance(res['data'], dict) else None) for k in keys})
|
print(f'{tag}: code={res["code"]} msg={msg}{extra}')
|
else:
|
print(f'{tag}: {str(res)[:200]}')
|
|
print('=== A. 城市列表与筛选 ===')
|
r = api('GET', '/account/user/city/list?pageNum=1&pageSize=50')
|
print('A1 全部(未删除)total =', r['total'], '(期望 28 = 27正常 + 1禁用)')
|
r = api('GET', '/account/user/city/list?' + kw('杭州'))
|
print('A2 keyword=杭州 total =', r.get('total', r), '首行 =', [(x['province'], x['cityName']) for x in r.get('rows', [])])
|
r = api('GET', '/account/user/city/list?' + kw('广东'))
|
print('A3 keyword=广东 total =', r.get('total', r), '(按省份模糊匹配)')
|
r = api('GET', '/account/user/city/list?status=1')
|
print('A4 status=1 total =', r['total'], [(x['cityName'], x['status']) for x in r['rows']])
|
r = api('GET', '/account/user/city/list?pageNum=1&pageSize=5')
|
print('A5 分页 pageSize=5 -> rows =', len(r['rows']), 'total =', r['total'])
|
|
print()
|
print('=== B. 新增校验 ===')
|
show('B1 同名', api('POST', '/account/user/city', {'province': '浙江省', 'cityName': '杭州'}))
|
show('B2 缺省', api('POST', '/account/user/city', {'cityName': '测试市'}))
|
show('B3 缺市名', api('POST', '/account/user/city', {'province': '测试省'}))
|
r = api('POST', '/account/user/city', {'province': '广东省', 'cityName': '珠海', 'sortNo': 999})
|
show('B4 新增珠海', r)
|
|
print()
|
print('=== C. 修改 / 状态 / 删除(自建数据,用完清理) ===')
|
r = api('GET', '/account/user/city/list?' + kw('珠海'))
|
cid = r['rows'][0]['id'] if r.get('rows') else None
|
print('C0 新增后的 id =', cid)
|
show('C1 改名成珠海市(同名查重排除自身)', api('PUT', '/account/user/city', {'id': cid, 'province': '广东省', 'cityName': '珠海'}))
|
show('C2 改成已存在的城市名', api('PUT', '/account/user/city', {'id': cid, 'province': '广东省', 'cityName': '杭州'}))
|
show('C3 不存在的 id', api('PUT', '/account/user/city', {'id': 999999, 'province': '广东省', 'cityName': '珠海'}))
|
show('C4 非法状态', api('PUT', '/account/user/city/changeStatus', {'id': cid, 'status': '9'}))
|
show('C5 禁用', api('PUT', '/account/user/city/changeStatus', {'id': cid, 'status': '1'}))
|
opts = api('GET', '/account/user/city/options')['data']
|
print('C6 禁用后是否还在 options 里 =', any(x['id'] == cid for x in opts))
|
show('C7 启用', api('PUT', '/account/user/city/changeStatus', {'id': cid, 'status': '0'}))
|
print('C8 删除被档案引用的城市(杭州 id=113):', end=' ')
|
show('', api('DELETE', '/account/user/city/113'))
|
print('C9 删除无引用的城市(珠海 id=%s):' % cid, end=' ')
|
show('', api('DELETE', '/account/user/city/%s' % cid))
|
r = api('GET', '/account/user/city/list?pageNum=1&pageSize=50')
|
print('C10 清理后 total =', r['total'], '(期望回到 28)')
|
r = api('GET', '/account/user/city/list?' + kw('珠海'))
|
print('C11 已删除的珠海是否还在列表 =', r.get('total', 0) > 0, '(期望 False)')
|