Merge branch 'master' of https://gitee.com/yudaocode/yudao-ui-admin-vue3
commit
d9ed3d1a6b
@ -0,0 +1,57 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
export interface BusinessVO {
|
||||
id: number
|
||||
name: string
|
||||
statusTypeId: number
|
||||
statusId: number
|
||||
contactNextTime: Date
|
||||
customerId: number
|
||||
dealTime: Date
|
||||
price: number
|
||||
discountPercent: number
|
||||
productPrice: number
|
||||
remark: string
|
||||
ownerUserId: number
|
||||
roUserIds: string
|
||||
rwUserIds: string
|
||||
endStatus: number
|
||||
endRemark: string
|
||||
contactLastTime: Date
|
||||
followUpStatus: number
|
||||
}
|
||||
|
||||
// 查询 CRM 商机列表
|
||||
export const getBusinessPage = async (params) => {
|
||||
return await request.get({ url: `/crm/business/page`, params })
|
||||
}
|
||||
|
||||
// 查询 CRM 商机列表,基于指定客户
|
||||
export const getBusinessPageByCustomer = async (params) => {
|
||||
return await request.get({ url: `/crm/business/page-by-customer`, params })
|
||||
}
|
||||
|
||||
// 查询 CRM 商机详情
|
||||
export const getBusiness = async (id: number) => {
|
||||
return await request.get({ url: `/crm/business/get?id=` + id })
|
||||
}
|
||||
|
||||
// 新增 CRM 商机
|
||||
export const createBusiness = async (data: BusinessVO) => {
|
||||
return await request.post({ url: `/crm/business/create`, data })
|
||||
}
|
||||
|
||||
// 修改 CRM 商机
|
||||
export const updateBusiness = async (data: BusinessVO) => {
|
||||
return await request.put({ url: `/crm/business/update`, data })
|
||||
}
|
||||
|
||||
// 删除 CRM 商机
|
||||
export const deleteBusiness = async (id: number) => {
|
||||
return await request.delete({ url: `/crm/business/delete?id=` + id })
|
||||
}
|
||||
|
||||
// 导出 CRM 商机 Excel
|
||||
export const exportBusiness = async (params) => {
|
||||
return await request.download({ url: `/crm/business/export-excel`, params })
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
export interface BusinessStatusTypeVO {
|
||||
id: number
|
||||
name: string
|
||||
deptIds: number[]
|
||||
status: boolean
|
||||
}
|
||||
|
||||
// 查询商机状态类型列表
|
||||
export const getBusinessStatusTypePage = async (params) => {
|
||||
return await request.get({ url: `/crm/business-status-type/page`, params })
|
||||
}
|
||||
|
||||
// 查询商机状态类型详情
|
||||
export const getBusinessStatusType = async (id: number) => {
|
||||
return await request.get({ url: `/crm/business-status-type/get?id=` + id })
|
||||
}
|
||||
|
||||
// 新增商机状态类型
|
||||
export const createBusinessStatusType = async (data: BusinessStatusTypeVO) => {
|
||||
return await request.post({ url: `/crm/business-status-type/create`, data })
|
||||
}
|
||||
|
||||
// 修改商机状态类型
|
||||
export const updateBusinessStatusType = async (data: BusinessStatusTypeVO) => {
|
||||
return await request.put({ url: `/crm/business-status-type/update`, data })
|
||||
}
|
||||
|
||||
// 删除商机状态类型
|
||||
export const deleteBusinessStatusType = async (id: number) => {
|
||||
return await request.delete({ url: `/crm/business-status-type/delete?id=` + id })
|
||||
}
|
||||
|
||||
// 导出商机状态类型 Excel
|
||||
export const exportBusinessStatusType = async (params) => {
|
||||
return await request.download({ url: `/crm/business-status-type/export-excel`, params })
|
||||
}
|
||||
|
||||
// 获取商机状态类型信息列表
|
||||
export const getBusinessStatusTypeList = async () => {
|
||||
return await request.get({ url: `/crm/business-status-type/get-simple-list` })
|
||||
}
|
||||
|
||||
// 根据类型ID获取商机状态信息列表
|
||||
export const getBusinessStatusListByTypeId = async (typeId: number) => {
|
||||
return await request.get({ url: `/crm/business-status-type/get-status-list?typeId=` + typeId })
|
||||
}
|
||||
@ -0,0 +1,246 @@
|
||||
// APP 链接类型(需要特殊处理,例如商品详情)
|
||||
export const enum APP_LINK_TYPE_ENUM {
|
||||
// 拼团活动
|
||||
ACTIVITY_COMBINATION,
|
||||
// 秒杀活动
|
||||
ACTIVITY_SECKILL,
|
||||
// 文章详情
|
||||
ARTICLE_DETAIL,
|
||||
// 优惠券详情
|
||||
COUPON_DETAIL,
|
||||
// 自定义页面详情
|
||||
DIY_PAGE_DETAIL,
|
||||
// 品类列表
|
||||
PRODUCT_CATEGORY_LIST,
|
||||
// 商品列表
|
||||
PRODUCT_LIST,
|
||||
// 商品详情
|
||||
PRODUCT_DETAIL_NORMAL,
|
||||
// 拼团商品详情
|
||||
PRODUCT_DETAIL_COMBINATION,
|
||||
// 积分商品详情
|
||||
PRODUCT_DETAIL_POINT,
|
||||
// 秒杀商品详情
|
||||
PRODUCT_DETAIL_SECKILL
|
||||
}
|
||||
|
||||
// APP 链接列表(做一下持久化?)
|
||||
export const APP_LINK_GROUP_LIST = [
|
||||
{
|
||||
name: '商城',
|
||||
links: [
|
||||
{
|
||||
name: '首页',
|
||||
path: '/pages/index/index'
|
||||
},
|
||||
{
|
||||
name: '商品分类',
|
||||
path: '/pages/index/category',
|
||||
type: APP_LINK_TYPE_ENUM.PRODUCT_CATEGORY_LIST
|
||||
},
|
||||
{
|
||||
name: '购物车',
|
||||
path: '/pages/index/cart'
|
||||
},
|
||||
{
|
||||
name: '个人中心',
|
||||
path: '/pages/index/user'
|
||||
},
|
||||
{
|
||||
name: '商品搜索',
|
||||
path: '/pages/index/search'
|
||||
},
|
||||
{
|
||||
name: '自定义页面',
|
||||
path: '/pages/index/page',
|
||||
type: APP_LINK_TYPE_ENUM.DIY_PAGE_DETAIL
|
||||
},
|
||||
{
|
||||
name: '客服',
|
||||
path: '/pages/chat/index'
|
||||
},
|
||||
{
|
||||
name: '系统设置',
|
||||
path: '/pages/public/setting'
|
||||
},
|
||||
{
|
||||
name: '问题反馈',
|
||||
path: '/pages/public/feedback'
|
||||
},
|
||||
{
|
||||
name: '常见问题',
|
||||
path: '/pages/public/faq'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '商品',
|
||||
links: [
|
||||
{
|
||||
name: '商品列表',
|
||||
path: '/pages/goods/list',
|
||||
type: APP_LINK_TYPE_ENUM.PRODUCT_LIST
|
||||
},
|
||||
{
|
||||
name: '商品详情',
|
||||
path: '/pages/goods/index',
|
||||
type: APP_LINK_TYPE_ENUM.PRODUCT_DETAIL_NORMAL
|
||||
},
|
||||
{
|
||||
name: '拼团商品详情',
|
||||
path: '/pages/goods/groupon',
|
||||
type: APP_LINK_TYPE_ENUM.PRODUCT_DETAIL_COMBINATION
|
||||
},
|
||||
{
|
||||
name: '秒杀商品详情',
|
||||
path: '/pages/goods/seckill',
|
||||
type: APP_LINK_TYPE_ENUM.PRODUCT_DETAIL_SECKILL
|
||||
},
|
||||
{
|
||||
name: '积分商品详情',
|
||||
path: '/pages/goods/score',
|
||||
type: APP_LINK_TYPE_ENUM.PRODUCT_DETAIL_POINT
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '营销活动',
|
||||
links: [
|
||||
{
|
||||
name: '拼团订单',
|
||||
path: '/pages/activity/groupon/order'
|
||||
},
|
||||
{
|
||||
name: '营销商品',
|
||||
path: '/pages/activity/index'
|
||||
},
|
||||
{
|
||||
name: '拼团活动',
|
||||
path: '/pages/activity/groupon/list',
|
||||
type: APP_LINK_TYPE_ENUM.ACTIVITY_COMBINATION
|
||||
},
|
||||
{
|
||||
name: '秒杀活动',
|
||||
path: '/pages/activity/seckill/list',
|
||||
type: APP_LINK_TYPE_ENUM.ACTIVITY_SECKILL
|
||||
},
|
||||
{
|
||||
name: '签到中心',
|
||||
path: '/pages/app/sign'
|
||||
},
|
||||
{
|
||||
name: '积分商城',
|
||||
path: '/pages/app/score-shop'
|
||||
},
|
||||
{
|
||||
name: '优惠券中心',
|
||||
path: '/pages/coupon/list'
|
||||
},
|
||||
{
|
||||
name: '优惠券详情',
|
||||
path: '/pages/coupon/detail',
|
||||
type: APP_LINK_TYPE_ENUM.COUPON_DETAIL
|
||||
},
|
||||
{
|
||||
name: '文章详情',
|
||||
path: '/pages/public/richtext',
|
||||
type: APP_LINK_TYPE_ENUM.ARTICLE_DETAIL
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '分销商城',
|
||||
links: [
|
||||
{
|
||||
name: '分销中心',
|
||||
path: '/pages/commission/index'
|
||||
},
|
||||
{
|
||||
name: '申请分销商',
|
||||
path: '/pages/commission/apply'
|
||||
},
|
||||
{
|
||||
name: '推广商品',
|
||||
path: '/pages/commission/goods'
|
||||
},
|
||||
{
|
||||
name: '分销订单',
|
||||
path: '/pages/commission/order'
|
||||
},
|
||||
{
|
||||
name: '分享记录',
|
||||
path: '/pages/commission/share-log'
|
||||
},
|
||||
{
|
||||
name: '我的团队',
|
||||
path: '/pages/commission/team'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '支付',
|
||||
links: [
|
||||
{
|
||||
name: '充值余额',
|
||||
path: '/pages/pay/recharge'
|
||||
},
|
||||
{
|
||||
name: '充值记录',
|
||||
path: '/pages/pay/recharge-log'
|
||||
},
|
||||
{
|
||||
name: '申请提现',
|
||||
path: '/pages/pay/withdraw'
|
||||
},
|
||||
{
|
||||
name: '提现记录',
|
||||
path: '/pages/pay/withdraw-log'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '用户中心',
|
||||
links: [
|
||||
{
|
||||
name: '用户信息',
|
||||
path: '/pages/user/info'
|
||||
},
|
||||
{
|
||||
name: '用户订单',
|
||||
path: '/pages/order/list'
|
||||
},
|
||||
{
|
||||
name: '售后订单',
|
||||
path: '/pages/order/aftersale/list'
|
||||
},
|
||||
{
|
||||
name: '商品收藏',
|
||||
path: '/pages/user/goods-collect'
|
||||
},
|
||||
{
|
||||
name: '浏览记录',
|
||||
path: '/pages/user/goods-log'
|
||||
},
|
||||
{
|
||||
name: '地址管理',
|
||||
path: '/pages/user/address/list'
|
||||
},
|
||||
{
|
||||
name: '发票管理',
|
||||
path: '/pages/user/invoice/list'
|
||||
},
|
||||
{
|
||||
name: '用户佣金',
|
||||
path: '/pages/user/wallet/commission'
|
||||
},
|
||||
{
|
||||
name: '用户余额',
|
||||
path: '/pages/user/wallet/money'
|
||||
},
|
||||
{
|
||||
name: '用户积分',
|
||||
path: '/pages/user/wallet/score'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<el-input v-model="appLink" placeholder="输入或选择链接">
|
||||
<template #append>
|
||||
<el-button @click="handleOpenDialog">选择</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<AppLinkSelectDialog ref="dialogRef" @change="handleLinkSelected" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
|
||||
// APP 链接输入框
|
||||
defineOptions({ name: 'AppLinkInput' })
|
||||
// 定义属性
|
||||
const props = defineProps({
|
||||
// 当前选中的链接
|
||||
modelValue: propTypes.string.def('')
|
||||
})
|
||||
// 当前的链接
|
||||
const appLink = ref('')
|
||||
// 选择对话框
|
||||
const dialogRef = ref()
|
||||
// 处理打开对话框
|
||||
const handleOpenDialog = () => dialogRef.value?.open(appLink.value)
|
||||
// 处理 APP 链接选中
|
||||
const handleLinkSelected = (link: string) => (appLink.value = link)
|
||||
|
||||
// getter
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
() => (appLink.value = props.modelValue),
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
// setter
|
||||
const emit = defineEmits<{
|
||||
'update:modelValue': [link: string]
|
||||
}>()
|
||||
watch(
|
||||
() => appLink,
|
||||
() => emit('update:modelValue', appLink.value)
|
||||
)
|
||||
</script>
|
||||
@ -0,0 +1,25 @@
|
||||
import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
||||
|
||||
/** 营销文章属性 */
|
||||
export interface PromotionArticleProperty {
|
||||
// 文章编号
|
||||
id: number
|
||||
// 组件样式
|
||||
style: ComponentStyle
|
||||
}
|
||||
|
||||
// 定义组件
|
||||
export const component = {
|
||||
id: 'PromotionArticle',
|
||||
name: '营销文章',
|
||||
icon: 'ph:article-medium',
|
||||
property: {
|
||||
style: {
|
||||
bgType: 'color',
|
||||
bgColor: '',
|
||||
marginLeft: 8,
|
||||
marginRight: 8,
|
||||
marginBottom: 8
|
||||
} as ComponentStyle
|
||||
}
|
||||
} as DiyComponent<PromotionArticleProperty>
|
||||
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div class="min-h-30px" v-html="article.content"></div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { PromotionArticleProperty } from './config'
|
||||
import * as ArticleApi from '@/api/mall/promotion/article/index'
|
||||
|
||||
/** 营销文章 */
|
||||
defineOptions({ name: 'PromotionArticle' })
|
||||
// 定义属性
|
||||
const props = defineProps<{ property: PromotionArticleProperty }>()
|
||||
// 商品列表
|
||||
const article = ref<ArticleApi.ArticleVO[]>({})
|
||||
watch(
|
||||
() => props.property.id,
|
||||
async () => {
|
||||
if (props.property.id) {
|
||||
article.value = await ArticleApi.getArticle(props.property.id)
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<ComponentContainerProperty v-model="formData.style">
|
||||
<el-form label-width="40px" :model="formData">
|
||||
<el-form-item label="文章" prop="id">
|
||||
<el-select
|
||||
v-model="formData.id"
|
||||
placeholder="请选择文章"
|
||||
class="w-full"
|
||||
filterable
|
||||
remote
|
||||
:remote-method="queryArticleList"
|
||||
:loading="loading"
|
||||
>
|
||||
<el-option
|
||||
v-for="article in articles"
|
||||
:key="article.id"
|
||||
:label="article.title"
|
||||
:value="article.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ComponentContainerProperty>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PromotionArticleProperty } from './config'
|
||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||
import * as ArticleApi from '@/api/mall/promotion/article/index'
|
||||
|
||||
// 营销文章属性面板
|
||||
defineOptions({ name: 'PromotionArticleProperty' })
|
||||
|
||||
const props = defineProps<{ modelValue: PromotionArticleProperty }>()
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const { formData } = usePropertyForm(props.modelValue, emit)
|
||||
// 文章列表
|
||||
const articles = ref<ArticleApi.ArticleVO>([])
|
||||
|
||||
// 加载中
|
||||
const loading = ref(false)
|
||||
// 查询文章列表
|
||||
const queryArticleList = async (title?: string) => {
|
||||
loading.value = true
|
||||
const { list } = await ArticleApi.getArticlePage({ title, pageSize: 10 })
|
||||
articles.value = list
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
queryArticleList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,64 @@
|
||||
import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
||||
|
||||
/** 拼团属性 */
|
||||
export interface PromotionCombinationProperty {
|
||||
// 布局类型:单列 | 三列
|
||||
layoutType: 'oneCol' | 'threeCol'
|
||||
// 商品字段
|
||||
fields: {
|
||||
// 商品名称
|
||||
name: PromotionCombinationFieldProperty
|
||||
// 商品价格
|
||||
price: PromotionCombinationFieldProperty
|
||||
}
|
||||
// 角标
|
||||
badge: {
|
||||
// 是否显示
|
||||
show: boolean
|
||||
// 角标图片
|
||||
imgUrl: string
|
||||
}
|
||||
// 上圆角
|
||||
borderRadiusTop: number
|
||||
// 下圆角
|
||||
borderRadiusBottom: number
|
||||
// 间距
|
||||
space: number
|
||||
// 拼团活动编号
|
||||
activityId: number
|
||||
// 组件样式
|
||||
style: ComponentStyle
|
||||
}
|
||||
// 商品字段
|
||||
export interface PromotionCombinationFieldProperty {
|
||||
// 是否显示
|
||||
show: boolean
|
||||
// 颜色
|
||||
color: string
|
||||
}
|
||||
|
||||
// 定义组件
|
||||
export const component = {
|
||||
id: 'PromotionCombination',
|
||||
name: '拼团',
|
||||
icon: 'mdi:account-group',
|
||||
property: {
|
||||
activityId: undefined,
|
||||
layoutType: 'oneCol',
|
||||
fields: {
|
||||
name: { show: true, color: '#000' },
|
||||
price: { show: true, color: '#ff3000' }
|
||||
},
|
||||
badge: { show: false, imgUrl: '' },
|
||||
borderRadiusTop: 8,
|
||||
borderRadiusBottom: 8,
|
||||
space: 8,
|
||||
style: {
|
||||
bgType: 'color',
|
||||
bgColor: '',
|
||||
marginLeft: 8,
|
||||
marginRight: 8,
|
||||
marginBottom: 8
|
||||
} as ComponentStyle
|
||||
}
|
||||
} as DiyComponent<PromotionCombinationProperty>
|
||||
@ -0,0 +1,64 @@
|
||||
import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
||||
|
||||
/** 秒杀属性 */
|
||||
export interface PromotionSeckillProperty {
|
||||
// 布局类型:单列 | 三列
|
||||
layoutType: 'oneCol' | 'threeCol'
|
||||
// 商品字段
|
||||
fields: {
|
||||
// 商品名称
|
||||
name: PromotionSeckillFieldProperty
|
||||
// 商品价格
|
||||
price: PromotionSeckillFieldProperty
|
||||
}
|
||||
// 角标
|
||||
badge: {
|
||||
// 是否显示
|
||||
show: boolean
|
||||
// 角标图片
|
||||
imgUrl: string
|
||||
}
|
||||
// 上圆角
|
||||
borderRadiusTop: number
|
||||
// 下圆角
|
||||
borderRadiusBottom: number
|
||||
// 间距
|
||||
space: number
|
||||
// 秒杀活动编号
|
||||
activityId: number
|
||||
// 组件样式
|
||||
style: ComponentStyle
|
||||
}
|
||||
// 商品字段
|
||||
export interface PromotionSeckillFieldProperty {
|
||||
// 是否显示
|
||||
show: boolean
|
||||
// 颜色
|
||||
color: string
|
||||
}
|
||||
|
||||
// 定义组件
|
||||
export const component = {
|
||||
id: 'PromotionSeckill',
|
||||
name: '秒杀',
|
||||
icon: 'mdi:calendar-time',
|
||||
property: {
|
||||
activityId: undefined,
|
||||
layoutType: 'oneCol',
|
||||
fields: {
|
||||
name: { show: true, color: '#000' },
|
||||
price: { show: true, color: '#ff3000' }
|
||||
},
|
||||
badge: { show: false, imgUrl: '' },
|
||||
borderRadiusTop: 8,
|
||||
borderRadiusBottom: 8,
|
||||
space: 8,
|
||||
style: {
|
||||
bgType: 'color',
|
||||
bgColor: '',
|
||||
marginLeft: 8,
|
||||
marginRight: 8,
|
||||
marginBottom: 8
|
||||
} as ComponentStyle
|
||||
}
|
||||
} as DiyComponent<PromotionSeckillProperty>
|
||||
@ -0,0 +1,21 @@
|
||||
import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
||||
|
||||
/** 用户卡片属性 */
|
||||
export interface UserCardProperty {
|
||||
// 组件样式
|
||||
style: ComponentStyle
|
||||
}
|
||||
|
||||
// 定义组件
|
||||
export const component = {
|
||||
id: 'UserCard',
|
||||
name: '用户卡片',
|
||||
icon: 'mdi:user-card-details',
|
||||
property: {
|
||||
style: {
|
||||
bgType: 'color',
|
||||
bgColor: '',
|
||||
marginBottom: 8
|
||||
} as ComponentStyle
|
||||
}
|
||||
} as DiyComponent<UserCardProperty>
|
||||
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center justify-between p-x-18px p-y-24px">
|
||||
<div class="flex flex-1 items-center gap-16px">
|
||||
<el-avatar :size="60">
|
||||
<Icon icon="ep:avatar" :size="60" />
|
||||
</el-avatar>
|
||||
<span class="text-18px font-bold">芋道源码</span>
|
||||
</div>
|
||||
<Icon icon="tdesign:qrcode" :size="20" />
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center justify-between justify-between bg-white p-x-20px p-y-8px text-12px"
|
||||
>
|
||||
<span class="color-#ff690d">点击绑定手机号</span>
|
||||
<span class="rounded-26px bg-#ff6100 p-x-8px p-y-5px color-white">去绑定</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { UserCardProperty } from './config'
|
||||
|
||||
/** 用户卡片 */
|
||||
defineOptions({ name: 'UserCard' })
|
||||
// 定义属性
|
||||
defineProps<{ property: UserCardProperty }>()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<ComponentContainerProperty v-model="formData.style" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UserCardProperty } from './config'
|
||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||
|
||||
// 用户卡片属性面板
|
||||
defineOptions({ name: 'UserCardProperty' })
|
||||
|
||||
const props = defineProps<{ modelValue: UserCardProperty }>()
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const { formData } = usePropertyForm(props.modelValue, emit)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,23 @@
|
||||
import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
||||
|
||||
/** 用户卡券属性 */
|
||||
export interface UserCouponProperty {
|
||||
// 组件样式
|
||||
style: ComponentStyle
|
||||
}
|
||||
|
||||
// 定义组件
|
||||
export const component = {
|
||||
id: 'UserCoupon',
|
||||
name: '用户卡券',
|
||||
icon: 'ep:ticket',
|
||||
property: {
|
||||
style: {
|
||||
bgType: 'color',
|
||||
bgColor: '',
|
||||
marginLeft: 8,
|
||||
marginRight: 8,
|
||||
marginBottom: 8
|
||||
} as ComponentStyle
|
||||
}
|
||||
} as DiyComponent<UserCouponProperty>
|
||||
@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<el-image
|
||||
src="https://shopro.sheepjs.com/admin/static/images/shop/decorate/couponCardStyle.png"
|
||||
/>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { UserCouponProperty } from './config'
|
||||
|
||||
/** 用户卡券 */
|
||||
defineOptions({ name: 'UserCoupon' })
|
||||
// 定义属性
|
||||
defineProps<{ property: UserCouponProperty }>()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<ComponentContainerProperty v-model="formData.style" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UserCouponProperty } from './config'
|
||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||
|
||||
// 用户卡券属性面板
|
||||
defineOptions({ name: 'UserCouponProperty' })
|
||||
|
||||
const props = defineProps<{ modelValue: UserCouponProperty }>()
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const { formData } = usePropertyForm(props.modelValue, emit)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,23 @@
|
||||
import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
||||
|
||||
/** 用户订单属性 */
|
||||
export interface UserOrderProperty {
|
||||
// 组件样式
|
||||
style: ComponentStyle
|
||||
}
|
||||
|
||||
// 定义组件
|
||||
export const component = {
|
||||
id: 'UserOrder',
|
||||
name: '用户订单',
|
||||
icon: 'ep:list',
|
||||
property: {
|
||||
style: {
|
||||
bgType: 'color',
|
||||
bgColor: '',
|
||||
marginLeft: 8,
|
||||
marginRight: 8,
|
||||
marginBottom: 8
|
||||
} as ComponentStyle
|
||||
}
|
||||
} as DiyComponent<UserOrderProperty>
|
||||
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<el-image src="https://shopro.sheepjs.com/admin/static/images/shop/decorate/orderCardStyle.png" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { UserOrderProperty } from './config'
|
||||
|
||||
/** 用户订单 */
|
||||
defineOptions({ name: 'UserOrder' })
|
||||
// 定义属性
|
||||
defineProps<{ property: UserOrderProperty }>()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<ComponentContainerProperty v-model="formData.style" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UserOrderProperty } from './config'
|
||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||
|
||||
// 用户订单属性面板
|
||||
defineOptions({ name: 'UserOrderProperty' })
|
||||
|
||||
const props = defineProps<{ modelValue: UserOrderProperty }>()
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const { formData } = usePropertyForm(props.modelValue, emit)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,23 @@
|
||||
import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util'
|
||||
|
||||
/** 用户资产属性 */
|
||||
export interface UserWalletProperty {
|
||||
// 组件样式
|
||||
style: ComponentStyle
|
||||
}
|
||||
|
||||
// 定义组件
|
||||
export const component = {
|
||||
id: 'UserWallet',
|
||||
name: '用户资产',
|
||||
icon: 'ep:wallet-filled',
|
||||
property: {
|
||||
style: {
|
||||
bgType: 'color',
|
||||
bgColor: '',
|
||||
marginLeft: 8,
|
||||
marginRight: 8,
|
||||
marginBottom: 8
|
||||
} as ComponentStyle
|
||||
}
|
||||
} as DiyComponent<UserWalletProperty>
|
||||
@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<el-image
|
||||
src="https://shopro.sheepjs.com/admin/static/images/shop/decorate/walletCardStyle.png"
|
||||
/>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { UserWalletProperty } from './config'
|
||||
|
||||
/** 用户资产 */
|
||||
defineOptions({ name: 'UserWallet' })
|
||||
// 定义属性
|
||||
defineProps<{ property: UserWalletProperty }>()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<ComponentContainerProperty v-model="formData.style" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UserWalletProperty } from './config'
|
||||
import { usePropertyForm } from '@/components/DiyEditor/util'
|
||||
|
||||
// 用户资产属性面板
|
||||
defineOptions({ name: 'UserWalletProperty' })
|
||||
|
||||
const props = defineProps<{ modelValue: UserWalletProperty }>()
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const { formData } = usePropertyForm(props.modelValue, emit)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -1,138 +0,0 @@
|
||||
<template>
|
||||
<!-- 操作栏 -->
|
||||
<el-row justify="end">
|
||||
<el-button type="primary" @click="openForm">
|
||||
<Icon class="mr-5px" icon="ep:plus" />
|
||||
新增
|
||||
</el-button>
|
||||
<el-button @click="handleEdit">
|
||||
<Icon class="mr-5px" icon="ep:edit" />
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button @click="handleDelete">
|
||||
<Icon class="mr-5px" icon="ep:delete" />
|
||||
移除
|
||||
</el-button>
|
||||
<el-button type="danger" @click="handleQuit"> 退出团队</el-button>
|
||||
</el-row>
|
||||
<!-- 团队成员展示 -->
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="list"
|
||||
:show-overflow-tooltip="true"
|
||||
:stripe="true"
|
||||
class="mt-20px"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column align="center" label="姓名" prop="nickname" />
|
||||
<el-table-column align="center" label="部门" prop="deptName" />
|
||||
<el-table-column align="center" label="岗位" prop="postNames" />
|
||||
<el-table-column align="center" label="权限级别" prop="level">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :type="DICT_TYPE.CRM_PERMISSION_LEVEL" :value="row.level" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :formatter="dateFormatter" align="center" label="加入时间" prop="createTime" />
|
||||
</el-table>
|
||||
<CrmPermissionForm ref="permissionFormRef" @success="getList" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import { ElTable } from 'element-plus'
|
||||
import * as PermissionApi from '@/api/crm/permission'
|
||||
import { useUserStoreWithOut } from '@/store/modules/user'
|
||||
import CrmPermissionForm from './CrmPermissionForm.vue'
|
||||
import { CrmPermissionLevelEnum } from './index'
|
||||
import { DICT_TYPE } from '@/utils/dict'
|
||||
|
||||
defineOptions({ name: 'CrmPermissionList' })
|
||||
|
||||
const message = useMessage() // 消息
|
||||
|
||||
const props = defineProps<{
|
||||
bizType: number // 模块类型
|
||||
bizId: number // 模块数据编号
|
||||
}>()
|
||||
const loading = ref(true) // 列表的加载中
|
||||
const list = ref<PermissionApi.PermissionVO[]>([]) // 列表的数据
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const data = await PermissionApi.getPermissionList({
|
||||
bizType: props.bizType,
|
||||
bizId: props.bizId
|
||||
})
|
||||
list.value = data
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
const multipleSelection = ref<PermissionApi.PermissionVO[]>([]) // 选择的团队成员
|
||||
const handleSelectionChange = (val: PermissionApi.PermissionVO[]) => {
|
||||
multipleSelection.value = val
|
||||
}
|
||||
|
||||
const permissionFormRef = ref<InstanceType<typeof CrmPermissionForm>>() // 权限表单 Ref
|
||||
/**
|
||||
* 编辑团队成员
|
||||
*/
|
||||
const handleEdit = () => {
|
||||
if (multipleSelection.value?.length === 0) {
|
||||
message.warning('请先选择团队成员后操作!')
|
||||
return
|
||||
}
|
||||
const ids = multipleSelection.value?.map((item) => item.id)
|
||||
permissionFormRef.value?.open('update', props.bizType, props.bizId, ids)
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除团队成员
|
||||
*/
|
||||
const handleDelete = async () => {
|
||||
if (multipleSelection.value?.length === 0) {
|
||||
message.warning('请先选择团队成员后操作!')
|
||||
return
|
||||
}
|
||||
await message.delConfirm()
|
||||
const ids = multipleSelection.value?.map((item) => item.id)
|
||||
await PermissionApi.deletePermission({
|
||||
bizType: props.bizType,
|
||||
bizId: props.bizId,
|
||||
ids
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加团队成员
|
||||
*/
|
||||
const openForm = () => {
|
||||
permissionFormRef.value?.open('create', props.bizType, props.bizId)
|
||||
}
|
||||
|
||||
const userStore = useUserStoreWithOut() // 用户信息缓存
|
||||
/**
|
||||
* 退出团队
|
||||
*/
|
||||
const handleQuit = async () => {
|
||||
const permission = list.value.find(
|
||||
(item) => item.userId === userStore.getUser.id && item.level === CrmPermissionLevelEnum.OWNER
|
||||
)
|
||||
if (permission) {
|
||||
message.warning('负责人不能退出团队!')
|
||||
return
|
||||
}
|
||||
const userPermission = list.value.find((item) => item.userId === userStore.getUser.id)
|
||||
await PermissionApi.quitTeam(userPermission?.id)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.bizId,
|
||||
() => {
|
||||
getList()
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
</script>
|
||||
@ -1,15 +0,0 @@
|
||||
import CrmPermissionList from './CrmPermissionList.vue'
|
||||
|
||||
enum CrmBizTypeEnum {
|
||||
CRM_LEADS = 1, // 线索
|
||||
CRM_CUSTOMER = 2, // 客户
|
||||
CRM_CONTACTS = 3, // 联系人
|
||||
CRM_BUSINESS = 5, // 商机
|
||||
CRM_CONTRACT = 6 // 合同
|
||||
}
|
||||
|
||||
enum CrmPermissionLevelEnum {
|
||||
OWNER = 1 // 负责人
|
||||
}
|
||||
|
||||
export { CrmPermissionList, CrmBizTypeEnum, CrmPermissionLevelEnum }
|
||||
@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-tabs>
|
||||
<el-tab-pane label="拥有客户数限制">
|
||||
<CustomerLimitConfigList :confType="LimitConfType.CUSTOMER_QUANTITY_LIMIT" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="锁定客户数限制">
|
||||
<CustomerLimitConfigList :confType="LimitConfType.CUSTOMER_LOCK_LIMIT" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</ContentWrap>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import CustomerLimitConfigList from '@/views/crm/config/customerLimitConfig/CustomerLimitConfigList.vue'
|
||||
import { LimitConfType } from '@/api/crm/customerLimitConfig'
|
||||
|
||||
defineOptions({ name: 'CrmCustomerLimitConfig' })
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue