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

chore: 新增标签管理模块

上级 e89409f6
<script setup lang="ts">
import type { Label } from '../types'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
interface Props {
data?: Label
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const isUpdate = $computed(() => !!props.data?.id)
const title = $computed(() => (isUpdate ? '修改标签' : '新建标签'))
const formRef = $ref<FormInstance>()
const form = reactive({
id: '',
name: '',
type: '',
update_rule: {
type: '1',
info: { unit: undefined, week: undefined, day: undefined }
},
status: ''
})
const rules = ref<FormRules>({
name: [{ required: true, message: '请输入标签名称' }],
type: [{ required: true, message: '请选择标签类型' }]
})
const unitList = [
{ label: '天', value: 1 },
{ label: '周', value: 2 },
{ label: '月', value: 3 }
]
const weekList = [
{ label: '周一', value: 1 },
{ label: '周二', value: 2 },
{ label: '周三', value: 3 },
{ label: '周四', value: 4 },
{ label: '周五', value: 5 },
{ label: '周六', value: 6 },
{ label: '周日', value: 7 }
]
const dayList = [1, 2, 3, 4, 5, 6]
// 提交
function handleSubmit() {
formRef?.validate().then(() => (isUpdate ? handleUpdate() : handleCreate()))
}
// 新建
function handleCreate() {
ElMessage({ message: '创建成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
}
// 修改
function handleUpdate() {
ElMessage({ message: '修改成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
}
</script>
<template>
<el-dialog :title="title" :close-on-click-modal="false" width="600px" @update:modelValue="$emit('update:modelValue')">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":" label-width="100px">
<el-form-item label="标签名称" prop="name">
<el-input v-model="form.name" placeholder="请输入" />
</el-form-item>
<el-form-item label="标签类型" prop="type">
<el-select v-model="form.type" style="width: 100%"></el-select>
</el-form-item>
<el-form-item label="更新频率" prop="update_rule.type">
<el-radio-group v-model="form.update_rule.type">
<el-radio label="1">自动更新</el-radio>
<el-radio label="2">手动更新</el-radio>
</el-radio-group>
<div class="update-rule-wrap" v-if="form.update_rule.type === '1'">
<span></span>
<el-select v-model="form.update_rule.info.unit" placeholder="" style="width: 60px">
<el-option v-for="item in unitList" :label="item.label" :value="item.value"></el-option>
</el-select>
<template v-if="form.update_rule.info.unit === 1">
<span>的凌晨更新</span>
</template>
<template v-if="form.update_rule.info.unit === 2">
<span></span>
<el-select v-model="form.update_rule.info.week" placeholder="" style="width: 80px">
<el-option v-for="item in weekList" :label="item.label" :value="item.value"></el-option>
</el-select>
<span>的凌晨更新</span>
</template>
<template v-if="form.update_rule.info.unit === 3">
<span></span>
<el-select v-model="form.update_rule.info.day" placeholder="" style="width: 60px">
<el-option v-for="item in dayList" :label="item" :value="item"></el-option>
</el-select>
<span>天的凌晨更新</span>
</template>
</div>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch v-model="form.status" active-text="生效" inactive-text="失效" />
</el-form-item>
</el-form>
<template #footer>
<el-row justify="center">
<el-button plain auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
</el-row>
</template>
</el-dialog>
</template>
<style lang="scss">
.update-rule-wrap {
width: 100%;
.el-select {
margin: 0 10px;
}
}
</style>
<script setup lang="ts">
import { Delete } from '@element-plus/icons-vue'
import type { LabelType } from '../types'
import { Edit, Delete } from '@element-plus/icons-vue'
import { ElMessageBox } from 'element-plus'
const typeList = $ref([
{ name: '基础标签' },
{ name: '渠道标签' },
{ name: '基础标签' },
{ name: '基础标签' },
{ name: '基础标签' },
{ name: '基础标签' }
const LabelTypeFormDialog = defineAsyncComponent(() => import('../components/LabelTypeFormDialog.vue'))
const list = $ref<LabelType[]>([
{ id: '1', name: '基础标签', url: 'red' },
{ id: '2', name: '渠道标签', url: 'blue' }
])
let formVisible = $ref(false)
let currentRow = $ref<LabelType>()
// 新建
function handleAdd() {
currentRow = undefined
formVisible = true
}
// 修改
function handleUpdate(row: LabelType) {
currentRow = row
formVisible = true
}
// 删除
function handleRemove(row: LabelType) {
ElMessageBox.confirm('确定要删除该类型吗?', '提示').then(() => {})
}
</script>
<template>
<el-button type="primary" style="width: 100%">添加标签类型</el-button>
<el-button type="primary" style="width: 100%" @click="handleAdd">添加标签类型</el-button>
<div class="label-type-total">
<h4>全部标签</h4>
<p>127个</p>
</div>
<ul>
<li class="label-type-item" v-for="(item, index) in typeList" :key="index">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="16" height="16">
<li class="label-type-item" v-for="item in list" :key="item.id">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="16" height="16" :fill="item.url">
<g>
<path
d="M497.941 225.941L286.059 14.059A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v204.118a48 48 0 0 0 14.059 33.941l211.882 211.882c18.744 18.745 49.136 18.746 67.882 0l204.118-204.118c18.745-18.745 18.745-49.137 0-67.882zM112 160c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm513.941 133.823L421.823 497.941c-18.745 18.745-49.137 18.745-67.882 0l-.36-.36L527.64 323.522c16.999-16.999 26.36-39.6 26.36-63.64s-9.362-46.641-26.36-63.64L331.397 0h48.721a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882z"></path>
</g>
</svg>
<p>{{ item.name }}</p>
<el-icon class="label-type-item__remove"><Delete /></el-icon>
<div class="label-type-actions">
<el-icon class="label-type-item__edit" @click="handleUpdate(item)"><Edit /></el-icon>
<el-icon class="label-type-item__remove" @click="handleRemove"><Delete /></el-icon>
</div>
</li>
</ul>
<LabelTypeFormDialog v-model="formVisible" :data="currentRow" v-if="formVisible"></LabelTypeFormDialog>
</template>
<style lang="scss">
......@@ -51,14 +74,24 @@ const typeList = $ref([
flex: 1;
}
&:hover {
background-color: #efefef;
.label-type-item__remove {
display: block;
background: #efefef;
.label-type-actions {
display: flex;
}
}
}
.label-type-item__remove {
.label-type-actions {
display: none;
width: 40px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
.el-icon {
font-size: 14px;
&:hover {
color: var(--main-color);
}
}
}
</style>
<script setup lang="ts">
import type { LabelType } from '../types'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
interface Props {
data?: LabelType
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
const isUpdate = $computed(() => !!props.data?.id)
const title = $computed(() => (isUpdate ? '修改标签类型' : '新建标签类型'))
const formRef = $ref<FormInstance>()
const form = reactive({ id: '', name: '', url: '' })
const rules = ref<FormRules>({
name: [{ required: true, message: '请输入标签类型名称' }],
url: [{ required: true, message: '请选择标签类型图标' }]
})
const iconColorList = $ref([
'#FF0000',
'#FF6600',
'#FFBF00',
'#FFD700',
'#66FF00',
'#00FFFF',
'#30D5C8',
'#6495ED',
'#003399',
'#003153',
'#003366',
'#2A52BE',
'#0047AB',
'#1E90FF',
'#002FA7',
'#000080',
'#5E86C1',
'#8000FF',
'#E32636',
'#FF00FF'
])
function handleChangeIcon(color: string) {
form.url = color
}
// 提交
function handleSubmit() {
formRef?.validate().then(() => (isUpdate ? handleUpdate() : handleCreate()))
}
// 新建
function handleCreate() {
ElMessage({ message: '创建成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
}
// 修改
function handleUpdate() {
ElMessage({ message: '修改成功', type: 'success' })
emit('update')
emit('update:modelValue', false)
}
</script>
<template>
<el-dialog :title="title" :close-on-click-modal="false" width="600px" @update:modelValue="$emit('update:modelValue')">
<el-form ref="formRef" :model="form" :rules="rules" label-suffix=":" label-width="100px">
<el-form-item label="类型名称" prop="name">
<el-input v-model="form.name" placeholder="请输入" />
</el-form-item>
<el-form-item label="类型图标" prop="url">
<div class="label-type-icon-list">
<div
class="label-type-icon-item"
v-for="color in iconColorList"
:class="{ 'is-active': color === form.url }"
:key="color"
@click="handleChangeIcon(color)">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="16" height="16" :fill="color">
<g>
<path
d="M497.941 225.941L286.059 14.059A48 48 0 0 0 252.118 0H48C21.49 0 0 21.49 0 48v204.118a48 48 0 0 0 14.059 33.941l211.882 211.882c18.744 18.745 49.136 18.746 67.882 0l204.118-204.118c18.745-18.745 18.745-49.137 0-67.882zM112 160c-26.51 0-48-21.49-48-48s21.49-48 48-48 48 21.49 48 48-21.49 48-48 48zm513.941 133.823L421.823 497.941c-18.745 18.745-49.137 18.745-67.882 0l-.36-.36L527.64 323.522c16.999-16.999 26.36-39.6 26.36-63.64s-9.362-46.641-26.36-63.64L331.397 0h48.721a48 48 0 0 1 33.941 14.059l211.882 211.882c18.745 18.745 18.745 49.137 0 67.882z"></path>
</g>
</svg>
</div>
</div>
</el-form-item>
</el-form>
<template #footer>
<el-row justify="center">
<el-button plain auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
<el-button type="primary" auto-insert-space @click="handleSubmit">保存</el-button>
</el-row>
</template>
</el-dialog>
</template>
<style lang="scss">
.label-type-icon-list {
width: 100%;
display: grid;
justify-content: space-between;
grid-template-columns: repeat(5, 50px);
}
.label-type-icon-item {
width: 16px;
height: 16px;
padding: 16px;
line-height: 0;
cursor: pointer;
&:hover,
&.is-active {
border-radius: 50%;
box-shadow: rgb(0 0 0 / 40%) 0px 2px 6px 0px;
}
}
</style>
<script setup lang="ts">
import type { Label } from '../types'
import { UserFilled } from '@element-plus/icons-vue'
// import { ElMessage } from 'element-plus'
interface Props {
data: Label
}
const props = defineProps<Props>()
const emit = defineEmits<{
(e: 'update'): void
(e: 'update:modelValue', visible: boolean): void
}>()
</script>
<template>
<el-dialog
title="查看标签信息"
:close-on-click-modal="false"
width="600px"
@update:modelValue="$emit('update:modelValue')">
<el-form label-suffix=":" label-width="82px">
<el-row>
<el-col :span="12"><el-form-item label="标签名称">标签名称</el-form-item></el-col>
<el-col :span="12">
<el-form-item label="标签类型">标签类型</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12"><el-form-item label="更新频率">自动更新</el-form-item></el-col>
<el-col :span="12"><el-form-item label="状态">生效</el-form-item></el-col>
</el-row>
</el-form>
<el-card>
<div class="label-box">
<dl>
<dt>符合标签人数</dt>
<dd class="label-box__count">
<el-icon><UserFilled></UserFilled></el-icon>
<span>199人</span>
</dd>
</dl>
<dl>
<dt>最后更新时间</dt>
<dd>2022-10-12 13:24:23</dd>
</dl>
<dl>
<dt>更新状态</dt>
<dd>
<span>完成</span>
<el-button type="primary" plain size="small">立即更新</el-button>
</dd>
</dl>
</div>
</el-card>
<template #footer>
<el-row justify="center">
<el-button plain auto-insert-space @click="$emit('update:modelValue', false)">关闭</el-button>
</el-row>
</template>
</el-dialog>
</template>
<style lang="scss">
.label-box {
display: flex;
justify-content: space-between;
dt {
margin-bottom: 10px;
text-align: center;
}
dd {
display: flex;
align-items: center;
justify-content: center;
span {
padding: 0 5px;
}
}
}
.label-box__count {
font-weight: bold;
color: var(--main-color);
}
</style>
// 标签类型
export interface LabelType {
id: string
name: string
url: string
}
// 标签
export interface Label {
id: string
name: string
status: 0 | 1
update_rule: LabelUpdateRule
updated_time: string
}
// 标签更新规则
export interface LabelUpdateRule {
type: 1 | 2 | 3
info: any
}
<script setup lang="ts">
import type { Label } from '../types'
import { Plus } from '@element-plus/icons-vue'
import AppList from '@/components/base/AppList.vue'
import LabelType from '../components/LabelType.vue'
import { ElMessageBox } from 'element-plus'
const LabelFormDialog = defineAsyncComponent(() => import('../components/LabelFormDialog.vue'))
const LabelViewDialog = defineAsyncComponent(() => import('../components/LabelViewDialog.vue'))
const appList = $ref<InstanceType<typeof AppList> | null>(null)
// 列表配置
......@@ -9,27 +14,52 @@ const listOptions = computed(() => {
return {
filters: [
{ type: 'input', prop: 'name', placeholder: '请输入标签名称' },
{ type: 'select', prop: 'type', placeholder: '请选择标签类型' }
{ type: 'select', prop: 'type', placeholder: '请选择标签类型' },
{ type: 'select', prop: 'type', placeholder: '请选择标签状态' },
{ type: 'input', prop: 'name', placeholder: '更新人' }
],
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '标签ID', prop: 'id' },
{ label: '标签名称', prop: 'name' },
{ label: '标签类型', prop: 'name' },
{ label: '更新频率', prop: 'name' },
{ label: '状态', prop: 'name' },
{ label: '更新人', prop: 'name' },
{ label: '更新时间', prop: 'name' },
{ label: '操作', slots: 'table-x', width: 240 }
{ label: '标签类型', prop: 'type' },
{ label: '更新频率', prop: 'update_rule.type' },
{ label: '状态', prop: 'status' },
{ label: '更新人', prop: 'updated_operator.name' },
{ label: '更新时间', prop: 'updated_time' },
{ label: '操作', slots: 'table-x', width: 320 }
],
data: [{}, {}]
data: [{ id: 1 }, { id: 2 }]
}
})
// 刷新
function handleRefresh() {
appList?.refetch()
}
let formVisible = $ref(false)
let currentRow = $ref<Label>()
// 新建
function handleAdd() {
currentRow = undefined
formVisible = true
}
// 修改
function handleUpdate(row: Label) {
currentRow = row
formVisible = true
}
// 删除
function handleRemove(row: Label) {
ElMessageBox.confirm('确定要删除该标签吗?', '提示').then(() => {})
}
let viewVisible = $ref(false)
// 查看
function handleView(row: Label) {
currentRow = row
viewVisible = true
}
</script>
<template>
......@@ -39,18 +69,23 @@ function handleRefresh() {
<AppList v-bind="listOptions" ref="appList" class="label-right">
<template #header-buttons>
<el-space>
<el-button type="primary" :icon="Plus">新建</el-button>
<el-button type="primary" :icon="Plus" @click="handleAdd">新建</el-button>
</el-space>
</template>
<template #table-x>
<el-button type="primary" plain>查看</el-button>
<el-button type="primary" plain>编辑</el-button>
<el-button type="primary" plain>删除</el-button>
<template #table-x="{ row }">
<el-button type="primary" plain>规则</el-button>
<el-button type="primary" plain @click="handleView(row)">查看</el-button>
<el-button type="primary" plain @click="handleUpdate(row)">编辑</el-button>
<el-button type="primary" plain @click="handleRemove(row)">删除</el-button>
</template>
</AppList>
</div>
</AppCard>
<!-- 新建/修改标签 -->
<LabelFormDialog v-model="formVisible" :data="currentRow" v-if="formVisible"></LabelFormDialog>
<!-- 查看标签 -->
<LabelViewDialog v-model="viewVisible" :data="currentRow" v-if="viewVisible && currentRow"></LabelViewDialog>
</template>
<style lang="scss">
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论