提交 3e518ce7 authored 作者: 王鹏飞's avatar 王鹏飞

chore: 新增标签类型

上级 17f07a01
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"nanoid": "^5.0.7", "nanoid": "^5.0.7",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"vue": "^3.4.25", "vue": "^3.4.26",
"vue-echarts": "^6.6.9", "vue-echarts": "^6.6.9",
"vue-router": "^4.3.2", "vue-router": "^4.3.2",
"xss": "^1.0.15" "xss": "^1.0.15"
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
"@tsconfig/node20": "^20.1.4", "@tsconfig/node20": "^20.1.4",
"@types/blueimp-md5": "^2.18.2", "@types/blueimp-md5": "^2.18.2",
"@types/node": "^20.3.1", "@types/node": "^20.3.1",
"@vitejs/plugin-vue": "^4.6.2", "@vitejs/plugin-vue": "^5.0.4",
"@vue-macros/reactivity-transform": "^0.4.4", "@vue-macros/reactivity-transform": "^0.4.4",
"@vue/eslint-config-typescript": "^13.0.0", "@vue/eslint-config-typescript": "^13.0.0",
"@vue/tsconfig": "^0.5.1", "@vue/tsconfig": "^0.5.1",
...@@ -1889,15 +1889,15 @@ ...@@ -1889,15 +1889,15 @@
"dev": true "dev": true
}, },
"node_modules/@vitejs/plugin-vue": { "node_modules/@vitejs/plugin-vue": {
"version": "4.6.2", "version": "5.0.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz", "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
"integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==", "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^14.18.0 || >=16.0.0" "node": "^18.0.0 || >=20.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"vite": "^4.0.0 || ^5.0.0", "vite": "^5.0.0",
"vue": "^3.2.25" "vue": "^3.2.25"
} }
}, },
...@@ -2101,36 +2101,36 @@ ...@@ -2101,36 +2101,36 @@
} }
}, },
"node_modules/@vue/compiler-core": { "node_modules/@vue/compiler-core": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.25.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.26.tgz",
"integrity": "sha512-Y2pLLopaElgWnMNolgG8w3C5nNUVev80L7hdQ5iIKPtMJvhVpG0zhnBG/g3UajJmZdvW0fktyZTotEHD1Srhbg==", "integrity": "sha512-N9Vil6Hvw7NaiyFUFBPXrAyETIGlQ8KcFMkyk6hW1Cl6NvoqvP+Y8p1Eqvx+UdqsnrnI9+HMUEJegzia3mhXmQ==",
"dependencies": { "dependencies": {
"@babel/parser": "^7.24.4", "@babel/parser": "^7.24.4",
"@vue/shared": "3.4.25", "@vue/shared": "3.4.26",
"entities": "^4.5.0", "entities": "^4.5.0",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"source-map-js": "^1.2.0" "source-map-js": "^1.2.0"
} }
}, },
"node_modules/@vue/compiler-dom": { "node_modules/@vue/compiler-dom": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.25.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.26.tgz",
"integrity": "sha512-Ugz5DusW57+HjllAugLci19NsDK+VyjGvmbB2TXaTcSlQxwL++2PETHx/+Qv6qFwNLzSt7HKepPe4DcTE3pBWg==", "integrity": "sha512-4CWbR5vR9fMg23YqFOhr6t6WB1Fjt62d6xdFPyj8pxrYub7d+OgZaObMsoxaF9yBUHPMiPFK303v61PwAuGvZA==",
"dependencies": { "dependencies": {
"@vue/compiler-core": "3.4.25", "@vue/compiler-core": "3.4.26",
"@vue/shared": "3.4.25" "@vue/shared": "3.4.26"
} }
}, },
"node_modules/@vue/compiler-sfc": { "node_modules/@vue/compiler-sfc": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.25.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.26.tgz",
"integrity": "sha512-m7rryuqzIoQpOBZ18wKyq05IwL6qEpZxFZfRxlNYuIPDqywrXQxgUwLXIvoU72gs6cRdY6wHD0WVZIFE4OEaAQ==", "integrity": "sha512-It1dp+FAOCgluYSVYlDn5DtZBxk1NCiJJfu2mlQqa/b+k8GL6NG/3/zRbJnHdhV2VhxFghaDq5L4K+1dakW6cw==",
"dependencies": { "dependencies": {
"@babel/parser": "^7.24.4", "@babel/parser": "^7.24.4",
"@vue/compiler-core": "3.4.25", "@vue/compiler-core": "3.4.26",
"@vue/compiler-dom": "3.4.25", "@vue/compiler-dom": "3.4.26",
"@vue/compiler-ssr": "3.4.25", "@vue/compiler-ssr": "3.4.26",
"@vue/shared": "3.4.25", "@vue/shared": "3.4.26",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"magic-string": "^0.30.10", "magic-string": "^0.30.10",
"postcss": "^8.4.38", "postcss": "^8.4.38",
...@@ -2138,12 +2138,12 @@ ...@@ -2138,12 +2138,12 @@
} }
}, },
"node_modules/@vue/compiler-ssr": { "node_modules/@vue/compiler-ssr": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.25.tgz", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.26.tgz",
"integrity": "sha512-H2ohvM/Pf6LelGxDBnfbbXFPyM4NE3hrw0e/EpwuSiYu8c819wx+SVGdJ65p/sFrYDd6OnSDxN1MB2mN07hRSQ==", "integrity": "sha512-FNwLfk7LlEPRY/g+nw2VqiDKcnDTVdCfBREekF8X74cPLiWHUX6oldktf/Vx28yh4STNy7t+/yuLoMBBF7YDiQ==",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.4.25", "@vue/compiler-dom": "3.4.26",
"@vue/shared": "3.4.25" "@vue/shared": "3.4.26"
} }
}, },
"node_modules/@vue/devtools-api": { "node_modules/@vue/devtools-api": {
...@@ -2225,48 +2225,48 @@ ...@@ -2225,48 +2225,48 @@
} }
}, },
"node_modules/@vue/reactivity": { "node_modules/@vue/reactivity": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.25.tgz", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.26.tgz",
"integrity": "sha512-mKbEtKr1iTxZkAG3vm3BtKHAOhuI4zzsVcN0epDldU/THsrvfXRKzq+lZnjczZGnTdh3ojd86/WrP+u9M51pWQ==", "integrity": "sha512-E/ynEAu/pw0yotJeLdvZEsp5Olmxt+9/WqzvKff0gE67tw73gmbx6tRkiagE/eH0UCubzSlGRebCbidB1CpqZQ==",
"dependencies": { "dependencies": {
"@vue/shared": "3.4.25" "@vue/shared": "3.4.26"
} }
}, },
"node_modules/@vue/runtime-core": { "node_modules/@vue/runtime-core": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.25.tgz", "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.26.tgz",
"integrity": "sha512-3qhsTqbEh8BMH3pXf009epCI5E7bKu28fJLi9O6W+ZGt/6xgSfMuGPqa5HRbUxLoehTNp5uWvzCr60KuiRIL0Q==", "integrity": "sha512-AFJDLpZvhT4ujUgZSIL9pdNcO23qVFh7zWCsNdGQBw8ecLNxOOnPcK9wTTIYCmBJnuPHpukOwo62a2PPivihqw==",
"dependencies": { "dependencies": {
"@vue/reactivity": "3.4.25", "@vue/reactivity": "3.4.26",
"@vue/shared": "3.4.25" "@vue/shared": "3.4.26"
} }
}, },
"node_modules/@vue/runtime-dom": { "node_modules/@vue/runtime-dom": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.25.tgz", "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.26.tgz",
"integrity": "sha512-ode0sj77kuwXwSc+2Yhk8JMHZh1sZp9F/51wdBiz3KGaWltbKtdihlJFhQG4H6AY+A06zzeMLkq6qu8uDSsaoA==", "integrity": "sha512-UftYA2hUXR2UOZD/Fc3IndZuCOOJgFxJsWOxDkhfVcwLbsfh2CdXE2tG4jWxBZuDAs9J9PzRTUFt1PgydEtItw==",
"dependencies": { "dependencies": {
"@vue/runtime-core": "3.4.25", "@vue/runtime-core": "3.4.26",
"@vue/shared": "3.4.25", "@vue/shared": "3.4.26",
"csstype": "^3.1.3" "csstype": "^3.1.3"
} }
}, },
"node_modules/@vue/server-renderer": { "node_modules/@vue/server-renderer": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.25.tgz", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.26.tgz",
"integrity": "sha512-8VTwq0Zcu3K4dWV0jOwIVINESE/gha3ifYCOKEhxOj6MEl5K5y8J8clQncTcDhKF+9U765nRw4UdUEXvrGhyVQ==", "integrity": "sha512-xoGAqSjYDPGAeRWxeoYwqJFD/gw7mpgzOvSxEmjWaFO2rE6qpbD1PC172YRpvKhrihkyHJkNDADFXTfCyVGhKw==",
"dependencies": { "dependencies": {
"@vue/compiler-ssr": "3.4.25", "@vue/compiler-ssr": "3.4.26",
"@vue/shared": "3.4.25" "@vue/shared": "3.4.26"
}, },
"peerDependencies": { "peerDependencies": {
"vue": "3.4.25" "vue": "3.4.26"
} }
}, },
"node_modules/@vue/shared": { "node_modules/@vue/shared": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.25.tgz", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.26.tgz",
"integrity": "sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA==" "integrity": "sha512-Fg4zwR0GNnjzodMt3KRy2AWGMKQXByl56+4HjN87soxLNU9P5xcJkstAlIeEF3cU6UYOzmJl1tV0dVPGIljCnQ=="
}, },
"node_modules/@vue/tsconfig": { "node_modules/@vue/tsconfig": {
"version": "0.5.1", "version": "0.5.1",
...@@ -8724,15 +8724,15 @@ ...@@ -8724,15 +8724,15 @@
"peer": true "peer": true
}, },
"node_modules/vue": { "node_modules/vue": {
"version": "3.4.25", "version": "3.4.26",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.25.tgz", "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.26.tgz",
"integrity": "sha512-HWyDqoBHMgav/OKiYA2ZQg+kjfMgLt/T0vg4cbIF7JbXAjDexRf5JRg+PWAfrAkSmTd2I8aPSXtooBFWHB98cg==", "integrity": "sha512-bUIq/p+VB+0xrJubaemrfhk1/FiW9iX+pDV+62I/XJ6EkspAO9/DXEjbDFoe8pIfOZBqfk45i9BMc41ptP/uRg==",
"dependencies": { "dependencies": {
"@vue/compiler-dom": "3.4.25", "@vue/compiler-dom": "3.4.26",
"@vue/compiler-sfc": "3.4.25", "@vue/compiler-sfc": "3.4.26",
"@vue/runtime-dom": "3.4.25", "@vue/runtime-dom": "3.4.26",
"@vue/server-renderer": "3.4.25", "@vue/server-renderer": "3.4.26",
"@vue/shared": "3.4.25" "@vue/shared": "3.4.26"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": "*" "typescript": "*"
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"nanoid": "^5.0.7", "nanoid": "^5.0.7",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"vue": "^3.4.25", "vue": "^3.4.26",
"vue-echarts": "^6.6.9", "vue-echarts": "^6.6.9",
"vue-router": "^4.3.2", "vue-router": "^4.3.2",
"xss": "^1.0.15" "xss": "^1.0.15"
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
"@tsconfig/node20": "^20.1.4", "@tsconfig/node20": "^20.1.4",
"@types/blueimp-md5": "^2.18.2", "@types/blueimp-md5": "^2.18.2",
"@types/node": "^20.3.1", "@types/node": "^20.3.1",
"@vitejs/plugin-vue": "^4.6.2", "@vitejs/plugin-vue": "^5.0.4",
"@vue-macros/reactivity-transform": "^0.4.4", "@vue-macros/reactivity-transform": "^0.4.4",
"@vue/eslint-config-typescript": "^13.0.0", "@vue/eslint-config-typescript": "^13.0.0",
"@vue/tsconfig": "^0.5.1", "@vue/tsconfig": "^0.5.1",
......
<script setup lang="ts">
import EventRule from './EventRule.vue'
import UserRule from './UserRule.vue'
import UserActionRule from './UserActionRule.vue'
const form = defineModel<any>()
onMounted(() => {
form.value = Object.assign(
{
user_attr_rule: { current_logic_operate: 'and', items: [] },
event_attr_rule: { current_logic_operate: 'and', items: [] },
user_action_rule: { current_logic_operate: 'and', items: [] }
},
form.value
)
})
</script>
<template>
<UserRule v-model="form.user_attr_rule" style="margin-top: 20px"></UserRule>
<EventRule v-model="form.event_attr_rule" style="margin-top: 20px"></EventRule>
<UserActionRule v-model="form.user_action_rule" style="margin-top: 20px"></UserActionRule>
</template>
<style src="@/assets/styles/rule.scss"></style>
...@@ -322,7 +322,7 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) { ...@@ -322,7 +322,7 @@ function remoteMethod(rule: EventRuleItem, attr: RuleAttr, search: string) {
</div> </div>
</div> </div>
<el-button text :icon="Plus" @click="handleAdd(eventAttrRule.items)" v-if="eventAttrRule.items.length < limit" <el-button text :icon="Plus" @click="handleAdd(eventAttrRule.items)" v-if="eventAttrRule.items.length < limit"
>添加</el-button >添加</el-button
> >
<slot name="footer"></slot> <slot name="footer"></slot>
</el-card> </el-card>
......
...@@ -44,7 +44,7 @@ const handleInputConfirm = () => { ...@@ -44,7 +44,7 @@ const handleInputConfirm = () => {
<template> <template>
<p class="rule-tips"> <p class="rule-tips">
<el-icon><Warning /></el-icon> <el-icon><Warning /></el-icon>
自定义分层标签:将满足不同分层规则的用户打上分层标签,同一用户会被优先匹配在顺序靠前的分层 分层标签:将满足不同分层规则的用户打上分层标签,同一用户会被优先匹配在顺序靠前的分层
</p> </p>
<div> <div>
<el-tag <el-tag
......
<script setup lang="ts">
import type { RuleAttr } from '@/types'
import { UserFilled } from '@element-plus/icons-vue'
import { useUserAttr } from '@/composables/useAllData'
import { stringOperatorList, numberOperatorList, dateOperatorList } from '@/utils/dictionary'
import { searchMetaMemberAttrs } from '@/api/base'
const form = defineModel<any>()
onMounted(() => {
form.value = Object.assign({ attr_id: '', attr: '', attr_name: '', attr_type: '', operate: '', operate_name: '', value: '' }, form.value)
})
const { userAttrList } = useUserAttr()
// 获取运算符列表
function getOperatorList(type: string) {
if (type === '1') return stringOperatorList
if (type === '2' || type === '3') return numberOperatorList
if (type === '4' || type === '5') return dateOperatorList
return stringOperatorList
}
// 属性改变
function handleAttrChange(value: string, item: RuleAttr) {
const found = userAttrList.value.find(item => item.id === value)
item.attr = found?.english_name || ''
item.attr_name = found?.name || ''
item.attr_type = found?.type || ''
// 清空条件数据
item.operate = ''
item.operate_name = ''
item.value = ''
remoteMethod(item)
}
// 条件改变
function handleOperateChange(value: string, item: RuleAttr) {
const found = getOperatorList(item.attr_type).find(item => item.value === value)
item.operate_name = found?.label || ''
item.value = ''
// 区间
if (value === 'range') {
item.value = { start: undefined, end: undefined }
}
}
function querySearch(item: RuleAttr, search: string, cb: (arg: any) => void) {
if (item.attr_id) {
searchMetaMemberAttrs({ search, member_meta_id: item.attr_id, per_page: 100 }).then(res => {
cb(res.data.list)
})
} else {
cb([])
}
}
const options = ref<{ label: string; value: string }[]>([])
const loading = ref(false)
function remoteMethod(item: RuleAttr, search: string = '') {
options.value = []
if (item.attr_id) {
loading.value = true
searchMetaMemberAttrs({ search, member_meta_id: item.attr_id, per_page: 100 }).then(res => {
options.value = res.data.list.map((item: any) => {
return { label: item.attr_value, value: item.attr_value }
})
})
loading.value = false
}
}
</script>
<template>
<el-card shadow="never">
<template #header>
<el-button circle color="#006df1" :icon="UserFilled"></el-button>
用户属性满足以下条件
</template>
<div class="rule">
<div class="rule-list">
<el-row class="rule-item">
<el-form-item>
<el-select v-model="form.attr_id" @change="value => handleAttrChange(value, form)">
<el-option v-for="option in userAttrList" :key="option.id" :label="option.name" :value="option.id"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="form.operate" @change="value => handleOperateChange(value, form)">
<el-option
v-for="option in getOperatorList(form.attr_type)"
:key="option.value"
:label="option.alias || option.label"
:value="option.value"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="!['null', 'not null'].includes(form.operate)">
<!-- 数字区间 -->
<template v-if="['2', '3'].includes(form.attr_type) && form.operate === 'range'">
<el-input-number step-strictly :controls="false" :min="0" v-model="form.value.start" />
<el-input-number step-strictly :controls="false" :min="0" v-model="form.value.end" />
</template>
<!-- 日期区间 -->
<template v-else-if="form.attr_type === '4' && form.operate === 'range'">
<el-date-picker v-model="form.value.start" type="date" value-format="YYYY-MM-DD" />
<el-date-picker v-model="form.value.end" type="date" value-format="YYYY-MM-DD" />
</template>
<!-- 时间区间 -->
<template v-else-if="form.attr_type === '5' && form.operate === 'range'">
<el-date-picker v-model="form.value.start" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
<el-date-picker v-model="form.value.end" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
</template>
<template v-else-if="form.attr_type === '4' && (form.operate === 'after' || form.operate === 'before')">
<el-date-picker v-model="form.value" type="date" value-format="YYYY-MM-DD" />
</template>
<template v-else-if="form.attr_type === '5' && (form.operate === 'after' || form.operate === 'before')">
<el-date-picker v-model="form.value" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 180px" />
</template>
<template v-else>
<el-select
v-model="form.value"
filterable
remote
allow-create
:multiple="['in', 'not in'].includes(form.operate)"
:remote-method="(query:string) => remoteMethod(form, query)"
:loading="loading"
style="width: 320px"
v-if="['in', 'not in'].includes(form.operate)">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-autocomplete
v-model="form.value"
value-key="attr_value"
:fetch-suggestions="(query, cb) => querySearch(form, query, cb)"
style="width: 320px"
v-else />
</template>
</el-form-item>
</el-row>
</div>
</div>
</el-card>
</template>
<style src="@/assets/styles/rule.scss"></style>
...@@ -248,7 +248,7 @@ function remoteMethod(event: RuleEvent, attr: RuleAttr, search: string) { ...@@ -248,7 +248,7 @@ function remoteMethod(event: RuleEvent, attr: RuleAttr, search: string) {
</section> </section>
</div> </div>
</div> </div>
<el-button text :icon="Plus" @click="handleAdd(userActionRule.items)">添加条件</el-button> <el-button text :icon="Plus" @click="handleAdd(userActionRule.items)">添加用户行为</el-button>
</el-card> </el-card>
</template> </template>
......
...@@ -163,7 +163,7 @@ function remoteMethod(item: RuleAttr, search: string = '') { ...@@ -163,7 +163,7 @@ function remoteMethod(item: RuleAttr, search: string = '') {
</el-row> </el-row>
</div> </div>
</div> </div>
<el-button text :icon="Plus" @click="handleAdd(userAttrRule.items)">添加条件</el-button> <el-button text :icon="Plus" @click="handleAdd(userAttrRule.items)">添加属性</el-button>
</el-card> </el-card>
</template> </template>
......
...@@ -3,7 +3,7 @@ import type { LabelTypeListRequest, LabelTypeCreateRequest, LabelTypeUpdateReque ...@@ -3,7 +3,7 @@ import type { LabelTypeListRequest, LabelTypeCreateRequest, LabelTypeUpdateReque
// 获取标签类型列表 // 获取标签类型列表
export function getLabelTypeList(params?: LabelTypeListRequest) { export function getLabelTypeList(params?: LabelTypeListRequest) {
return httpRequest.get('/api/lab/v1/experiment/tag-type/list', { params }) return httpRequest.get('/api/lab/v1/experiment/tag-type/bda-list', { params })
} }
// 创建标签类型 // 创建标签类型
......
...@@ -10,6 +10,9 @@ import LevelRule from '@/components/rule/LevelRule.vue' ...@@ -10,6 +10,9 @@ import LevelRule from '@/components/rule/LevelRule.vue'
import EventPreferenceRule from '@/components/rule/EventPreferenceRule.vue' import EventPreferenceRule from '@/components/rule/EventPreferenceRule.vue'
import EventTargetRule from '@/components/rule/EventTargetRule.vue' import EventTargetRule from '@/components/rule/EventTargetRule.vue'
import RFMRule from '@/components/rule/RFMRule.vue' import RFMRule from '@/components/rule/RFMRule.vue'
import CustomRule from '@/components/rule/CustomRule.vue'
import SingleUserRule from '@/components/rule/SingleUserRule.vue'
import UserRule from '@/components/rule/UserRule.vue'
const props = defineProps<{ const props = defineProps<{
data: Label data: Label
...@@ -36,16 +39,7 @@ const form = reactive({ ...@@ -36,16 +39,7 @@ const form = reactive({
function fetchInfo() { function fetchInfo() {
getLabelRule({ id: props.data.id }).then(res => { getLabelRule({ id: props.data.id }).then(res => {
const { detail } = res.data const { detail } = res.data
// const [user_attr_rule = { current_logic_operate: 'and', items: [] }] = detail.user_attr_rule
// const [event_attr_rule = { current_logic_operate: 'and', items: [] }] = detail.event_attr_rule
// const attrRuleItems = user_attr_rule.items.map((item: any) => {
// item.value = ['in', 'not in'].includes(item.operate) ? item.value.split(',') : item.value
// return item
// })
// const eventRuleItems = event_attr_rule.items.map((item: any) => {
// item.value = ['in', 'not in'].includes(item.operate) ? item.value.split(',') : item.value
// return item
// })
let rules = detail.rules let rules = detail.rules
if (detail.rules.length === 0) { if (detail.rules.length === 0) {
if (detail.label == '2') { if (detail.label == '2') {
...@@ -71,6 +65,19 @@ function fetchInfo() { ...@@ -71,6 +65,19 @@ function fetchInfo() {
if (detail.label === '4') { if (detail.label === '4') {
rules = { R: {}, F: {}, M: {} } rules = { R: {}, F: {}, M: {} }
} }
if (detail.label === '5') {
rules = { attr_id: '', attr: '', attr_name: '', attr_type: '', operate: '', operate_name: '', value: '' }
}
if (detail.label === '6') {
rules = { current_logic_operate: 'and', items: [] }
}
if (detail.label === '7') {
rules = {
user_attr_rule: { current_logic_operate: 'and', items: [] },
event_attr_rule: { current_logic_operate: 'and', items: [] },
user_action_rule: { current_logic_operate: 'and', items: [] }
}
}
} }
Object.assign(form, { id: props.data.id, rules }) Object.assign(form, { id: props.data.id, rules })
}) })
...@@ -132,7 +139,7 @@ function handleUpdate() { ...@@ -132,7 +139,7 @@ function handleUpdate() {
</el-row> </el-row>
</el-form> </el-form>
<el-form :model="form" inline ref="formRef" :disabled="disabled" @submit.prevent v-if="form.id"> <el-form :model="form" inline ref="formRef" :disabled="disabled" @submit.prevent v-if="form.id">
<!-- 自定义分层 --> <!-- 分层 -->
<LevelRule v-model="form.rules" v-if="data.label == '1'"></LevelRule> <LevelRule v-model="form.rules" v-if="data.label == '1'"></LevelRule>
<!-- 事件偏好 --> <!-- 事件偏好 -->
<EventPreferenceRule v-model="form.rules" v-if="data.label == '2'"></EventPreferenceRule> <EventPreferenceRule v-model="form.rules" v-if="data.label == '2'"></EventPreferenceRule>
...@@ -140,8 +147,12 @@ function handleUpdate() { ...@@ -140,8 +147,12 @@ function handleUpdate() {
<EventTargetRule v-model="form.rules" v-if="data.label == '3'"></EventTargetRule> <EventTargetRule v-model="form.rules" v-if="data.label == '3'"></EventTargetRule>
<!-- RFM模型 --> <!-- RFM模型 -->
<RFMRule v-model="form.rules" v-if="data.label == '4'"></RFMRule> <RFMRule v-model="form.rules" v-if="data.label == '4'"></RFMRule>
<!-- 用户属性规则 --> <!-- 自定义 -->
<!-- <UserRule></UserRule> --> <CustomRule v-model="form.rules" v-if="data.label == '7'"></CustomRule>
<!-- 单属性 -->
<SingleUserRule v-model="form.rules" v-if="data.label == '5'"></SingleUserRule>
<!-- 多属性规则 -->
<UserRule v-model="form.rules" v-if="data.label == '6'"></UserRule>
<!-- 事件属性规则 --> <!-- 事件属性规则 -->
<!-- <EventRule style="margin-top: 20px"></EventRule> --> <!-- <EventRule style="margin-top: 20px"></EventRule> -->
</el-form> </el-form>
......
...@@ -59,7 +59,7 @@ function handleRemove(row: LabelType) { ...@@ -59,7 +59,7 @@ function handleRemove(row: LabelType) {
</g> </g>
</svg> </svg>
<p>{{ item.name }}</p> <p>{{ item.name }}</p>
<div class="label-type-actions"> <div class="label-type-actions" v-if="!item.is_default">
<el-icon class="label-type-item__edit" @click.stop="handleUpdate(item)" v-permission="'experiment_tag_type_update'"><Edit /></el-icon> <el-icon class="label-type-item__edit" @click.stop="handleUpdate(item)" v-permission="'experiment_tag_type_update'"><Edit /></el-icon>
<el-icon class="label-type-item__remove" @click.stop="handleRemove(item)" v-permission="'experiment_tag_type_delete'"><Delete /></el-icon> <el-icon class="label-type-item__remove" @click.stop="handleRemove(item)" v-permission="'experiment_tag_type_delete'"><Delete /></el-icon>
</div> </div>
......
...@@ -7,7 +7,11 @@ export function useLabelType() { ...@@ -7,7 +7,11 @@ export function useLabelType() {
function fetchTypeList() { function fetchTypeList() {
getLabelTypeList().then(res => { getLabelTypeList().then(res => {
labelCount.value = res.data.tag_count labelCount.value = res.data.tag_count
typeList.value = res.data.items let defaultItems = res.data.default_items || []
defaultItems = defaultItems.map((item: LabelType) => {
return { ...item, is_default: true }
})
typeList.value = [...defaultItems, ...res.data.items]
}) })
} }
onMounted(() => { onMounted(() => {
......
...@@ -5,6 +5,7 @@ export interface LabelType { ...@@ -5,6 +5,7 @@ export interface LabelType {
id: string id: string
name: string name: string
url: string url: string
is_default?: boolean
} }
export type LabelTypeListRequest = Pick<LabelType, 'id' | 'name'> & { experiment_id?: string } export type LabelTypeListRequest = Pick<LabelType, 'id' | 'name'> & { experiment_id?: string }
......
...@@ -96,9 +96,12 @@ export const happenInfoList = [ ...@@ -96,9 +96,12 @@ export const happenInfoList = [
export const triggerInfoList = [{ label: '触发次数', value: '触发次数' }] export const triggerInfoList = [{ label: '触发次数', value: '触发次数' }]
export const labelList = [ export const labelList = [
{ label: '自定义分层标签 ', value: '1' }, { label: '单属性标签', value: '5' },
{ label: '多属性标签', value: '6' },
{ label: '事件偏好标签 ', value: '2' }, { label: '事件偏好标签 ', value: '2' },
{ label: '事件指标标签 ', value: '3' }, { label: '事件指标标签 ', value: '3' },
{ label: '自定义标签', value: '7' },
{ label: '分层标签 ', value: '1' },
{ label: 'RFM模型标签 ', value: '4' } { label: 'RFM模型标签 ', value: '4' }
] ]
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论