alipayChannelForm.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <template>
  2. <div>
  3. <el-dialog :visible.sync="dialogVisible" :title="title" @closed="close" append-to-body width="800px">
  4. <el-form ref="form" :model="formData" :rules="rules" size="medium" label-width="100px" v-loading="formLoading">
  5. <el-form-item label-width="180px" label="渠道费率" prop="feeRate">
  6. <el-input v-model="formData.feeRate" placeholder="请输入渠道费率" clearable :style="{width: '100%'}">
  7. <template slot="append">%</template>
  8. </el-input>
  9. </el-form-item>
  10. <el-form-item label-width="180px" label="开放平台 APPID" prop="config.appId">
  11. <el-input v-model="formData.config.appId" placeholder="请输入开放平台 APPID" clearable :style="{width: '100%'}">
  12. </el-input>
  13. </el-form-item>
  14. <el-form-item label-width="180px" label="渠道状态" prop="status">
  15. <el-radio-group v-model="formData.status" size="medium">
  16. <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)" :key="parseInt(dict.value)"
  17. :label="parseInt(dict.value)">
  18. {{ dict.label }}
  19. </el-radio>
  20. </el-radio-group>
  21. </el-form-item>
  22. <el-form-item label-width="180px" label="网关地址" prop="config.serverUrl">
  23. <el-radio-group v-model="formData.config.serverUrl" size="medium">
  24. <el-radio label="https://openapi.alipay.com/gateway.do">线上环境</el-radio>
  25. <el-radio label="https://openapi-sandbox.dl.alipaydev.com/gateway.do">沙箱环境</el-radio>
  26. </el-radio-group>
  27. </el-form-item>
  28. <el-form-item label-width="180px" label="算法类型" prop="config.signType">
  29. <el-radio-group v-model="formData.config.signType" size="medium">
  30. <el-radio key="RSA2" label="RSA2">RSA2</el-radio>
  31. </el-radio-group>
  32. </el-form-item>
  33. <el-form-item label-width="180px" label="公钥类型" prop="config.mode">
  34. <el-radio-group v-model="formData.config.mode" size="medium">
  35. <el-radio key="公钥模式" :label="1">公钥模式</el-radio>
  36. <el-radio key="证书模式" :label="2">证书模式</el-radio>
  37. </el-radio-group>
  38. </el-form-item>
  39. <div v-if="formData.config.mode === 1">
  40. <el-form-item label-width="180px" label="应用私钥" prop="config.privateKey">
  41. <el-input type="textarea" :autosize="{minRows: 8, maxRows: 8}" v-model="formData.config.privateKey"
  42. placeholder="请输入应用私钥" clearable :style="{width: '100%'}">
  43. </el-input>
  44. </el-form-item>
  45. <el-form-item label-width="180px" label="支付宝公钥" prop="config.alipayPublicKey">
  46. <el-input
  47. type="textarea"
  48. :autosize="{minRows: 8, maxRows: 8}"
  49. v-model="formData.config.alipayPublicKey"
  50. placeholder="请输入支付宝公钥" clearable
  51. :style="{width: '100%'}">
  52. </el-input>
  53. </el-form-item>
  54. </div>
  55. <div v-if="formData.config.mode === 2">
  56. <el-form-item label-width="180px" label="商户公钥应用证书" prop="config.appCertContent">
  57. <el-input v-model="formData.config.appCertContent" type="textarea"
  58. placeholder="请上传商户公钥应用证书"
  59. readonly :autosize="{minRows: 8, maxRows: 8}" :style="{width: '100%'}"></el-input>
  60. </el-form-item>
  61. <el-form-item label-width="180px" label="">
  62. <el-upload
  63. action=""
  64. ref="privateKeyContentFile"
  65. :limit="1"
  66. :accept="fileAccept"
  67. :http-request="appCertUpload"
  68. :before-upload="fileBeforeUpload">
  69. <el-button size="small" type="primary" icon="el-icon-upload">点击上传</el-button>
  70. </el-upload>
  71. </el-form-item>
  72. <el-form-item label-width="180px" label="支付宝公钥证书" prop="config.alipayPublicCertContent">
  73. <el-input v-model="formData.config.alipayPublicCertContent" type="textarea"
  74. placeholder="请上传支付宝公钥证书"
  75. readonly :autosize="{minRows: 8, maxRows: 8}" :style="{width: '100%'}"></el-input>
  76. </el-form-item>
  77. <el-form-item label-width="180px" label="">
  78. <el-upload
  79. ref="privateCertContentFile"
  80. action=""
  81. :limit="1"
  82. :accept="fileAccept"
  83. :before-upload="fileBeforeUpload"
  84. :http-request="alipayPublicCertUpload">
  85. <el-button size="small" type="primary" icon="el-icon-upload">点击上传</el-button>
  86. </el-upload>
  87. </el-form-item>
  88. <el-form-item label-width="180px" label="根证书" prop="config.rootCertContent">
  89. <el-input
  90. v-model="formData.config.rootCertContent"
  91. type="textarea"
  92. placeholder="请上传根证书"
  93. readonly :autosize="{minRows: 8, maxRows: 8}"
  94. :style="{width: '100%'}">
  95. </el-input>
  96. </el-form-item>
  97. <el-form-item label-width="180px" label="">
  98. <el-upload
  99. ref="privateCertContentFile"
  100. :limit="1"
  101. :accept="fileAccept"
  102. action=""
  103. :before-upload="fileBeforeUpload"
  104. :http-request="rootCertUpload">
  105. <el-button size="small" type="primary" icon="el-icon-upload">点击上传</el-button>
  106. </el-upload>
  107. </el-form-item>
  108. </div>
  109. <el-form-item label-width="180px" label="备注" prop="remark">
  110. <el-input v-model="formData.remark" :style="{width: '100%'}"></el-input>
  111. </el-form-item>
  112. </el-form>
  113. <div slot="footer" class="dialog-footer">
  114. <el-button @click="close">取消</el-button>
  115. <el-button type="primary" @click="submitForm">确定</el-button>
  116. </div>
  117. </el-dialog>
  118. </div>
  119. </template>
  120. <script>
  121. import { createChannel, getChannel, updateChannel } from "@/api/pay/channel";
  122. import { CommonStatusEnum } from "@/utils/constants";
  123. export default {
  124. name: "alipayChannelForm",
  125. data() {
  126. return {
  127. dialogVisible: false,
  128. formLoading: false,
  129. title:'',
  130. formData: {
  131. appId: '',
  132. code: '',
  133. status: undefined,
  134. feeRate: undefined,
  135. remark: '',
  136. config: {
  137. appId: '',
  138. serverUrl: null,
  139. signType: '',
  140. mode: null,
  141. privateKey: '',
  142. alipayPublicKey: '',
  143. appCertContent: '',
  144. alipayPublicCertContent: '',
  145. rootCertContent: ''
  146. }
  147. },
  148. rules: {
  149. feeRate: [{ required: true, message: '请输入渠道费率', trigger: 'blur' }],
  150. status: [{ required: true, message: '渠道状态不能为空', trigger: 'blur' }],
  151. 'config.appId': [{ required: true, message: '请输入开放平台上创建的应用的 ID', trigger: 'blur' }],
  152. 'config.serverUrl': [{ required: true, message: '请传入网关地址', trigger: 'blur' }],
  153. 'config.signType': [{ required: true, message: '请传入签名算法类型', trigger: 'blur' }],
  154. 'config.mode': [{ required: true, message: '公钥类型不能为空', trigger: 'blur'}],
  155. 'config.privateKey': [{ required: true, message: '请输入商户私钥', trigger: 'blur' }],
  156. 'config.alipayPublicKey': [{ required: true, message: '请输入支付宝公钥字符串', trigger: 'blur' }],
  157. 'config.appCertContent': [{ required: true, message: '请上传商户公钥应用证书', trigger: 'blur' }],
  158. 'config.alipayPublicCertContent': [{ required: true, message: '请上传支付宝公钥证书', trigger: 'blur'}],
  159. 'config.rootCertContent': [{ required: true, message: '请上传指定根证书', trigger: 'blur' }],
  160. },
  161. fileAccept: ".crt",
  162. }
  163. },
  164. methods: {
  165. open(appId, code) {
  166. this.dialogVisible = true;
  167. this.formLoading = true;
  168. this.reset(appId, code);
  169. getChannel(appId, code).then(response => {
  170. if (response.data && response.data.id) {
  171. this.formData = response.data;
  172. this.formData.config = JSON.parse(response.data.config);
  173. }
  174. this.title = !this.formData.id ? '创建支付渠道' : '编辑支付渠道'
  175. }).finally(() => {
  176. this.formLoading = false;
  177. });
  178. },
  179. close() {
  180. this.dialogVisible = false;
  181. this.reset(undefined, undefined);
  182. },
  183. submitForm() {
  184. this.$refs['form'].validate(valid => {
  185. if (!valid) {
  186. return
  187. }
  188. const data = { ...this.formData };
  189. data.config = JSON.stringify(this.formData.config);
  190. if (!data.id) {
  191. createChannel(data).then(response => {
  192. this.$modal.msgSuccess("新增成功");
  193. this.$emit('success')
  194. this.close();
  195. });
  196. } else {
  197. updateChannel(data).then(response => {
  198. this.$modal.msgSuccess("修改成功");
  199. this.$emit('success')
  200. this.close();
  201. })
  202. }
  203. });
  204. },
  205. /** 重置表单 */
  206. reset(appId, code) {
  207. this.formData = {
  208. appId: appId,
  209. code: code,
  210. status: CommonStatusEnum.ENABLE,
  211. remark: '',
  212. feeRate: null,
  213. config: {
  214. appId: '',
  215. serverUrl: null,
  216. signType: 'RSA2',
  217. mode: null,
  218. privateKey: '',
  219. alipayPublicKey: '',
  220. appCertContent: '',
  221. alipayPublicCertContent: '',
  222. rootCertContent: ''
  223. }
  224. }
  225. this.resetForm('form')
  226. },
  227. fileBeforeUpload(file) {
  228. let format = '.' + file.name.split(".")[1];
  229. if (format !== this.fileAccept) {
  230. this.$message.error('请上传指定格式"' + this.fileAccept + '"文件');
  231. return false;
  232. }
  233. let isRightSize = file.size / 1024 / 1024 < 2
  234. if (!isRightSize) {
  235. this.$message.error('文件大小超过 2MB')
  236. }
  237. return isRightSize
  238. },
  239. appCertUpload(event) {
  240. const readFile = new FileReader()
  241. readFile.onload = (e) => {
  242. this.formData.config.appCertContent = e.target.result
  243. }
  244. readFile.readAsText(event.file);
  245. },
  246. alipayPublicCertUpload(event) {
  247. const readFile = new FileReader()
  248. readFile.onload = (e) => {
  249. this.formData.config.alipayPublicCertContent = e.target.result
  250. }
  251. readFile.readAsText(event.file);
  252. },
  253. rootCertUpload(event) {
  254. const readFile = new FileReader()
  255. readFile.onload = (e) => {
  256. this.formData.config.rootCertContent = e.target.result
  257. }
  258. readFile.readAsText(event.file);
  259. }
  260. }
  261. }
  262. </script>