微信app支付功能-服务端的实现-python3版

  • 一:需求说明
  • 二:微信app支付处理流程
  • 三:所需依赖
    • 3.1 支付配置
  • 四:接口开发
    • 4.1 创建订单接口
    • 4.2 微信异步回调接口
    • 4.3 订单状态查询

一:需求说明

在自有的android app中加入微信支付功能,app内点击支付按钮,需app调起本机上的微信app进行支付。

二:微信app支付处理流程


上图为微信官方支付流程图,由图可见,商户服务端需要实现3部分业务,其中2部分业务与商户客户端调用相关,另一部分业务与微信服务端回调相关。

注:开发文档路径:访问微信开发文档https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3

三:所需依赖

3.1 支付配置

APP_ID
在微信开放平台(https://open.weixin.qq.com)获取APPID

如果没有创建应用,请先创建

MCH_ID
在微信商户平台获取MCH_ID

API密钥
获取API密钥

四:接口开发

4.1 创建订单接口

创建订单,对订单数据进行签名,然后向微信服务器发送创建订单请求。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literalsimport traceback
import logging
import uuid
import requests
import json
import xmltodict
import time
import pymysql
import datetime
import randomfrom hashlib import md5MYSQL = dict(host='127.0.0.1', user='mysql_user', passwd='mysql_pwd', db='mydb', charset="utf8mb4"
)
logger = logging.getLogger(__name__)
conn = pymysql.connect(**MYSQL)
cur_dict = conn.cursor(pymysql.cursors.DictCursor)
cur = conn.cursor()###############################################
#############    微信支付配置   #################
###############################################
# 微信支付APP_ID
WEIXIN_APP_ID = 'wx91f04ffbf8a23431'
# 微信支付MCH_ID 【登录账号】
WEIXIN_MCH_ID = '1535411231'
# 微信支付sign_type
WEIXIN_SIGN_TYPE = 'MD5'
# 服务器IP地址
WEIXIN_SPBILL_CREATE_IP = '32.23.11.34'
# 微信支付用途
WEIXIN_BODY = '费用充值'
# 微信KEY值 【API密钥】
WEIXIN_KEY = 'ZiwcVpWomDqixQdhRgm5FpBKNXqwasde'
# 微信统一下单URL
WEIXIN_UNIFIED_ORDER_URL = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
# 微信查询订单URL
WEIXIN_QUERY_ORDER_URL = 'https://api.mch.weixin.qq.com/pay/orderquery'
# 微信支付回调API
WEIXIN_CALLBACK_API = 'http://xxxx.com/weixinpay_rollback/'def make_payment_info(notify_url=None, out_trade_no=None, total_fee=None):order_info = {'appid': WEIXIN_APP_ID,'mch_id': WEIXIN_MCH_ID,'device_info': 'WEB','nonce_str': '','sign_type': WEIXIN_SIGN_TYPE,'body': WEIXIN_BODY,'out_trade_no': str(out_trade_no),'total_fee': total_fee,'spbill_create_ip': WEIXIN_SPBILL_CREATE_IP,'notify_url': notify_url,'trade_type': 'APP'}return order_infodef make_payment_request_wx(notify_url, out_trade_no, total_fee):"""微信统一下单,并返回客户端数据:param notify_url: 回调地址:param out_trade_no: 订单编号:param total_fee: 充值金额:return: app所需结果数据"""def generate_call_app_data(params_dict, prepay_id):"""客户端APP的数据参数包装"""request_order_info = {'appid': params_dict['appid'],'partnerid': params_dict['mch_id'],'prepayid': prepay_id,'package': 'Sign=WXPay','noncestr': generate_nonce_str(),'timestamp': str(int(time.time()))}request_order_info['sign'] = generate_sign(request_order_info)return request_order_infodef generate_sign(params):"""生成md5签名的参数"""if 'sign' in params:params.pop('sign')src = '&'.join(['%s=%s' % (k, v) for k, v in sorted(params.items())]) + '&key=%s' % WEIXIN_KEYreturn md5(src.encode('utf-8')).hexdigest().upper()def generate_nonce_str():"""生成随机字符串"""return str(uuid.uuid4()).replace('-', '')def generate_request_data(params_dict):"""生成统一下单请求所需要提交的数据"""params_dict['nonce_str'] = generate_nonce_str()params_dict['sign'] = generate_sign(params_dict)return xmltodict.unparse({'xml': params_dict}, pretty=True, full_document=False).encode('utf-8')def make_payment_request(params_dict, unified_order_url):"""生成返回给客户端APP的数据参数"""data = generate_request_data(params_dict)headers = {'Content-Type': 'application/xml'}res = requests.post(unified_order_url, data=data, headers=headers)if res.status_code == 200:result = json.loads(json.dumps(xmltodict.parse(res.content)))if result['xml']['return_code'] == 'SUCCESS':prepay_id = result['xml']['prepay_id']return generate_call_app_data(params_dict, prepay_id), result['xml']else:return result['xml']['return_msg'], Nonereturn None, Noneif float(total_fee) < 0.01:raise Exception('充值金额不能小于0.01')payment_info = make_payment_info(notify_url=notify_url, out_trade_no=out_trade_no, total_fee=total_fee)res, info = make_payment_request(payment_info, WEIXIN_UNIFIED_ORDER_URL)return res, infodef create_order(data, out_trade_no):"""创建订单信息,存入库中:return:"""insert_sql = ''' insert into {table}(status, app_id, seller_id, device_info, trade_type, prepay_id, trade_status, out_trade_no, total_amount) values (3, '{app_id}', '{seller_id}', '{device_info}', '{trade_type}', '{prepay_id}', '{trade_status}', '{out_trade_no}', '{total_amount}')'''app_id = data['appid']  # 应用IDseller_id = data['mch_id']  # 商户号device_info = data['device_info']  # 微信支付分配的终端设备号trade_status = data['result_code']  # 业务结果 SUCCESS/FAILtotal_amount = data['total_amount']  # 总金额if trade_status == "SUCCESS":trade_type = data['trade_type']  # 交易类型prepay_id = data['prepay_id']  # 预支付交易会话标识insert_sql = insert_sql.format(app_id=app_id,seller_id=seller_id,device_info=device_info,trade_type=trade_type,prepay_id=prepay_id,trade_status=trade_status,out_trade_no=out_trade_no,total_amount=total_amount/100  # 将微信的分转为元)cur_dict.execute(insert_sql)return Trueelse:return Falsedef create_order_number():"""生成订单号:return:"""date = datetime.datetime.now().strftime("%Y%m%d%H%M%S")# 生成4为随机数作为订单号的一部分random_str = str(random.randint(1, 9999))random_str = random_str.rjust(4, '0')rtn = '%s%s%s' % (date, random_str)return rtndef weixin_create_order(request):"""【API】: 创建订单,供商户app调用"""res = {'code': 1,'msg': 'error'}try:price = 0.99  # 0.99元,微信的单位为分,需要转为分out_trade_no = create_order_number()order_info, info = make_payment_request_wx(WEIXIN_CALLBACK_API, out_trade_no, int(price * 100))if order_info and info:info['total_amount'] = int(price * 100)if info['result_code'] == "SUCCESS":order_info['out_trade_no'] = out_trade_nores['order_info'] = order_infocreate_order(info, out_trade_no)# 调用统一创建订单接口失败else:res['msg'] = info['result_code']elif order_info:res['msg'] = order_infores['code'] = -1else:res['code'] = -2except Exception:traceback.print_exc()finally:return json.dumps(res)

4.2 微信异步回调接口

微信异步回调通知商户服务端。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literalsimport traceback
import logging
import xmltodict
import pymysqlfrom hashlib import md5MYSQL = dict(host='127.0.0.1', user='mysql_user', passwd='mysql_pwd', db='mydb', charset="utf8mb4"
)
logger = logging.getLogger(__name__)
conn = pymysql.connect(**MYSQL)
cur_dict = conn.cursor(pymysql.cursors.DictCursor)
cur = conn.cursor()###############################################
#############    微信支付配置   #################
###############################################
# 微信支付APP_ID
WEIXIN_APP_ID = 'wx91f04ffbf8a23431'
# 微信支付MCH_ID 【登录账号】
WEIXIN_MCH_ID = '1535411231'
# 微信支付sign_type
WEIXIN_SIGN_TYPE = 'MD5'
# 服务器IP地址
WEIXIN_SPBILL_CREATE_IP = '32.23.11.34'
# 微信支付用途
WEIXIN_BODY = '费用充值'
# 微信KEY值 【API密钥】
WEIXIN_KEY = 'ZiwcVpWomDqixQdhRgm5FpBKNXqwasde'
# 微信统一下单URL
WEIXIN_UNIFIED_ORDER_URL = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
# 微信查询订单URL
WEIXIN_QUERY_ORDER_URL = 'https://api.mch.weixin.qq.com/pay/orderquery'
# 微信支付回调API
WEIXIN_CALLBACK_API = 'http://xxxx.com/weixinpay_rollback/'def weixinpay_call_back(request):"""微信支付回调:param request: 回调参数:return:"""def generate_sign(params):"""生成md5签名的参数"""if 'sign' in params:params.pop('sign')src = '&'.join(['%s=%s' % (k, v) for k, v in sorted(params.items())]) + '&key=%s' % WEIXIN_KEYreturn md5(src.encode('utf-8')).hexdigest().upper()def validate_sign(resp_dict):"""验证微信返回的签名"""if 'sign' not in resp_dict:return Falsewx_sign = resp_dict['sign']sign = generate_sign(resp_dict)if sign == wx_sign:return Truereturn Falsedef handle_wx_response_xml(params):"""处理微信支付返回的xml格式数据"""resp_dict = xmltodict.parse(params)['xml']return_code = resp_dict.get('return_code')if return_code == 'SUCCESS':  # 仅仅判断通信标识成功,非交易标识成功,交易需判断result_codeif validate_sign(resp_dict):return resp_dictelse:print('FAIL')returnargs = request.body# 验证平台签名resp_dict = handle_wx_response_xml(args)if resp_dict is None:return Nonereturn resp_dictdef weixinpay_response_xml(params):"""生成交易成功返回信息"""def generate_response_data(resp_dict):"""字典转xml"""return xmltodict.unparse({'xml': resp_dict}, pretty=True, full_document=False).encode('utf-8')return_info = {'return_code': params,'return_msg': 'OK'}return generate_response_data(return_info)def weixin_rollback(request):"""【API】: 微信宝支付结果回调接口,供微信服务端调用"""try:# 支付异步回调验证data = weixinpay_call_back(request)if data:res = "success"trade_status = data['result_code']  # 业务结果  SUCCESS/FAILout_trade_no = data['out_trade_no']  # 商户订单号if trade_status == "SUCCESS":status = 1app_id = data['appid']  # 应用IDbank_type = data['bank_type']  # 付款银行cash_fee = data['cash_fee']  # 现金支付金额(分)device_info = data['device_info']  # 微信支付分配的终端设备号fee_type = data['fee_type']  # 货币种类gmt_create = data['time_end']  # 支付完成时间total_amount = int(data['total_fee'])/100  # 总金额(单位由分转元)trade_type = data['trade_type']  # 交易类型trade_no = data['transaction_id']  # 微信支付订单号seller_id = data['mch_id']  # 商户号buyer_id = data['openid']  # 用户标识update_sql = ''' update orders set trade_status='{trade_status}', app_id='{app_id}', seller_id='{seller_id}', buyer_id='{buyer_id}', total_amount='{total_amount}', out_trade_no='{out_trade_no}', gmt_create='{gmt_create}', trade_no='{trade_no}', device_info='{device_info}', trade_type='{trade_type}', bank_type='{bank_type}', fee_type='{fee_type}', cash_fee='{cash_fee}',  status='{status}' where out_trade_no='{out_trade_no}' '''update_sql = update_sql.format(app_id=app_id,bank_type=bank_type,cash_fee=cash_fee,device_info=device_info,fee_type=fee_type,out_trade_no=out_trade_no,gmt_create=gmt_create,total_amount=total_amount,trade_type=trade_type,trade_no=trade_no,seller_id=seller_id,buyer_id=buyer_id,trade_status=trade_status,status=status)else:res = "error: pay failed! "status = 0err_code = data['err_code']  # 错误代码err_code_des = data['err_code_des']  # 错误代码描述update_sql = ''' update orders set trade_status='{trade_status}', err_code='{err_code}', err_code_des='{err_code_des}', status='{status}' where out_trade_no='{out_trade_no}'  '''update_sql = update_sql.format(out_trade_no=out_trade_no,trade_status=trade_status,status=status,err_code=err_code,err_code_des=err_code_des,)cur_dict.execute(update_sql)conn.commit()else:res = "error: verify failed! "except Exception:traceback.print_exc()finally:return weixinpay_response_xml(res)

4.3 订单状态查询

商户app调用此接口查询【微信服务端】某个订单的支付状态,并同步更新商户服务端订单状态。
可根据需要,将此步骤做成异步任务,实时更新商户服务端订单状态。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literalsimport traceback
import logging
import xmltodict
import pymysql
import uuid
import json
import requestsfrom hashlib import md5MYSQL = dict(host='127.0.0.1', user='mysql_user', passwd='mysql_pwd', db='mydb', charset="utf8mb4"
)
logger = logging.getLogger(__name__)
conn = pymysql.connect(**MYSQL)
cur_dict = conn.cursor(pymysql.cursors.DictCursor)
cur = conn.cursor()###############################################
#############    微信支付配置   #################
###############################################
# 微信支付APP_ID
WEIXIN_APP_ID = 'wx91f04ffbf8a23431'
# 微信支付MCH_ID 【登录账号】
WEIXIN_MCH_ID = '1535411231'
# 微信支付sign_type
WEIXIN_SIGN_TYPE = 'MD5'
# 服务器IP地址
WEIXIN_SPBILL_CREATE_IP = '32.23.11.34'
# 微信支付用途
WEIXIN_BODY = '费用充值'
# 微信KEY值 【API密钥】
WEIXIN_KEY = 'ZiwcVpWomDqixQdhRgm5FpBKNXqwasde'
# 微信统一下单URL
WEIXIN_UNIFIED_ORDER_URL = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
# 微信查询订单URL
WEIXIN_QUERY_ORDER_URL = 'https://api.mch.weixin.qq.com/pay/orderquery'
# 微信支付回调API
WEIXIN_CALLBACK_API = 'http://xxxx.com/weixinpay_rollback/'def update_order(data):"""查询支付订单,并更新订单:param data::return:"""# err_code = data['err_code']  # 错误代码# err_code_des = data['err_code_des']  # 错误代码描述trade_status = data['result_code']  # 业务结果 SUCCESS/FAILapp_id = data['appid']  # 应用IDseller_id = data['mch_id']  # 商户号if trade_status == "SUCCESS":buyer_id = data['openid']  # 用户标识total_amount = int(data['total_fee']) / 100  # 总金额(元)out_trade_no = data['out_trade_no']  # 商户订单号gmt_create = data['time_end']  # 支付完成时间trade_no = data['transaction_id']  # 微信支付订单号trade_status = data['trade_state']  # 交易状态if trade_status == "SUCCESS":status = 1elif trade_status == "USERPAYING":status = 2else:status = 0msg = data['trade_state_desc']# SUCCESS—支付成功# REFUND—转入退款# NOTPAY—未支付# CLOSED—已关闭# REVOKED—已撤销(刷卡支付)# USERPAYING--用户支付中# PAYERROR--支付失败(其他原因,如银行返回失败)device_info = data['device_info']  # 微信支付分配的终端设备号trade_type = data['trade_type']  # 交易类型bank_type = data['bank_type']  # 付款银行fee_type = data['fee_type']  # 货币种类cash_fee = data['cash_fee']  # 现金支付金额(分)# cash_fee_type = data['cash_fee_type']  # 现金支付货币类型# nonce_str = data['nonce_str']  # 随机字符串# coupon_fee = data['coupon_fee']  # 代金券金额# coupon_count = data['coupon_count']  # 代金券使用数量# coupon_id_$n = data['coupon_id_$n']  # 代金券ID# coupon_fee_$n = data['coupon_fee_$n']  # 单个代金券支付金额update_sql = ''' update orders set app_id='{app_id}', seller_id='{seller_id}', buyer_id='{buyer_id}', total_amount='{total_amount}', out_trade_no='{out_trade_no}', gmt_create='{gmt_create}', trade_no='{trade_no}', device_info='{device_info}', trade_type='{trade_type}', bank_type='{bank_type}', fee_type='{fee_type}', cash_fee='{cash_fee}', status='{status}', trade_status='{trade_status}' where out_trade_no='{out_trade_no}'  '''update_sql = update_sql.format(trade_status=trade_status,app_id=app_id,seller_id=seller_id,buyer_id=buyer_id,total_amount=total_amount,out_trade_no=out_trade_no,gmt_create=gmt_create,trade_no=trade_no,device_info=device_info,trade_type=trade_type,bank_type=bank_type,fee_type=fee_type,cash_fee=cash_fee,status=status# err_code_des=err_code_des,# err_code=err_code)cur_dict.execute(update_sql)else:msg = trade_statusstatus = 0update_sql = '''update {table} set  trade_status='{trade_status}', app_id='{app_id}', seller_id='{seller_id}', status='{status}' where id={id} and status!=1 '''update_sql = update_sql.format(# err_code=err_code,# err_code_des=err_code_des,trade_status=trade_status,app_id=app_id,seller_id=seller_id,id=id,status=status)cur_dict.execute(update_sql)conn.commit()return status, msgdef make_querypayment_request(params_dict, query_order_url):"""生成查询订单返回的数据参数"""def generate_nonce_str():"""生成随机字符串"""return str(uuid.uuid4()).replace('-', '')def generate_sign(params):"""生成md5签名的参数"""if 'sign' in params:params.pop('sign')src = '&'.join(['%s=%s' % (k, v) for k, v in sorted(params.items())]) + '&key=%s' % WEIXIN_KEYreturn md5(src.encode('utf-8')).hexdigest().upper()def generate_request_data(params_dict):"""生成统一下单请求所需要提交的数据"""params_dict['nonce_str'] = generate_nonce_str()params_dict['sign'] = generate_sign(params_dict)return xmltodict.unparse({'xml': params_dict}, pretty=True, full_document=False).encode('utf-8')data = generate_request_data(params_dict)headers = {'Content-Type': 'application/xml'}res = requests.post(query_order_url, data=data, headers=headers)if res.status_code == 200:result = json.loads(json.dumps(xmltodict.parse(res.content)))# if result['xml']['return_code'] == 'SUCCESS':#     prepay_id = result['xml']['prepay_id']#     return generate_call_app_data(params_dict, prepay_id)# else:return result['xml']return Nonedef weixin_orderquery(request):"""【API】:支付状态查询,供商户客户端app调用"""res = {'code': 1,'status': 0,'msg': '支付失败!未知错误!'}out_trade_no = request.POST.get('out_trade_no')  # 商户订单号try:select_sql = '''select id, app_id, trade_no, seller_id, status from orders where out_trade_no={out_trade_no} '''select_sql = select_sql.format(out_trade_no=out_trade_no)cur_dict.execute(select_sql)order_data = cur_dict.fetchone()if order_data:id = order_data['id']# 支付成功if order_data['status'] == 1:res['status'] = 1res['msg'] = '支付成功!'# 支付失败elif order_data['status'] == 0:res['status'] = 0res['msg'] = '支付失败!'# 支付过程中, 查询微信服务器支付状态else:params_dict = {'appid': order_data['app_id'],'mch_id': order_data['seller_id'],'transaction_id': order_data['trade_no']}data = make_querypayment_request(params_dict, WEIXIN_QUERY_ORDER_URL)if data:if data['return_code'] == 'SUCCESS':trade_status = data['result_code']  # 业务结果  SUCCESS/FAILif trade_status == "SUCCESS":res['status'], res['msg'] = update_order(data)elif trade_status == "ORDERNOTEXIST":res['msg'] = "支付错误! 微信服务器返回的订单号不存在!"res['status'] = 0elif trade_status == "SYSTEMERROR":res['msg'] = "支付错误! 微信服务器错误!"res['status'] = 0else:res['status'] = 0res['msg'] = "支付错误! 微信服务器支付错误!"else:res['status'] = 0res['msg'] = data['return_msg']else:res['msg'] = "支付错误! 微信服务器通信错误!"else:res['status'] = 0res['msg'] = "订单号不存在!"except Exception:traceback.print_exc()finally:return json.dumps(res)

微信app支付功能-服务端的实现-python3版相关推荐

  1. 支付宝app支付功能-服务端的实现-python3版

    支付宝app支付功能-服务端的实现-python3版 一:需求说明 二:支付宝app支付处理流程 三:所需依赖 3.1 依赖库 3.2 支付配置 3.2.1 沙箱环境配置 3.2.2 正式环境配置 四 ...

  2. Android安卓原生接入微信app支付PHP服务端

    Android安卓接入微信app支付PHP服务端 1.进入微信商户平台查看统一下单接口文档. 在查看完统一下单文档后,能够看到需要传递给微信"统一下单接口"地址的参数有哪些 统一下 ...

  3. android微信支付都需要什么意思,Android开发微信APP支付功能的要点小结

    基本概念 包名值得是你APP的包,在创建工程时候设置的,需要在微信支付平台上面设置. 签名指的是你生成APK时候所用的签名文件的md5,去掉:全部小写,需要在微信支付平台上面设置. 调试阶段,签名文件 ...

  4. 支付宝APP支付Java服务端

    支付宝APP支付Java服务端: 公司项目要求对接支付宝进行支付功能,这边做出整理方便以后使用(支付宝的支付对接还是很简单的). 1):去支付宝开放平台,-1.注册账号,2.创建应用 3.配置应用 4 ...

  5. php tp 微信支付,PHP实现的微信APP支付功能示例【基于TP5框架】

    本文实例讲述了PHP实现的微信APP支付功能.分享给大家供大家参考,具体如下: 1.进行支付请求 他给的DEMO 用的时候有时候会报错 1)我遇到的情况 把  WxPay.Api.php这个文件的 p ...

  6. 微信APP支付功能开发

    前期准备工作 1. 微信各平台功能认识 1.1 微信开放平台: 支持移动应用,公众号的开发,创建应用并得到APPID,使你的应用支持微信支付. 1.2 微信公众平台: 微信小程序,服务号,订阅号的开发 ...

  7. 微信app支付 php,PHP 微信APP支付 整合 thinkphp3.2.3

    php开发APP支付功能中,涉及到微信APP支付功能.为了考虑数据的严密性,加密的过程全部都需要在服务端进行生成.微信APP支付与支付宝的还不太一样.微信APP支付需要二次的加密请求才可以完成整个服务 ...

  8. 基于spring-boot+uni-app实现app支付功能(微信/支付宝)服务端

    基于spring-boot+uni-app实现app支付功能(微信/支付宝)服务端 支付宝支付 1 准备工作 申请支付能力 接口加签方式 2代码 依赖 支付宝支付配置类 支付宝控制层 异步通知 微信支 ...

  9. 微信app支付服务端开发记录

    微信APP支付服务端 调用接口需要注意事项: 1.签名:需要全部参数参加签名,空值去掉.(实际传递了什么参数需要,就根据实际参数进行签名) 2.签名参数:appid是申请支付功能的app对于的ID,k ...

最新文章

  1. 怎么学python-没有任何基础的人,该如何学习Python?「附具体步骤」
  2. React,Redux,React-redux的错综复杂关系
  3. 国际:如何识别真正的程序员
  4. python是干什么的
  5. java编写一个个人通信录程序
  6. 吴恩达神经网络和深度学习-学习笔记-37-inception网络
  7. [转] Scala Try 与错误处理
  8. 1462 通往奥格瑞玛的道路
  9. 软件观念革命:交互设计精髓_电子沙盘设计主要分为哪几种?
  10. 【NGUI】实现半圆形进度条,技能CD效果
  11. matlab测量直流母线上的电压,直流母线
  12. iSCSI网络SCSI接口
  13. Trie 前缀树的c 实现
  14. Linux文本三剑客(grep、sed、awk)
  15. 怎样改变照片大小?免费在线图片压缩方法
  16. 电脑和电脑之间到底是如何通信的
  17. java主程序怎样调用子程序_主程序调用子程序使用( )指令。
  18. 译文Deep Learning in Bioinformatics --深度学习在生物信息学领域的应用(1)
  19. OpenDRIVE文件格式详解
  20. 课程设计--电子地图

热门文章

  1. Winscp链接linux开发版超时,WinSCP联接linux超时.
  2. winscp,winscp连接
  3. 关于数据库账号和密码加密问题
  4. 奢侈太后慈禧的起居生活
  5. 高德地图定位及导航开发流程
  6. 常用HTML技术 淘宝店铺装修
  7. 新手入门AI (Adobe Illustrator)软件工具详解(一)
  8. 调整照片色彩改变照片风格Lightroom Classic2022中文
  9. 【高等代数】行列式的定义和性质
  10. 【笔记】创新思维工作坊(一)