|
|
@@ -0,0 +1,339 @@
|
|
|
+<script setup lang="tsx">
|
|
|
+import { onMounted, ref, watch } from 'vue';
|
|
|
+import { useRoute, useRouter } from 'vue-router';
|
|
|
+import type { FormInst } from 'naive-ui';
|
|
|
+import { NForm, NInput, useMessage } from 'naive-ui';
|
|
|
+import {
|
|
|
+ fetchAddChannel,
|
|
|
+ fetchAppSecret,
|
|
|
+ fetchChannelDetail,
|
|
|
+ fetchEditChannel,
|
|
|
+ fetchResetAppSecret
|
|
|
+} from '@/service/api/h5-manage/channel-manage';
|
|
|
+import { fetchGetTenantList } from '@/service/api/tenant';
|
|
|
+import ZUpload from '../../../components/zt/upload/z-upload.vue';
|
|
|
+const router = useRouter();
|
|
|
+const route = useRoute();
|
|
|
+const formRef = ref<FormInst | null>(null);
|
|
|
+const message = useMessage();
|
|
|
+const disabled = ref(false);
|
|
|
+const isShow = ref(false);
|
|
|
+const payOwnershipDisabled = ref(false);
|
|
|
+const loading = ref(false);
|
|
|
+
|
|
|
+const model = ref({
|
|
|
+ appId: '',
|
|
|
+ appSecret: '',
|
|
|
+ id: 0,
|
|
|
+ accessName: '',
|
|
|
+ tenantId: undefined,
|
|
|
+ status: 0,
|
|
|
+ logoUrl: '',
|
|
|
+ remark: '',
|
|
|
+ payOwnership: 1,
|
|
|
+ shareRatio: 0,
|
|
|
+ thirdCallbackUrl: '',
|
|
|
+ themeMainColor: '',
|
|
|
+ themeSubColor: '',
|
|
|
+ h5Url: '',
|
|
|
+ authCallbackUrl: '',
|
|
|
+ payCallbackUrl: ''
|
|
|
+});
|
|
|
+
|
|
|
+const rules = ref({
|
|
|
+ accessName: {
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'input'],
|
|
|
+ message: '请输入'
|
|
|
+ },
|
|
|
+
|
|
|
+ logoUrl: {
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ message: '请上传'
|
|
|
+ },
|
|
|
+ remark: {
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ message: '请输入'
|
|
|
+ },
|
|
|
+ tenantId: {
|
|
|
+ type: 'number' as const,
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ message: '请输入'
|
|
|
+ },
|
|
|
+ themeMainColor: {
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ message: '请选择'
|
|
|
+ },
|
|
|
+ themeSubColor: {
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ message: '请输入'
|
|
|
+ },
|
|
|
+ authCallbackUrl: {
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ message: '请输入'
|
|
|
+ },
|
|
|
+ payCallbackUrl: {
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ message: '请选择'
|
|
|
+ },
|
|
|
+ shareRatio: {
|
|
|
+ type: 'number' as const,
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ message: '请输入分账比例'
|
|
|
+ },
|
|
|
+ thirdCallbackUrl: {
|
|
|
+ required: true,
|
|
|
+ trigger: ['blur', 'change'],
|
|
|
+ message: '请输入回调地址'
|
|
|
+ }
|
|
|
+ // thirdCallbackUrl: {}
|
|
|
+});
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => model.value.payOwnership,
|
|
|
+ newVal => {
|
|
|
+ if (newVal === 1) {
|
|
|
+ rules.value.shareRatio.required = true;
|
|
|
+ rules.value.thirdCallbackUrl.required = false;
|
|
|
+ } else if (newVal === 2) {
|
|
|
+ // 第三方账户:显示回调地址
|
|
|
+ rules.value.thirdCallbackUrl.required = true;
|
|
|
+ rules.value.shareRatio.required = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { immediate: true }
|
|
|
+);
|
|
|
+
|
|
|
+function handleValidateButtonClick(e: MouseEvent) {
|
|
|
+ e.preventDefault();
|
|
|
+ formRef.value?.validate(async errors => {
|
|
|
+ if (!errors) {
|
|
|
+ loading.value = true;
|
|
|
+
|
|
|
+ const form = JSON.parse(JSON.stringify(model.value));
|
|
|
+
|
|
|
+ let res;
|
|
|
+ if (route.query.mode == 'edit') {
|
|
|
+ res = await fetchEditChannel(form);
|
|
|
+ } else {
|
|
|
+ res = await fetchAddChannel(form);
|
|
|
+ }
|
|
|
+ loading.value = false;
|
|
|
+ console.log(res);
|
|
|
+
|
|
|
+ if (!res.error) {
|
|
|
+ router.push({
|
|
|
+ path: '/h5-manage/channel-manage'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.log(errors);
|
|
|
+ message.error('验证失败');
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+async function getSecret() {
|
|
|
+ if (isShow.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取appSecret接口
|
|
|
+ const res = await fetchAppSecret(route.query.id);
|
|
|
+ if (res.data) {
|
|
|
+ model.value.appSecret = res.data.appSecret;
|
|
|
+ isShow.value = true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+async function handleResetSecret() {
|
|
|
+ window.$dialog?.info({
|
|
|
+ title: '提示',
|
|
|
+ content: `你确定要重置秘钥吗?`,
|
|
|
+ positiveText: '确定',
|
|
|
+ negativeText: '取消',
|
|
|
+ onPositiveClick: async () => {
|
|
|
+ // 重置秘钥接口
|
|
|
+ const res = await fetchResetAppSecret(route.query.id);
|
|
|
+ if (res.data) {
|
|
|
+ model.value.appSecret = res.data.appSecret;
|
|
|
+ isShow.value = true;
|
|
|
+ message.success('重置成功');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+async function getDetail() {
|
|
|
+ // 获取详情接口
|
|
|
+ const res = await fetchChannelDetail(route.query.id);
|
|
|
+ if (res.data) {
|
|
|
+ model.value = res.data;
|
|
|
+ model.value.id = Number(route.query.id);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ if (route.query.id) {
|
|
|
+ payOwnershipDisabled.value = true;
|
|
|
+ if (route.query.mode === 'detail') {
|
|
|
+ disabled.value = true;
|
|
|
+ }
|
|
|
+ getDetail();
|
|
|
+ }
|
|
|
+ console.log(route.query);
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="edit-health-goods pl-20px pt-20px">
|
|
|
+ <NForm
|
|
|
+ ref="formRef"
|
|
|
+ :model="model"
|
|
|
+ :rules="rules"
|
|
|
+ label-placement="left"
|
|
|
+ label-width="120px"
|
|
|
+ require-mark-placement="right-hanging"
|
|
|
+ size="medium"
|
|
|
+ class="max-w-840px"
|
|
|
+ :disabled="disabled"
|
|
|
+ >
|
|
|
+ <div class="font-600">基本信息</div>
|
|
|
+ <template v-if="disabled">
|
|
|
+ <NFormItem label="app_id">
|
|
|
+ <div>{{ model.appId }}</div>
|
|
|
+ <!-- <NInput v-model:value="model.appId" placeholder="" /> -->
|
|
|
+ </NFormItem>
|
|
|
+ <NFormItem label="app_secret">
|
|
|
+ <div class="flex items-center">
|
|
|
+ <div>{{ model.appSecret }}</div>
|
|
|
+ <div @click="getSecret">
|
|
|
+ <SvgIcon v-if="!isShow" icon="weui:eyes-off-filled" class="ml-10px"></SvgIcon>
|
|
|
+ </div>
|
|
|
+ <NButton class="ml-10px" round type="primary" size="small" :loading="loading" @click="handleResetSecret">
|
|
|
+ 重置秘钥
|
|
|
+ </NButton>
|
|
|
+ </div>
|
|
|
+ <!-- <NInput v-model:value="model.appSecret" placeholder="" /> -->
|
|
|
+ </NFormItem>
|
|
|
+ </template>
|
|
|
+ <NFormItem label="渠道名称" path="accessName">
|
|
|
+ <div class="w-100%">
|
|
|
+ <NInput v-model:value="model.accessName" :maxlength="20" placeholder="" />
|
|
|
+ <div class="text-12px">最多支持20个汉字;</div>
|
|
|
+ </div>
|
|
|
+ </NFormItem>
|
|
|
+
|
|
|
+ <NFormItem label="租户编号" path="tenantId">
|
|
|
+ <ApiSelect
|
|
|
+ v-model:value="model.tenantId"
|
|
|
+ :api="fetchGetTenantList"
|
|
|
+ result-feild="data.list"
|
|
|
+ label-field="tenantCode"
|
|
|
+ value-field="id"
|
|
|
+ ></ApiSelect>
|
|
|
+ </NFormItem>
|
|
|
+
|
|
|
+ <NFormItem label="状态">
|
|
|
+ <NSwitch v-model:value="model.status" :unchecked-value="0" :checked-value="1" />
|
|
|
+ </NFormItem>
|
|
|
+
|
|
|
+ <NFormItem label="渠道LOGO" path="logoUrl">
|
|
|
+ <ZUpload v-model:value="model.logoUrl" :max="1"></ZUpload>
|
|
|
+ </NFormItem>
|
|
|
+ <NFormItem label="备注" path="remark">
|
|
|
+ <div class="w-100%">
|
|
|
+ <NInput v-model:value="model.remark" type="textarea" show-count :maxlength="500" placeholder="" />
|
|
|
+ <div class="text-12px">最多支持500个汉字;</div>
|
|
|
+ </div>
|
|
|
+ </NFormItem>
|
|
|
+
|
|
|
+ <div class="flex">
|
|
|
+ <div class="items-center font-600">支付归属</div>
|
|
|
+ <div class="ml-20px text-12px">支付归属影响资金流向,一旦确定不可变更。如需切换,建议新建渠道后迁移。</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <NFormItem label="支付方式设置" path="payType">
|
|
|
+ <!-- 平台支付 -->
|
|
|
+ <NRadioGroup v-model:value="model.payOwnership" :disabled="payOwnershipDisabled" name="radiogroup">
|
|
|
+ <NFormItem label="" path="shareRatio">
|
|
|
+ <div class="flex-col">
|
|
|
+ <div class="flex items-center">
|
|
|
+ <NRadio :value="1" class="mr-2" />
|
|
|
+ <span class="text-sm">平台支付(资金进入平台商户号,平台统一收款)</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="model.payOwnership === 1" class="flex items-center gap-2 pl-6 text-sm">
|
|
|
+ <span>分账比例设置</span>
|
|
|
+ <NInputNumber
|
|
|
+ v-model:value="model.shareRatio"
|
|
|
+ :disabled="payOwnershipDisabled"
|
|
|
+ :min="0"
|
|
|
+ :max="100"
|
|
|
+ :precision="2"
|
|
|
+ />
|
|
|
+ <span>% 给渠道方</span>
|
|
|
+ </div>
|
|
|
+ <p v-if="model.payOwnership === 1" class="ml-120px text-xs text-gray-500">范围:0-100,保留两位小数</p>
|
|
|
+ </div>
|
|
|
+ </NFormItem>
|
|
|
+ <!-- 第三方支付 -->
|
|
|
+ <NFormItem label="" path="thirdCallbackUrl">
|
|
|
+ <div class="flex items-center">
|
|
|
+ <NRadio :value="2" class="mr-2" />
|
|
|
+ <span class="text-sm">第三方支付(资金进入第三方商户,平台只提供技术服务)</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="model.payOwnership === 2" class="flex items-center gap-2 pl-6 text-sm">
|
|
|
+ <span>第三方回调地址</span>
|
|
|
+ <NInput
|
|
|
+ v-model:value="model.thirdCallbackUrl"
|
|
|
+ :disabled="payOwnershipDisabled"
|
|
|
+ placeholder="请输入回调地址"
|
|
|
+ class="flex-1"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </NFormItem>
|
|
|
+ </NRadioGroup>
|
|
|
+ </NFormItem>
|
|
|
+
|
|
|
+ <div class="font-600">主题样式</div>
|
|
|
+ <NFormItem label="主色" path="themeMainColor">
|
|
|
+ <NInput v-model:value="model.themeMainColor" placeholder="" />
|
|
|
+ </NFormItem>
|
|
|
+ <NFormItem label="辅色" path="themeSubColor">
|
|
|
+ <NInput v-model:value="model.themeSubColor" placeholder="" />
|
|
|
+ </NFormItem>
|
|
|
+
|
|
|
+ <div class="font-600">对接配置</div>
|
|
|
+
|
|
|
+ <NFormItem label="授权回调地址" path="authCallbackUrl">
|
|
|
+ <NInput v-model:value="model.authCallbackUrl" placeholder="" />
|
|
|
+ </NFormItem>
|
|
|
+ <NFormItem label="支付回调地址" path="payCallbackUrl">
|
|
|
+ <NInput v-model:value="model.payCallbackUrl" placeholder="" />
|
|
|
+ </NFormItem>
|
|
|
+
|
|
|
+ <div v-if="!disabled" class="flex justify-end">
|
|
|
+ <NButton round type="primary" :loading="loading" @click="handleValidateButtonClick">保存</NButton>
|
|
|
+ </div>
|
|
|
+ </NForm>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+::v-deep .n-form-item-blank {
|
|
|
+ z-index: 6 !important;
|
|
|
+}
|
|
|
+.edit-health-goods {
|
|
|
+ background: #fff;
|
|
|
+}
|
|
|
+</style>
|