Files
medical-mall/pages/mall/admin/app/routine/config.uvue
2026-02-13 01:52:47 +08:00

380 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="admin-page">
<view class="admin-card content-card">
<!-- Tabs (1:1 CRMEB Style) -->
<view class="tabs-row">
<view
class="tab-item"
:class="{ active: activeTab === 'config' }"
@click="activeTab = 'config'"
>
<text class="tab-text">小程序配置</text>
</view>
<view
class="tab-item"
:class="{ active: activeTab === 'message' }"
@click="activeTab = 'message'"
>
<text class="tab-text">消息推送配置</text>
</view>
</view>
<!-- Form Area -->
<view class="config-content">
<!-- Tab 1: 小程序配置 (Image 1) -->
<view v-if="activeTab === 'config'" class="form-body">
<view class="form-item row">
<text class="label">小程序名称:</text>
<view class="form-content">
<input class="form-input" v-model="config.name" placeholder="请输入小程序名称" />
<text class="tip">小程序名称</text>
</view>
</view>
<view class="form-item row">
<text class="label">客服类型:</text>
<view class="form-content">
<view class="radio-group">
<view class="radio-item" @click="config.kefuType = 'system'">
<view class="radio-circle" :class="{ checked: config.kefuType === 'system' }"></view>
<text class="radio-text">跟随系统</text>
</view>
<view class="radio-item" @click="config.kefuType = 'routine'">
<view class="radio-circle" :class="{ checked: config.kefuType === 'routine' }"></view>
<text class="radio-text">小程序客服</text>
</view>
</view>
<text class="tip line-height-tip">跟随系统:跟随系统使用默认客服、电话或者跳转链接;小程序客服:需要在小程序后台配置客服用户;</text>
</view>
</view>
<view class="form-item row">
<text class="label">手机号获取方式:</text>
<view class="form-content">
<view class="checkbox-group">
<view class="checkbox-item" @click="config.authPhone = !config.authPhone">
<view class="checkbox-box" :class="{ checked: config.authPhone }">
<text v-if="config.authPhone" class="check-ic">v</text>
</view>
<text class="checkbox-text">微信授权</text>
</view>
<view class="checkbox-item" @click="config.manualPhone = !config.manualPhone">
<view class="checkbox-box" :class="{ checked: config.manualPhone }">
<text v-if="config.manualPhone" class="check-ic">v</text>
</view>
<text class="checkbox-text">手动填写</text>
</view>
</view>
<text class="tip">小程序获取手机号的方式,微信授权和手机号验证码</text>
</view>
</view>
<view class="form-item row">
<text class="label">强制获取昵称头像:</text>
<view class="form-content">
<view class="radio-group">
<view class="radio-item" @click="config.forceUserInfo = true">
<view class="radio-circle" :class="{ checked: config.forceUserInfo }"></view>
<text class="radio-text">开启</text>
</view>
<view class="radio-item" @click="config.forceUserInfo = false">
<view class="radio-circle" :class="{ checked: !config.forceUserInfo }"></view>
<text class="radio-text">关闭</text>
</view>
</view>
<text class="tip">是否在小程序用户授权之后,弹窗获取用户的昵称和头像</text>
</view>
</view>
<view class="form-item row">
<text class="label">发货信息管理:</text>
<view class="form-content">
<view class="radio-group">
<view class="radio-item" @click="config.deliveryInfo = true">
<view class="radio-circle" :class="{ checked: config.deliveryInfo }"></view>
<text class="radio-text">开启</text>
</view>
<view class="radio-item" @click="config.deliveryInfo = false">
<view class="radio-circle" :class="{ checked: !config.deliveryInfo }"></view>
<text class="radio-text">关闭</text>
</view>
</view>
<text class="tip line-height-tip">小程序有订单发货管理时,请打开此开关,否则会导致订单资金冻结</text>
</view>
</view>
<view class="form-btns">
<button class="btn primary" @click="handleSubmit">提交</button>
</view>
</view>
<!-- Tab 2: 消息推送配置 (Image 2) -->
<view v-if="activeTab === 'message'" class="form-body">
<view class="form-item row">
<text class="label">接口地址:</text>
<view class="form-content">
<input class="form-input readonly" v-model="messageConfig.apiUrl" readonly />
<text class="tip">配置小程序消息推送使用的接口地址,直接复制输入框内容(此项系统生成,无法修改)</text>
</view>
</view>
<view class="form-item row">
<text class="label">小程序验证TOKEN</text>
<view class="form-content">
<input class="form-input" v-model="messageConfig.token" placeholder="请输入小程序验证TOKEN" />
<text class="tip">小程序验证TOKEN</text>
</view>
</view>
<view class="form-item row">
<text class="label">消息加解密方式:</text>
<view class="form-content">
<view class="radio-group">
<view class="radio-item" @click="messageConfig.encryptMode = 'plain'">
<view class="radio-circle" :class="{ checked: messageConfig.encryptMode === 'plain' }"></view>
<text class="radio-text">明文模式</text>
</view>
<view class="radio-item" @click="messageConfig.encryptMode = 'compat'">
<view class="radio-circle" :class="{ checked: messageConfig.encryptMode === 'compat' }"></view>
<text class="radio-text">兼容模式</text>
</view>
<view class="radio-item" @click="messageConfig.encryptMode = 'safe'">
<view class="radio-circle" :class="{ checked: messageConfig.encryptMode === 'safe' }"></view>
<text class="radio-text">安全模式</text>
</view>
</view>
<text class="tip">小程序消息推送中的消息加密方式,暂时仅支持明文模式</text>
</view>
</view>
<view class="form-item row">
<text class="label">EncodingAESKey</text>
<view class="form-content">
<input class="form-input" v-model="messageConfig.aesKey" placeholder="请输入EncodingAESKey" />
<text class="tip">消息加密密钥由43位字符组成字符范围为A-Z,a-z,0-9</text>
</view>
</view>
<view class="form-btns">
<button class="btn primary" @click="handleSubmit">提交</button>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref } from 'vue'
const activeTab = ref('config')
const config = ref({
name: 'CRMEB标准版',
kefuType: 'system',
authPhone: true,
manualPhone: false,
forceUserInfo: true,
deliveryInfo: true
})
const messageConfig = ref({
apiUrl: 'https://v5.crmeb.net/api/wechat/miniServe',
token: '',
encryptMode: 'plain',
aesKey: ''
})
function handleSubmit() {
uni.showToast({
title: '保存成功',
icon: 'success'
})
}
</script>
<style scoped lang="scss">
.admin-page {
padding: 20px;
}
.content-card {
background: #fff;
border-radius: 4px;
}
.tabs-row {
display: flex;
flex-direction: row;
border-bottom: 1px solid #f0f0f0;
padding: 0 20px;
}
.tab-item {
padding: 16px 20px;
cursor: pointer;
position: relative;
&.active {
.tab-text {
color: #1890ff;
}
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background: #1890ff;
}
}
}
.tab-text {
font-size: 14px;
color: #666;
}
.config-content {
padding: 30px 20px;
}
.form-body {
max-width: 800px;
}
.form-item {
margin-bottom: 25px;
&.row {
display: flex;
flex-direction: row;
align-items: flex-start;
}
}
.label {
width: 140px;
text-align: right;
font-size: 14px;
color: #333;
padding-top: 8px;
margin-right: 15px;
}
.form-content {
flex: 1;
}
.form-input {
width: 100%;
max-width: 460px;
height: 34px;
border: 1px solid #dcdee2;
border-radius: 4px;
padding: 0 12px;
font-size: 14px;
&.readonly {
background-color: #f3f3f3;
}
}
.tip {
display: block;
font-size: 12px;
color: #999;
margin-top: 8px;
&.line-height-tip {
line-height: 1.6;
max-width: 460px;
}
}
.radio-group, .checkbox-group {
display: flex;
flex-direction: row;
align-items: center;
height: 34px;
}
.radio-item, .checkbox-item {
display: flex;
flex-direction: row;
align-items: center;
margin-right: 25px;
cursor: pointer;
}
.radio-circle {
width: 14px;
height: 14px;
border: 1px solid #dcdee2;
border-radius: 50%;
margin-right: 6px;
position: relative;
&.checked {
border-color: #1890ff;
&::after {
content: '';
width: 8px;
height: 8px;
background: #1890ff;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.checkbox-box {
width: 14px;
height: 14px;
border: 1px solid #dcdee2;
border-radius: 2px;
margin-right: 6px;
display: flex;
align-items: center;
justify-content: center;
&.checked {
background-color: #1890ff;
border-color: #1890ff;
}
}
.check-ic {
color: #fff;
font-size: 10px;
}
.radio-text, .checkbox-text {
font-size: 14px;
color: #333;
}
.form-btns {
margin-top: 40px;
padding-left: 155px;
}
.btn.primary {
width: 64px;
height: 32px;
line-height: 32px;
background: #1890ff;
color: #fff;
font-size: 14px;
border-radius: 4px;
text-align: center;
border: none;
}
</style>