提交 339f967c authored 作者: 王鹏飞's avatar 王鹏飞

feat: 新增公众号授权

上级 4ad890e2
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -6,7 +6,7 @@ export function getConnectionList(params: { created_operator?: string; type?: st ...@@ -6,7 +6,7 @@ export function getConnectionList(params: { created_operator?: string; type?: st
} }
// 创建链接 // 创建链接
export function createConnection(data: { type: string; config_attributes: string }) { export function createConnection(data: { type: string; config_attributes: any }) {
return httpRequest.post('/api/lab/v1/experiment/connection/create', data) return httpRequest.post('/api/lab/v1/experiment/connection/create', data)
} }
...@@ -16,7 +16,7 @@ export function getConnectionDetails(params: { id?: string }) { ...@@ -16,7 +16,7 @@ export function getConnectionDetails(params: { id?: string }) {
} }
// 更新链接 // 更新链接
export function updateConnection(data: { id: string; config_attributes: string }) { export function updateConnection(data: { id: string; config_attributes: any }) {
return httpRequest.post('/api/lab/v1/experiment/connection/update', data) return httpRequest.post('/api/lab/v1/experiment/connection/update', data)
} }
...@@ -39,3 +39,18 @@ export function getSurveyForm(params: { form_id: string }) { ...@@ -39,3 +39,18 @@ export function getSurveyForm(params: { form_id: string }) {
export function submitSurveyForm(data: { id: string; form_id: string; form: string }) { export function submitSurveyForm(data: { id: string; form_id: string; form: string }) {
return httpRequest.post('/api/lab/v1/experiment/connection/save-survey-form-view', data) return httpRequest.post('/api/lab/v1/experiment/connection/save-survey-form-view', data)
} }
// 获取公众号第三方授权操作地址
export function getWechatAuth(params: { connection_id: string; auth_type?: 1 | 2 | 3; redirect_uri: string }) {
return httpRequest.get('/api/lab/v1/experiment/wechat-platform/auth', { params })
}
// 同步授权方公众号信息到本地
export function asyncOfficialAccountInfo(params: { connection_id: string; appid: string }) {
return httpRequest.get('/api/lab/v1/experiment/wechat-platform/async-official-account', { params })
}
// 同步微信公众号用户到本地
export function asyncOfficialAccountUsers(params: { connection_id: string; appid: string }) {
return httpRequest.get('/api/lab/v1/experiment/wechat-platform/async-official-account', { params })
}
...@@ -27,6 +27,10 @@ const routerView = function () { ...@@ -27,6 +27,10 @@ const routerView = function () {
const edit = function () { const edit = function () {
emits('edit', props.data.id) emits('edit', props.data.id)
} }
const iconMap = {
'13': '99',
'14': '100'
}
</script> </script>
<template> <template>
...@@ -40,7 +44,7 @@ const edit = function () { ...@@ -40,7 +44,7 @@ const edit = function () {
<el-icon size="20" color="#333"><Delete /></el-icon> <el-icon size="20" color="#333"><Delete /></el-icon>
</div> </div>
<div class="connect-item__icon"> <div class="connect-item__icon">
<Icon w="40" h="40" :multicolour="true" class="svg" :name="data.type"></Icon> <Icon w="40" h="40" :multiColor="true" class="svg" :name="iconMap[data.type] || data.type"></Icon>
</div> </div>
<p> <p>
{{ data.type === '12' ? data.config_attributes[0].value : data.type_name }} {{ data.type === '12' ? data.config_attributes[0].value : data.type_name }}
......
<script setup lang="ts"> <script setup lang="ts">
import type { IconProp } from '../types' import type { PlatformItem } from '../types'
import Icon from '@/components/ConnectionIcon.vue' import Icon from '@/components/ConnectionIcon.vue'
// icon defineProps<{ platformList: PlatformItem[] }>()
const iconItems = $ref<IconProp[]>([ const modelValue = defineModel<string>({ default: '1' })
{ label: '公众号', name: '1', checkbox: true },
{ label: '钉钉', name: '2', checkbox: false },
{ label: '小鹅通', name: '3', checkbox: false },
{ label: '问卷星', name: '4', checkbox: false },
{ label: '今日头条', name: '5', checkbox: false },
{ label: '抖音', name: '6', checkbox: false },
{ label: '微博', name: '7', checkbox: false },
{ label: '小红书', name: '8', checkbox: false },
{ label: '邮箱', name: '9', checkbox: false },
{ label: '短信', name: '10', checkbox: false },
{ label: '内部消息', name: '11', checkbox: false },
{ label: '自定义', name: '12', checkbox: false },
{ label: '卷王', name: '13', checkbox: false }
])
let typeValue = ref<IconProp>({ label: '公众号', name: '1', checkbox: true }) const emit = defineEmits<{
change: [data: PlatformItem]
}>()
const handleIcon = function (data: IconProp) { function handleChange(item: PlatformItem) {
iconItems.forEach((item: IconProp) => (item.checkbox = false)) modelValue.value = item.type
data.checkbox = true emit('change', item)
typeValue.value = data
} }
const getData = function () {
return typeValue.value
}
defineExpose({ getData })
</script> </script>
<template> <template>
<div class="connect-from_icon__box"> <div class="connect-from_icon__box">
<div v-for="item in iconItems" :key="item.name" :class="item.checkbox ? 'mr20-mt20 active box' : 'mr20-mt20 box'"> <div class="box" v-for="item in platformList" :key="item.type" :class="{ active: item.type === modelValue }" @click="handleChange(item)">
<div @click="handleIcon(item)" class="connect-form_icon" :style="`background: ${item.checkbox ? '#AA1941' : ''}`"> <div class="connect-form_icon">
<Icon :multicolour="!item.checkbox" :color="item.checkbox ? '#fff' : ''" class="svg" :name="item.name"></Icon> <Icon :multiColor="item.type !== modelValue" :color="item.type === modelValue ? '#fff' : ''" class="svg" :name="item.icon || item.type"></Icon>
</div> </div>
<div class="name">{{ item.label }}</div> <div class="name">{{ item.type_name }}</div>
</div> </div>
</div> </div>
</template> </template>
<style lang="scss"> <style lang="scss">
.connect-from_icon__box { .connect-from_icon__box {
display: grid;
grid-template-columns: repeat(4, 1fr);
row-gap: 20px;
column-gap: 20px;
.box { .box {
padding: 10px 20px; padding: 10px 20px;
width: 180px;
height: 100px; height: 100px;
border: 1px dashed#ddd; border: 1px dashed#ddd;
} cursor: pointer;
padding: 10px;
display: flex;
flex-wrap: wrap;
.mr20-mt20 {
margin-right: 20px;
margin-bottom: 20px;
&.active { &.active {
.name { .name {
color: #ba143e; color: #ba143e;
} }
.connect-form_icon { .connect-form_icon {
background: #aa1941;
box-shadow: 2px 2px 10px 0px rgba(0, 0, 0, 0.2); box-shadow: 2px 2px 10px 0px rgba(0, 0, 0, 0.2);
} }
} }
......
<script setup lang="ts"> <script setup lang="ts">
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import type { PlatformItem, ConfigAttribute } from '../types'
const props = defineProps<{ data: { type: string; name: string; value?: string | Array<any> } }>() const props = defineProps<{ platform: PlatformItem }>()
const modelValue = defineModel<ConfigAttribute[]>()
// 用户需知 // 用户需知
const checked = $ref(true) const checked = ref(true)
// form // form
const formRef = $ref<FormInstance>() const formRef = ref<FormInstance>()
const formAll = ref([ const configList = computed(() => {
{ return props.platform.config_attributes || []
type: '1', })
form: [ onMounted(() => {
{ label: '链接名称', prop: 'name', value: '' }, modelValue.value = modelValue.value ? Object.assign([], configList.value, modelValue.value) : configList.value
{ label: '公众号类型', prop: 'type', value: '' },
{ label: '授权方昵称', prop: 'nikeName', value: '' }
]
},
{
type: '2',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: 'AgentId', prop: 'agentId', value: '' },
{ label: 'AppKey', prop: 'appKey', value: '' },
{ label: 'AppSecret', prop: 'appSecret', value: '' }
]
},
{
type: '3',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: 'app_id', prop: 'app_id', value: '' },
{ label: 'client_id', prop: 'client_id', value: '' },
{ label: 'secret_key', prop: 'secret_key', value: '' }
]
},
{
type: '4',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: 'AppKey', prop: 'appKey', value: '' },
{ label: 'AppSecret', prop: 'appSecret', value: '' }
]
},
{
type: '5',
form: [{ label: '链接名称', prop: 'name', value: '' }]
},
{
type: '6',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: '应用类别', prop: 'dyInput1', value: '' },
{ label: '授权域回调', prop: 'dyInput2', value: '' },
{ label: '网站应用简介', prop: 'dyInput3', value: '' },
{ label: '应用官网', prop: 'dyInput4', value: '' },
{ label: '联系人姓名', prop: 'dyInput5', value: '' }
]
},
{
type: '6',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: '应用类别', prop: 'dyInput1', value: '' },
{ label: '授权域回调', prop: 'dyInput2', value: '' },
{ label: '网站应用简介', prop: 'dyInput3', value: '' },
{ label: '应用官网', prop: 'dyInput4', value: '' },
{ label: '联系人姓名', prop: 'dyInput5', value: '' }
]
},
{
type: '7',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: 'AppKey', prop: 'appKey', value: '' },
{ label: 'AppSecret', prop: 'appSecret', value: '' }
]
},
{
type: '8',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: 'AppKey', prop: 'appKey', value: '' },
{ label: 'AppSecret', prop: 'appSecret', value: '' }
]
},
{
type: '9',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: 'client_id', prop: 'client_id', value: '' },
{ label: 'client_secret', prop: 'client_secret', value: '' },
{ label: 'token URL', prop: 'token', value: '' },
{ label: 'API URL', prop: 'apiUrl', value: '' }
]
},
{
type: '10',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: 'client_id', prop: 'client_id', value: '' },
{ label: 'SdkAppId', prop: 'sdkAppId', value: '' },
{ label: 'token URL', prop: 'token', value: '' },
{ label: 'API URL', prop: 'apiUrl', value: '' }
]
},
{
type: '11',
form: [{ label: '链接名称', prop: 'name', value: '' }]
},
{
type: '12',
form: [
{ label: '链接名称', prop: 'name', value: '' },
{ label: 'APP类型', prop: 'appType', value: '' },
{ label: 'AppId', prop: 'appId', value: '' }
]
},
{
type: '13',
form: [{ label: '名称', prop: 'name', value: '' }]
}
])
const formItem = computed(() => {
const [data] = formAll.value.filter(item => item.type === props.data.type)
let dataValue = []
try {
dataValue = Array.isArray(props.data?.value) ? props.data?.value : JSON.parse(props.data?.value || '')
} catch (error) {
console.log(error)
}
return props.data?.value ? Object.assign(data?.form, dataValue) : data?.form
}) })
defineExpose({ formItem }) function showItem(data: ConfigAttribute) {
return !!configList.value.find(item => item.prop === data.prop)
}
</script> </script>
<template> <template>
...@@ -154,11 +39,13 @@ defineExpose({ formItem }) ...@@ -154,11 +39,13 @@ defineExpose({ formItem })
<div class="content-right"> <div class="content-right">
<el-form ref="formRef" label-suffix=":" label-width="122px"> <el-form ref="formRef" label-suffix=":" label-width="122px">
<el-form-item label="链接类型"> <el-form-item label="链接类型">
<span>{{ props.data.name }}</span> <span>{{ platform.type_name }}</span>
</el-form-item> </el-form-item>
<el-form-item :label="item.label" :prop="item.prop" v-for="item in formItem" :key="item.prop"> <template v-for="item in modelValue" :key="item.prop">
<el-form-item :label="item.label" :prop="item.prop" v-if="showItem(item)">
<el-input v-model="item.value" placeholder="请输入"></el-input> <el-input v-model="item.value" placeholder="请输入"></el-input>
</el-form-item> </el-form-item>
</template>
</el-form> </el-form>
</div> </div>
</div> </div>
......
...@@ -10,3 +10,17 @@ export interface DetailsProp { ...@@ -10,3 +10,17 @@ export interface DetailsProp {
type: string type: string
type_name: string type_name: string
} }
export interface ConfigAttribute {
label: string
prop: string
value: string
}
export interface PlatformItem {
type: string
type_name: string
icon?: string
config_attributes?: ConfigAttribute[]
onBeforeNext?: (index: number, data: PlatformItem) => Promise<boolean> | boolean
}
...@@ -96,17 +96,8 @@ function handleViewEvent(item: any) { ...@@ -96,17 +96,8 @@ function handleViewEvent(item: any) {
<div class="home-right_content"> <div class="home-right_content">
<AppCard class="card" title="最近活跃用户跟踪"> <AppCard class="card" title="最近活跃用户跟踪">
<div class="content-user"> <div class="content-user">
<div <div :class="item.isActive ? 'content-user_item active' : 'content-user_item'" v-for="item in userList" :key="item.id" @click="handleUser(item)">
:class="item.isActive ? 'content-user_item active' : 'content-user_item'" <img :src="item.gender === '1' ? 'https://webapp-pub.ezijing.com/pages/assa/dml_boy.png' : 'https://webapp-pub.ezijing.com/pages/assa/dml_girl.png'" />
v-for="item in userList"
:key="item.id"
@click="handleUser(item)">
<img
:src="
item.gender === '1'
? 'https://webapp-pub.ezijing.com/pages/assa/dml_boy.png'
: 'https://webapp-pub.ezijing.com/pages/assa/dml_girl.png'
" />
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
</div> </div>
</div> </div>
...@@ -120,7 +111,7 @@ function handleViewEvent(item: any) { ...@@ -120,7 +111,7 @@ function handleViewEvent(item: any) {
</div> </div>
<!-- <Icon :name="item.connection_type" w="30" h="30"></Icon> --> <!-- <Icon :name="item.connection_type" w="30" h="30"></Icon> -->
<div class="event"> <div class="event">
<Icon class="icon" :name="item.connection_type" :multicolour="true" w="24" h="24"></Icon> <Icon class="icon" :name="item.connection_type" :multiColor="true" w="24" h="24"></Icon>
<span>"{{ item.connection_name }}"</span> <span>"{{ item.connection_name }}"</span>
<span style="cursor: pointer" @click="handleViewEvent(item)">"{{ item.event_name }}"</span> <span style="cursor: pointer" @click="handleViewEvent(item)">"{{ item.event_name }}"</span>
...@@ -131,11 +122,7 @@ function handleViewEvent(item: any) { ...@@ -131,11 +122,7 @@ function handleViewEvent(item: any) {
</div> </div>
</div> </div>
<!-- 事件详情 --> <!-- 事件详情 -->
<ViewEvent <ViewEvent v-model="viewEventVisible" :event="currentViewEvent" :user="currentUser" v-if="viewEventVisible && currentViewEvent"></ViewEvent>
v-model="viewEventVisible"
:event="currentViewEvent"
:user="currentUser"
v-if="viewEventVisible && currentViewEvent"></ViewEvent>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
......
...@@ -49,31 +49,11 @@ function handleSave() { ...@@ -49,31 +49,11 @@ function handleSave() {
<template> <template>
<el-dialog title="配置连接" width="800px" append-to-body @update:modelValue="$emit('update:modelValue')"> <el-dialog title="配置连接" width="800px" append-to-body @update:modelValue="$emit('update:modelValue')">
<div class="connection-list"> <div class="connection-list">
<div <div class="connection-item" v-for="item in connectionList" :key="item.id" :class="{ 'is-active': isActive(item) }" @click="toggleSelection(item)">
class="connection-item"
v-for="item in connectionList"
:key="item.id"
:class="{ 'is-active': isActive(item) }"
@click="toggleSelection(item)"
>
<el-checkbox @change="toggleSelection(item)" :model-value="isActive(item)" /> <el-checkbox @change="toggleSelection(item)" :model-value="isActive(item)" />
<div :class="isActive(item) ? 'connection-item__icon active' : 'connection-item__icon'"> <div :class="isActive(item) ? 'connection-item__icon active' : 'connection-item__icon'">
<ConnectionIcon <ConnectionIcon style="transform: translateY(3px)" v-if="isActive(item)" color="#fff" :name="item.type + ''" w="20" h="20" />
style="transform: translateY(3px)" <ConnectionIcon style="transform: translateY(3px)" v-else :multiColor="true" :name="item.type + ''" w="20" h="20" />
v-if="isActive(item)"
color="#fff"
:name="item.type + ''"
w="20"
h="20"
/>
<ConnectionIcon
style="transform: translateY(3px)"
v-else
:multicolour="true"
:name="item.type + ''"
w="20"
h="20"
/>
</div> </div>
<p :style="`color: ${isActive(item) && '#ba143e'}`">{{ item.name }}</p> <p :style="`color: ${isActive(item) && '#ba143e'}`">{{ item.name }}</p>
</div> </div>
......
...@@ -130,7 +130,7 @@ function handleViewEvent(item: any) { ...@@ -130,7 +130,7 @@ function handleViewEvent(item: any) {
{{ item.updated_time?.slice(item.updated_time.indexOf(' '), item.updated_time.length - 3) }} {{ item.updated_time?.slice(item.updated_time.indexOf(' '), item.updated_time.length - 3) }}
{{ getDate(item.updated_time) }} {{ getDate(item.updated_time) }}
</div> </div>
<Icon class="icon" :multicolour="true" :name="item.connection_type" w="20" h="20"></Icon> <Icon class="icon" :multiColor="true" :name="item.connection_type" w="20" h="20"></Icon>
<div class="event"> <div class="event">
<span>"{{ item.connection_name }}"</span> <span>"{{ item.connection_name }}"</span>
<span style="cursor: pointer" @click="handleViewEvent(item)">"{{ item.event_name }}"</span> <span style="cursor: pointer" @click="handleViewEvent(item)">"{{ item.event_name }}"</span>
......
...@@ -10,7 +10,7 @@ import AutoImport from 'unplugin-auto-import/vite' ...@@ -10,7 +10,7 @@ import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig(({ mode }) => ({ export default defineConfig(({ mode }) => ({
base: mode === 'prod' ? 'https://webapp-pub.ezijing.com/website/prod/saas-dml/' : '/', base: mode === 'prod' ? 'https://webapp-pub.ezijing.com/website/prod/saas-dml/' : '/',
plugins: [ plugins: [
vue({ reactivityTransform: true }), vue({ script: { defineModel: true }, reactivityTransform: true }),
AutoImport({ AutoImport({
imports: ['vue', 'vue/macros', 'vue-router', '@vueuse/core'], imports: ['vue', 'vue/macros', 'vue-router', '@vueuse/core'],
dts: true, dts: true,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论