# 患者端互联网小程序（Taro）- 支付助手

> 微信小程序应用 —— 主要使用 react.js + **[taro](https://docs.taro.zone/docs/)** + **[taroui](https://taro-ui.jd.com/#/)**等技术栈<br/>
> 本项目已升级到 taro3，相关组件的具体文档参考[Taro 文档](https://docs.taro.zone/docs/)<br/>
> 为了追求更高开发效率，根据业务需求的差异，在此仓库中集成**4**个独立小程序，分别是**太和患者端**、**白云患者端**、**云平台**、**支付小程序**。<br />
> 今后，根据具体业务需求，可以进行代码拆解。完全可以独立成全新的小程序，进行某家医院的二次开发。

## 相关文档

- [患者端小程序-微信](./患者端小程序-微信.md)，主要内容为项目的大致结构

- [前端培训资料-小程序](./前端培训资料-小程序.md)，主要内容为多个项目的具体结构，生命周期，全局状态管理，项目运行流程等

本文档主要内容为支付助手小程序的具体功能模块及主要的支付页面的处理流程

## 项目 Git

#### [Gogs Git address](https://gogs.ywtinfo.com/ywt/th_net_hospital_weapp)

#### 生产环境分支：publish

#### 开发环境分支：视需求版本而定，具体命名规则见文末

## 项目 Command

node version: v14.17.0，yarn(包管理工具) install

```json
// 安装依赖
yarn 或者 npm install

// 本地开发快速切换项目
yarn replace:pay // 支付助手

// qa环境运行
yarn run dev:weapp-pay  // 支付助手

// qa环境打包
yarn run build-qa:weapp-pay  // 支付助手

// prod环境打包
yarn run build:weapp-pay  // 支付助手
```

## 文件目录

根据项目打包目录（根目录下的 `app.config.js`）进行功能业务分析

```javascript
export default defineAppConfig({
	pages: [
		"pages/index/index", // 入口文件
		"pages/index/choice", // 服务类型选择
		"pages/index/home", // 首页
		"pages/index/service", // 客服反馈
		"pages/outPatient/guide", // 治疗指引
		"pages/outPatient/detail", // 门诊缴费
		"pages/guangsan/stuffOrder", // 广三耗材
		"pages/guangsan/prescription", // 广三处方
		"pages/guangsan/storeAddress", // 广三药房地址选择
		"pages/order/orderList", // 订单列表
		"pages/order/detail", // 订单详情
		"pages/order/diagnoseReport", // 专家报告
		"pages/follow/chat", // 随访
		"pages/prescription/prescription", // 处方
		"pages/prescription/deliverTrack", // 订单物流跟踪
		"pages/prescription/addressList", // 取药点
		"pages/users/userPage", // 个人中心
		"pages/users/addUser", // 添加用户
		"pages/users/myFamily", // 我的家人
		"pages/users/verify", // 实名认证
		"pages/users/reVerify", // 重新认证
		"pages/users/satisfactionInquiry", // 满意度调查，webview 页面
		"pages/users/sideEffectInquiry", // 不良反应反馈
		"pages/users/patientInquiry", // 问卷调查
		"pages/pay/index", // 支付页面
		"pages/protocol/index", // 公告/协议
	],
	subpackages: [
		{ root: "pages/invoice", pages: ["fillIn", "detail", "edit"] }, // 发票信息
		{
			root: "pages/global", // 通用页面
			pages: [
				"resultTip", // 结果展示
				"login", // 快速登录/立即申请
				"manualLogin", // 手机号登录注册
				"middlePage", // 提交结果页
				"hospitalRecords", // 在院病历
			],
		},
		{
			root: "pages/offline_consult", // 线下咨询，包含了线下详情，诊疗卡列表，添加诊疗卡
			pages: ["detail", "addOrEditCard", "cardList"],
		},
		{
			root: "pages/th", // 太和业务
			pages: [
				"stuffOrder", // 耗材
				"stuffInvoiceDetail", // 发票
				"prescriptionList", // 处方列表
				"prescription", // 处方详情
				"checkIndex", // 检查检验结果
				"checkTestResult", // 检验结果
				"checkResult", // 检查结果
				"checkResultPay", // 检查结果支付
				"checkResultWaiting", // 检查结果预计时间
			],
		},
		{ root: "pages/drug", pages: ["search", "details", "newsDetails"] }, // 用药查询
		{
			root: "pages/by", // 白云业务，支付，眼镜店取货，自助报道
			pages: ["global/pay", "glasses/mail", "reported/index"],
		},
		{ root: "pages/qrcodes", pages: ["nucleic_acid/index"] }, // 核酸检测缴费
		{
			root: "pages/medical_device", // 检查报告
			pages: ["reportList", "checkContent", "reportDetail"],
		},
	],
	// 其他项目配置...
});
```

## 跳转支付流程

以白云小程序外转处方跳转到支付助手小程序支付为例：

1.白云小程序触发支付动作：

`src/pages/by/prescription/index.js`

```js
// 支付跳转逻辑判断，微信 => 医务通小助手，工行 => 医务通云平台
isWeChatPay = async () => {
	let isWeChatPay = true;
	const payPathResult = await getPaymentConfig();
	isWeChatPay = payPathResult.isWeChatPay === 1;
	return isWeChatPay;
};

// 点击支付按钮
const onPay = async () => {
	// 判断支付渠道
	const isWeChatPay = await isWeChatPay();
	jumpPay(
		orderId,
		total,
		"cfwz",
		() => {},
		"prescription",
		() => {},
		null,
		null,
		isWeChatPay
	);
};
```

2.触发公共方法 `jumpPay()`，跳转到支付：

`src/utils/utils.js`

```js
export function jumpPay(
	orderId, // 支付orderId
	amount, // 支付金额，单位是分
	source, // 业务来源，分为guangsan和太和（初始支付业务简单使用的字段），新增cfwz（处方外转）
	fail, // 支付失败回调
	businesstype = "", // 业务类型，进一步区分同来源下不同业务的渲染，以及支付成功的判断
	success = () => {}, // 支付成功回调
	apiType = "", // 支付接口类型，区分调用不同支付接口
	other = "", // 支付接口更多的传参对象
	isWeChatPay = true // 支付配置，是否是微信支付，是则跳转至医务通支付助手支付；如果是去往工行对应的商户，则跳转至医务通云平台小程序支付
) {
	// 医务通支付助手：wxaf8c063f54bd52fb；云平台：wxf69c32bf44d378a8
	const weappConfig = Taro.getStorageSync("weapp-config");
	const appId = isWeChatPay ? "wxaf8c063f54bd52fb" : "wxf69c32bf44d378a8";
	const queryStr = stringify(
		{
			orderId,
			amount,
			source,
			type: businesstype,
			apiType,
			other,
		},
		{ addQueryPrefix: true }
	);
	console.log("queryStr ===>", queryStr);
	Taro.navigateToMiniProgram({
		appId,
		path: `pages/index/index${queryStr}`,
		extraData: {},
		envVersion: weappConfig.envVersion,
	})
		.then(() => {
			log.info("n");
			success();
		})
		.catch(() => {
			log.error();
			// Taro.showToast({ title: '跳转失败', icon: 'none' })
			fail();
		});
}
```

3.支付助手首页接收并解析参数，传递到支付页面：

`src/pages/index/index.js`

```js
import Taro, { getCurrentInstance } from "@tarojs/taro";
import React, { Component } from "react";
import { View } from "@tarojs/components";
import { observer, inject } from "mobx-react";
import parse from "url-parse";
import { stringify } from "qs";
import { handleToken, checkShowCount } from "../../utils/utils";
import log from "../../utils/log";
import { set } from "../../store/globalData";
import { syncMedCards } from "../../server/globalApi";
import initConfig from "../../config/index";

console.log("NODE_ENV", process.env.NODE_ENV, "APP_TYPE", APP_TYPE);
@inject("userInfo")
@observer
class Index extends Component {
	constructor(props) {}

	componentDidMount() {
		const { q, entry, payInfo, orderId, amount } =
			getCurrentInstance().router.params;

		handleToken((data) => {
			set("userInfo", data);
			userInfo.initData(data);

			if (q) {
				// 其他链接进入逻辑
			} else if (entry) {
				// 其他链接进入逻辑
			} else if (
				orderId &&
				amount &&
				(APP_TYPE === "pay-app" || APP_TYPE === "yun-app")
			) {
				const queryStr = stringify(getCurrentInstance().router.params || {}, {
					addQueryPrefix: false,
				});
				// 跳转到支付页面
				Taro.redirectTo({ url: `/pages/pay/index?${queryStr}` });
			} else {
				// debugger;
				Taro.reLaunch({ url: `/pages/index/home` });
			}
		});
	}
	render() {
		return <View></View>;
	}
}

export default Index;
```

4.支付页面解析路由参数，订阅消息授权，发起支付：

`src/pages/pay/index.js`

5.支付成功/失败后，返回白云小程序外转处方详情页，详情页重新获取详情，更改处方状态
