index.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <script setup lang="tsx">
  2. import { onMounted, ref, watch } from 'vue';
  3. import { useRoute, useRouter } from 'vue-router';
  4. import type { FormInst } from 'naive-ui';
  5. import { NForm, NInput, useMessage } from 'naive-ui';
  6. import {
  7. fetchAddChannel,
  8. fetchAppSecret,
  9. fetchChannelDetail,
  10. fetchEditChannel,
  11. fetchResetAppSecret
  12. } from '@/service/api/h5-manage/channel-manage';
  13. import { fetchGetTenantList } from '@/service/api/tenant';
  14. import ZUpload from '../../../components/zt/upload/z-upload.vue';
  15. const router = useRouter();
  16. const route = useRoute();
  17. const formRef = ref<FormInst | null>(null);
  18. const message = useMessage();
  19. const disabled = ref(false);
  20. const isShow = ref(false);
  21. const payOwnershipDisabled = ref(false);
  22. const loading = ref(false);
  23. const model = ref({
  24. appId: '',
  25. appSecret: '',
  26. id: 0,
  27. accessName: '',
  28. tenantId: undefined,
  29. status: 0,
  30. logoUrl: '',
  31. remark: '',
  32. payOwnership: 1,
  33. shareRatio: 0,
  34. thirdCallbackUrl: '',
  35. themeMainColor: '',
  36. themeSubColor: '',
  37. h5Url: '',
  38. authCallbackUrl: '',
  39. payCallbackUrl: ''
  40. });
  41. const rules = ref({
  42. accessName: {
  43. required: true,
  44. trigger: ['blur', 'input'],
  45. message: '请输入'
  46. },
  47. logoUrl: {
  48. required: true,
  49. trigger: ['blur', 'change'],
  50. message: '请上传'
  51. },
  52. remark: {
  53. required: true,
  54. trigger: ['blur', 'change'],
  55. message: '请输入'
  56. },
  57. tenantId: {
  58. type: 'number' as const,
  59. required: true,
  60. trigger: ['blur', 'change'],
  61. message: '请输入'
  62. },
  63. themeMainColor: {
  64. required: true,
  65. trigger: ['blur', 'change'],
  66. message: '请选择'
  67. },
  68. themeSubColor: {
  69. required: true,
  70. trigger: ['blur', 'change'],
  71. message: '请输入'
  72. },
  73. authCallbackUrl: {
  74. required: true,
  75. trigger: ['blur', 'change'],
  76. message: '请输入'
  77. },
  78. payCallbackUrl: {
  79. required: true,
  80. trigger: ['blur', 'change'],
  81. message: '请选择'
  82. },
  83. shareRatio: {
  84. type: 'number' as const,
  85. required: true,
  86. trigger: ['blur', 'change'],
  87. message: '请输入分账比例'
  88. },
  89. thirdCallbackUrl: {
  90. required: true,
  91. trigger: ['blur', 'change'],
  92. message: '请输入回调地址'
  93. }
  94. // thirdCallbackUrl: {}
  95. });
  96. watch(
  97. () => model.value.payOwnership,
  98. newVal => {
  99. if (newVal === 1) {
  100. rules.value.shareRatio.required = true;
  101. rules.value.thirdCallbackUrl.required = false;
  102. } else if (newVal === 2) {
  103. // 第三方账户:显示回调地址
  104. rules.value.thirdCallbackUrl.required = true;
  105. rules.value.shareRatio.required = false;
  106. }
  107. },
  108. { immediate: true }
  109. );
  110. function handleValidateButtonClick(e: MouseEvent) {
  111. e.preventDefault();
  112. formRef.value?.validate(async errors => {
  113. if (!errors) {
  114. loading.value = true;
  115. const form = JSON.parse(JSON.stringify(model.value));
  116. let res;
  117. if (route.query.mode == 'edit') {
  118. res = await fetchEditChannel(form);
  119. } else {
  120. res = await fetchAddChannel(form);
  121. }
  122. loading.value = false;
  123. console.log(res);
  124. if (!res.error) {
  125. router.push({
  126. path: '/h5-manage/channel-manage'
  127. });
  128. }
  129. } else {
  130. console.log(errors);
  131. message.error('验证失败');
  132. }
  133. });
  134. }
  135. async function getSecret() {
  136. if (isShow.value) {
  137. return;
  138. }
  139. // 获取appSecret接口
  140. const res = await fetchAppSecret(route.query.id);
  141. if (res.data) {
  142. model.value.appSecret = res.data.appSecret;
  143. isShow.value = true;
  144. }
  145. }
  146. async function handleResetSecret() {
  147. window.$dialog?.info({
  148. title: '提示',
  149. content: `你确定要重置秘钥吗?`,
  150. positiveText: '确定',
  151. negativeText: '取消',
  152. onPositiveClick: async () => {
  153. // 重置秘钥接口
  154. const res = await fetchResetAppSecret(route.query.id);
  155. if (res.data) {
  156. model.value.appSecret = res.data.appSecret;
  157. isShow.value = true;
  158. message.success('重置成功');
  159. }
  160. }
  161. });
  162. }
  163. async function getDetail() {
  164. // 获取详情接口
  165. const res = await fetchChannelDetail(route.query.id);
  166. if (res.data) {
  167. model.value = res.data;
  168. model.value.id = Number(route.query.id);
  169. }
  170. }
  171. onMounted(() => {
  172. if (route.query.id) {
  173. payOwnershipDisabled.value = true;
  174. if (route.query.mode === 'detail') {
  175. disabled.value = true;
  176. }
  177. getDetail();
  178. }
  179. console.log(route.query);
  180. });
  181. </script>
  182. <template>
  183. <div class="edit-health-goods pl-20px pt-20px">
  184. <NForm
  185. ref="formRef"
  186. :model="model"
  187. :rules="rules"
  188. label-placement="left"
  189. label-width="120px"
  190. require-mark-placement="right-hanging"
  191. size="medium"
  192. class="max-w-840px"
  193. :disabled="disabled"
  194. >
  195. <div class="font-600">基本信息</div>
  196. <template v-if="disabled">
  197. <NFormItem label="app_id">
  198. <div>{{ model.appId }}</div>
  199. <!-- <NInput v-model:value="model.appId" placeholder="" /> -->
  200. </NFormItem>
  201. <NFormItem label="app_secret">
  202. <div class="flex items-center">
  203. <div>{{ model.appSecret }}</div>
  204. <div @click="getSecret">
  205. <SvgIcon v-if="!isShow" icon="weui:eyes-off-filled" class="ml-10px"></SvgIcon>
  206. </div>
  207. <NButton class="ml-10px" round type="primary" size="small" :loading="loading" @click="handleResetSecret">
  208. 重置秘钥
  209. </NButton>
  210. </div>
  211. <!-- <NInput v-model:value="model.appSecret" placeholder="" /> -->
  212. </NFormItem>
  213. </template>
  214. <NFormItem label="渠道名称" path="accessName">
  215. <div class="w-100%">
  216. <NInput v-model:value="model.accessName" :maxlength="20" placeholder="" />
  217. <div class="text-12px">最多支持20个汉字;</div>
  218. </div>
  219. </NFormItem>
  220. <NFormItem label="租户编号" path="tenantId">
  221. <ApiSelect
  222. v-model:value="model.tenantId"
  223. :api="fetchGetTenantList"
  224. result-feild="data.list"
  225. label-field="tenantCode"
  226. value-field="id"
  227. ></ApiSelect>
  228. </NFormItem>
  229. <NFormItem label="状态">
  230. <NSwitch v-model:value="model.status" :unchecked-value="0" :checked-value="1" />
  231. </NFormItem>
  232. <NFormItem label="渠道LOGO" path="logoUrl">
  233. <ZUpload v-model:value="model.logoUrl" :max="1"></ZUpload>
  234. </NFormItem>
  235. <NFormItem label="备注" path="remark">
  236. <div class="w-100%">
  237. <NInput v-model:value="model.remark" type="textarea" show-count :maxlength="500" placeholder="" />
  238. <div class="text-12px">最多支持500个汉字;</div>
  239. </div>
  240. </NFormItem>
  241. <div class="flex">
  242. <div class="items-center font-600">支付归属</div>
  243. <div class="ml-20px text-12px">支付归属影响资金流向,一旦确定不可变更。如需切换,建议新建渠道后迁移。</div>
  244. </div>
  245. <NFormItem label="支付方式设置" path="payType">
  246. <!-- 平台支付 -->
  247. <NRadioGroup v-model:value="model.payOwnership" :disabled="payOwnershipDisabled" name="radiogroup">
  248. <NFormItem label="" path="shareRatio">
  249. <div class="flex-col">
  250. <div class="flex items-center">
  251. <NRadio :value="1" class="mr-2" />
  252. <span class="text-sm">平台支付(资金进入平台商户号,平台统一收款)</span>
  253. </div>
  254. <div v-if="model.payOwnership === 1" class="flex items-center gap-2 pl-6 text-sm">
  255. <span>分账比例设置</span>
  256. <NInputNumber
  257. v-model:value="model.shareRatio"
  258. :disabled="payOwnershipDisabled"
  259. :min="0"
  260. :max="100"
  261. :precision="2"
  262. />
  263. <span>% 给渠道方</span>
  264. </div>
  265. <p v-if="model.payOwnership === 1" class="ml-120px text-xs text-gray-500">范围:0-100,保留两位小数</p>
  266. </div>
  267. </NFormItem>
  268. <!-- 第三方支付 -->
  269. <NFormItem label="" path="thirdCallbackUrl">
  270. <div class="flex items-center">
  271. <NRadio :value="2" class="mr-2" />
  272. <span class="text-sm">第三方支付(资金进入第三方商户,平台只提供技术服务)</span>
  273. </div>
  274. <div v-if="model.payOwnership === 2" class="flex items-center gap-2 pl-6 text-sm">
  275. <span>第三方回调地址</span>
  276. <NInput
  277. v-model:value="model.thirdCallbackUrl"
  278. :disabled="payOwnershipDisabled"
  279. placeholder="请输入回调地址"
  280. class="flex-1"
  281. />
  282. </div>
  283. </NFormItem>
  284. </NRadioGroup>
  285. </NFormItem>
  286. <div class="font-600">主题样式</div>
  287. <NFormItem label="主色" path="themeMainColor">
  288. <NInput v-model:value="model.themeMainColor" placeholder="" />
  289. </NFormItem>
  290. <NFormItem label="辅色" path="themeSubColor">
  291. <NInput v-model:value="model.themeSubColor" placeholder="" />
  292. </NFormItem>
  293. <div class="font-600">对接配置</div>
  294. <NFormItem label="授权回调地址" path="authCallbackUrl">
  295. <NInput v-model:value="model.authCallbackUrl" placeholder="" />
  296. </NFormItem>
  297. <NFormItem label="支付回调地址" path="payCallbackUrl">
  298. <NInput v-model:value="model.payCallbackUrl" placeholder="" />
  299. </NFormItem>
  300. <div v-if="!disabled" class="flex justify-end">
  301. <NButton round type="primary" :loading="loading" @click="handleValidateButtonClick">保存</NButton>
  302. </div>
  303. </NForm>
  304. </div>
  305. </template>
  306. <style lang="scss" scoped>
  307. ::v-deep .n-form-item-blank {
  308. z-index: 6 !important;
  309. }
  310. .edit-health-goods {
  311. background: #fff;
  312. }
  313. </style>