提交 93cc4e52 authored 作者: lihuihui's avatar lihuihui

update

上级 eb610b6b
...@@ -39,5 +39,8 @@ defineProps<{ title?: string }>() ...@@ -39,5 +39,8 @@ defineProps<{ title?: string }>()
line-height: 1; line-height: 1;
margin-bottom: 24px; margin-bottom: 24px;
border-left: 3px solid #aa1941; border-left: 3px solid #aa1941;
&.small{
font-size: 14px;
}
} }
</style> </style>
import { getProjectMap } from '@/api/base'
// 赛项信息
interface ProjectType {
id: number
name: string
}
interface ProjectStatus {
id: number
name: string
}
const projectTypeMap = ref<ProjectType[]>([])
const projectStatusMap = ref<ProjectStatus[]>([])
export function useGetProjectMap() {
getProjectMap().then((res: any) => {
projectTypeMap.value = res.data.project_type_map.map((item: any) => {
item.id = item.id + ''
return item
})
projectStatusMap.value = res.data.project_status_map.map((item: any) => {
item.id = item.id + ''
return item
})
})
return { projectTypeMap, projectStatusMap }
}
import httpRequest from '@/utils/axios' import httpRequest from '@/utils/axios'
import type { CreateChannelParams, ChannelListSearch } from './types'
// 获取封面列表 // 获取渠道列表
export function getCoverList(params?: { type?: string; page?: number; ['per-page']?: number }) { export function getChannelList(params?: ChannelListSearch) {
return httpRequest.get('/api/resource/v1/backend/cover/list', { params }) return httpRequest.get('/api/zws/v1/backend/channel/list', { params })
}
// 获取渠道详情
export function getChannelDetail(params?: { id?: string | string[] }) {
return httpRequest.get('/api/zws/v1/backend/channel/view', { params })
}
// 获取成员列表
export function getChannelUserList(params?: { id?: string | string[] }) {
return httpRequest.get('/api/zws/v1/backend/channel/member', { params })
}
// 新增渠道成员
export function memberCreate(data: { user_id: string; channels_id: string; roles: string; type?: string }) {
return httpRequest.post('/api/zws/v1/backend/channel/member-create', data)
}
// 删除成员
export function memberDelete(data: { user_id: string; channel_id: string; role_id: string; }) {
return httpRequest.post('/api/zws/v1/backend/channel/member-delete', data)
}
// 获取渠道相关的公共map
export function getChannelMap() {
return httpRequest.get('/api/zws/v1/backend/channel/conditions')
}
// 搜索用户
export function searchUser(params: { q: string; }) {
return httpRequest.get('/api/zws/v1/backend/common/search-user', { params })
}
// 获取角色
export function getProjectRoles() {
return httpRequest.get('/api/zws/v1/backend/common/project-roles')
}
// 创建
export function createChannel(data: CreateChannelParams) {
return httpRequest.post('/api/zws/v1/backend/channel/create', data)
} }
<script setup lang="ts">
import { searchUser, getProjectRoles } from '../api'
import { ElMessage } from 'element-plus'
const emit = defineEmits(['update:modelValue', 'changeUser'])
// 用户搜索
interface UserInfo {
id: string
nickname: string
mobile: string
}
let userValue = $ref('')
const loading = ref(false)
let userListOption = $ref<UserInfo[]>()
const remoteMethod = (q: string) => {
if (q) {
loading.value = true
searchUser({ q: q }).then((res: { data: UserInfo[] }) => {
loading.value = false
userListOption = res.data
})
}
}
// 获取角色
interface ProjectRole {
id: string
name: string
}
let roleValue = $ref([])
let projectRoleOption = $ref<ProjectRole[]>()
getProjectRoles().then((res: { data: ProjectRole[] }) => {
projectRoleOption = res.data
})
// 选择完成
const submit = function () {
if (Object.keys(roleValue).length && userValue) {
const data = {
userInfo: userListOption.find(item => item.id === userValue),
role: projectRoleOption.reduce((a: any, b) => {
if (roleValue.find((item: any) => item === b.id)) {
a.push(b)
}
return a
}, [])
}
emit('changeUser', data)
emit('update:modelValue', false)
userValue = ''
roleValue = []
} else {
ElMessage('请选择')
}
}
</script>
<template>
<el-dialog title="添加项目成员" width="400px" :close-on-click-modal="false">
<el-form style="display: block; width: 80%; margin: 0 auto" class="demo-form-inline">
<el-form-item label="选择成员">
<el-select
v-model="userValue"
filterable
remote
reserve-keyword
placeholder="请输入"
:remote-method="remoteMethod"
:loading="loading"
>
<el-option
v-for="item in userListOption"
:key="item.id"
:label="item.mobile ? `${item.nickname}(${item.mobile}})` : item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="选择角色" v-show="userValue">
<el-select v-model="roleValue" multiple placeholder="请选择">
<el-option v-for="item in projectRoleOption" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="emit('update:modelValue', false)">取消</el-button>
<el-button type="primary" @click="submit"> 确定 </el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import type { FormRules } from 'element-plus'
import { searchUser } from '../api'
const form = $ref({
contact_person: '',
contact_phone: '',
contact_email: '',
agreement_id: '',
agreement_signing_time: '',
agreement_filing_time: '',
channel_open_time: '',
agreement_type: '',
division_proportion: '',
channel_tax_rate: '',
bank_account_name: '',
channel_bank: '',
channel_bank_account: '',
company_registered_address: ''
})
interface State {
id: string
name: string
}
interface Props {
agreementType: State[]
channelTaxRate: State[]
}
const prop = defineProps<Props>()
const rules = reactive<FormRules>({
contact_person: [{ required: true, message: '请输入' }],
contact_phone: [{ required: true, message: '请输入' }],
contact_email: [{ required: true, message: '请输入' }]
})
// 用户搜索
interface UserInfo {
id: string
nickname: string
mobile: string
}
const loading = ref(false)
let userListOption = $ref<UserInfo[]>()
const remoteMethod = (q: string) => {
if (q) {
loading.value = true
searchUser({ q: q }).then((res: { data: UserInfo[] }) => {
loading.value = false
userListOption = res.data
})
}
}
</script>
<template>
<div class="basic-info">
<h2 class="app-card-hd__title small">协议信息</h2>
<el-form label-width="100px" :model="form" class="demo-form-inline" :inline="true" :rules="rules">
<el-form-item label="联络人" prop="contact_person">
<el-select
v-model="form.contact_person"
filterable
remote
reserve-keyword
placeholder="请输入"
:remote-method="remoteMethod"
:loading="loading"
>
<el-option
v-for="item in userListOption"
:key="item.id"
:label="item.mobile ? `${item.nickname}(${item.mobile}})` : item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="联络电话" prop="contact_phone">
<el-input v-model="form.contact_phone" placeholder="请输入" />
</el-form-item>
<el-form-item label="联络邮箱" prop="contact_email">
<el-input v-model="form.contact_email" placeholder="请输入" />
</el-form-item>
<!-- <el-form-item label="服务电话">
<el-input v-model="form.channel_tax_rate" placeholder="请输入" />
</el-form-item> -->
<el-form-item label="合作协议编号">
<el-input v-model="form.agreement_id" placeholder="请输入" />
</el-form-item>
<el-form-item label="协议签署时间">
<el-date-picker v-model="form.agreement_signing_time" type="date" placeholder="请选择" />
</el-form-item>
<el-form-item label="协议归档时间">
<el-date-picker v-model="form.agreement_filing_time" type="date" placeholder="请选择" />
</el-form-item>
<el-form-item label="账号开通时间">
<el-date-picker v-model="form.channel_open_time" type="date" placeholder="请选择" />
</el-form-item>
<el-form-item label="签约类型">
<el-select v-model="form.agreement_type" placeholder="请选择">
<el-option v-for="item in prop.agreementType" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="分成比例(%)">
<el-input v-model="form.division_proportion" placeholder="请输入" />
</el-form-item>
<el-form-item label="渠道税率">
<el-select v-model="form.channel_tax_rate" placeholder="请选择">
<el-option v-for="item in prop.channelTaxRate" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="银行开户名">
<el-input v-model="form.bank_account_name" placeholder="请输入" />
</el-form-item>
<el-form-item label="银行开户行">
<el-input v-model="form.channel_bank" placeholder="请输入" />
</el-form-item>
<el-form-item label="银行账号">
<el-input v-model="form.channel_bank_account" placeholder="请输入" />
</el-form-item>
<el-form-item label="注册地址">
<el-input v-model="form.company_registered_address" placeholder="请输入" />
</el-form-item>
</el-form>
</div>
</template>
<style lang="scss" scoped>
.basic-info {
padding-top: 20px;
}
</style>
<script setup lang="ts">
import type { FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { searchUser } from '../api'
import type { BasicInfoParams } from '../types'
const route = useRoute()
let form = $ref({
title: '',
service_phone: '',
channel_owner_user_id: '',
channel_status: '',
tags: [],
summary: '',
comment: ''
})
interface Props {
channelTags: string[]
type: string
channelStatus: {
id: string
name: string
}[]
data?: BasicInfoParams
}
const prop = defineProps<Props>()
const rules = reactive<FormRules>({
title: [{ required: true, message: '请输入' }],
channel_owner_user_id: [{ required: true, message: '请选择' }],
channel_status: [{ required: true, message: '请选择' }]
})
// 用户搜索
interface UserInfo {
id: string
nickname: string
mobile: string
}
const loading = ref(false)
let userListOption = $ref<UserInfo[]>()
const remoteMethod = (q: string) => {
if (q) {
loading.value = true
searchUser({ q: q }).then((res: { data: UserInfo[] }) => {
loading.value = false
userListOption = res.data
})
}
}
const formRule = $ref<any>()
const submit = function () {
return formRule
.validateField()
.then(() => {
const paramForm = JSON.parse(JSON.stringify(form))
paramForm.tags = paramForm.tags.toString()
console.log(paramForm, 'paramForm')
return paramForm
})
.catch(() => {
ElMessage({
message: '基本信息有误',
type: 'warning'
})
return false
})
}
defineExpose({
submit
})
// 数据回显
watch(
() => prop.data,
val => {
form = Object.assign(form, val)
remoteMethod(form.channel_owner_user_id)
}
)
</script>
<template>
<div class="basic-info">
<h2 class="app-card-hd__title small">基本信息</h2>
<el-form ref="formRule" label-width="100px" :model="form" class="demo-form-inline" :inline="true" :rules="rules">
<el-form-item label="渠道名称" prop="title">
<el-input v-model="form.title" placeholder="请输入" />
</el-form-item>
<el-form-item label="渠道电话" v-if="prop.type !== '1'">
<el-input v-model="form.service_phone" placeholder="请输入" />
</el-form-item>
<el-form-item label="渠道归属人" prop="channel_owner_user_id">
<el-select
v-model="form.channel_owner_user_id"
filterable
remote
reserve-keyword
placeholder="请输入"
:remote-method="remoteMethod"
:loading="loading"
>
<el-option
v-for="item in userListOption"
:key="item.id"
:label="item.mobile ? `${item.nickname}(${item.mobile}})` : item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="channel_status">
<el-select v-model="form.channel_status" placeholder="请选择">
<el-option v-for="item in prop.channelStatus" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="渠道标签">
<el-select v-model="form.tags" placeholder="请选择" multiple>
<el-option v-for="item in prop.channelTags" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
<el-form-item label="渠道摘要">
<el-input v-model="form.summary" :rows="2" type="textarea" placeholder="请输入" />
</el-form-item>
<el-form-item label="备注" v-if="prop.type === '3'">
<el-input v-model="form.comment" :rows="2" type="textarea" placeholder="请输入" />
</el-form-item>
</el-form>
</div>
</template>
<style lang="scss" scoped>
.basic-info {
padding-top: 20px;
}
</style>
<script setup lang="ts">
import type { FormRules } from 'element-plus'
import AppUploadVue from '@/components/base/AppUpload.vue'
const form = $ref({
company_name: '',
company_short_name: '',
tax_number: '',
channel_tax_rate: '',
contact_person: '',
contact_phone: '',
contact_email: '',
contact_wechat: '',
bank_account_name: '',
channel_bank: '',
channel_bank_account: '',
company_registered_address: '',
business_license: ''
})
const upload = $ref({
i1: '',
i2: '',
i3: ''
})
const uploadFile = $ref<{
company_legal_representative_id_card_front?: string
company_legal_representative_id_card_back?: string
business_license?: string
}>()
const prop = defineProps({
type: Number,
channelTags: Array
})
const rules = reactive<FormRules>({
contact_person: [{ required: true, message: '请输入' }],
contact_phone: [{ required: true, message: '请输入' }],
contact_email: [{ required: true, message: '请输入' }]
})
// 上传
const uploadI1 = function (file: any) {
console.log(file)
uploadFile.company_legal_representative_id_card_front = file.raw
}
const uploadI2 = function (file: any) {
uploadFile.company_legal_representative_id_card_back = file.raw
}
const uploadI3 = function (file: any) {
uploadFile.business_license = file.raw
}
</script>
<template>
<div class="basic-info">
<h2 class="app-card-hd__title small">公司信息</h2>
<el-form label-width="100px" :model="form" class="demo-form-inline" :inline="true" :rules="rules">
<el-form-item label="公司名称">
<el-input v-model="form.company_name" placeholder="请输入" />
</el-form-item>
<el-form-item label="公司字号">
<el-input v-model="form.company_short_name" placeholder="请输入" />
</el-form-item>
<el-form-item label="企业税号">
<el-input v-model="form.tax_number" placeholder="请输入" />
</el-form-item>
<el-form-item label="企业税率">
<el-input v-model="form.channel_tax_rate" placeholder="请输入" />
</el-form-item>
<el-form-item label="联络人" prop="contact_person">
<el-input v-model="form.contact_person" placeholder="请输入" />
</el-form-item>
<el-form-item label="联络电话" prop="contact_phone">
<el-input v-model="form.contact_phone" placeholder="请输入" />
</el-form-item>
<el-form-item label="联络邮箱" prop="contact_email">
<el-input v-model="form.contact_email" placeholder="请输入" />
</el-form-item>
<el-form-item label="联络微信">
<el-input v-model="form.contact_wechat" placeholder="请输入" />
</el-form-item>
<el-form-item label="银行开户名">
<el-input v-model="form.bank_account_name" placeholder="请输入" />
</el-form-item>
<el-form-item label="银行开户行">
<el-input v-model="form.channel_bank" placeholder="请输入" />
</el-form-item>
<el-form-item label="银行账号">
<el-input v-model="form.channel_bank_account" placeholder="请输入" />
</el-form-item>
<el-form-item label="注册地址">
<el-input v-model="form.company_registered_address" placeholder="请输入" />
</el-form-item>
<el-form-item label="法人身份证(国徽面)">
<AppUploadVue v-model="upload.i1" @success="uploadI1"></AppUploadVue>
</el-form-item>
<el-form-item label="法人身份证(头像面)">
<AppUploadVue v-model="upload.i2" @success="uploadI2"></AppUploadVue>
</el-form-item>
<el-form-item label="营业执照">
<AppUploadVue v-model="upload.i3" @success="uploadI3"></AppUploadVue>
</el-form-item>
</el-form>
</div>
</template>
<style lang="scss" scoped>
.basic-info {
padding-top: 20px;
}
</style>
<script setup lang="ts">
const form = $ref({
channel_quality: '',
distribution_status: '',
case_withdraw_status: '',
service_dialog_status: ''
})
interface State {
id: string
name: string
}
interface Props {
channelQuality: number[]
distributionStatus: State[]
caseWithdrawStatus: State[]
serviceDialogStatus: State[]
}
const prop = defineProps<Props>()
</script>
<template>
<div class="basic-info">
<h2 class="app-card-hd__title small">控制信息</h2>
<el-form label-width="100px" :model="form" class="demo-form-inline" :inline="true">
<el-form-item label="渠道质量">
<el-select v-model="form.channel_quality" placeholder="请选择">
<el-option v-for="item in prop.channelQuality" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
<el-form-item label="分配状态">
<el-select v-model="form.distribution_status" placeholder="请选择">
<el-option v-for="item in prop.distributionStatus" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="回抽状态">
<el-select v-model="form.case_withdraw_status" placeholder="请选择">
<el-option v-for="item in prop.caseWithdrawStatus" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="咨询框状态">
<el-select v-model="form.service_dialog_status" placeholder="请选择">
<el-option v-for="item in prop.serviceDialogStatus" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-form>
</div>
</template>
<style lang="scss" scoped>
.basic-info {
padding-top: 20px;
}
</style>
<script setup lang="ts">
import { ElMessage } from 'element-plus'
const emit = defineEmits(['update:modelValue', 'selectLeaders'])
const prop = defineProps<{
leaders: {
id: string
name: string
}[]
}>()
const submit = function () {
if (leaderValue.length) {
emit('selectLeaders', leaderValue.toString())
emit('update:modelValue', false)
} else {
ElMessage('请选择')
}
}
const leaderValue = $ref([])
</script>
<template>
<el-dialog title="请选择管理人员" width="400px" :close-on-click-modal="false">
<el-checkbox-group v-model="leaderValue">
<el-checkbox v-for="item in prop.leaders" :key="item.id" :label="item.id">{{ item.name }}</el-checkbox>
</el-checkbox-group>
<template #footer>
<span class="dialog-footer">
<el-button @click="emit('update:modelValue', false)">取消</el-button>
<el-button type="primary" @click="submit"> 确定 </el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import AppUploadVue from '@/components/base/AppUpload.vue'
import type { ProjectParams } from '../types'
import type { FormInstance, FormRules } from 'element-plus'
import { searchUser } from '../api'
interface State {
id: string
name: string
}
interface Props {
contractConversionType: State[]
contractType: State[]
contractDivisionRuleType: State[]
contractSecondaryDivisionType: any
}
const prop = defineProps<Props>()
const list = $ref<ProjectParams[]>([])
const listOptions = $computed(() => {
return {
columns: [
{
label: '项目名称',
prop: 'project_id_name'
},
{
label: '分成规则',
prop: 'division_rule',
computed(row: { row: { division_rule: string } }) {
return prop.contractSecondaryDivisionType.find(
(item: { id: string; name: string }) => item.id === row.row.division_rule
).name
}
},
{ label: '分成比例', prop: 'division_proportion' },
{
label: '学员上限',
prop: 'unpaid_list_limit'
},
{ label: '有效期', prop: 'expire_month' },
{ label: '跟进人', prop: 'follower_user_id' },
{ label: '关联日期', prop: 'updated_time' },
{ label: '操作', prop: 'name', slots: 'table-x', width: 100 }
],
data: list
}
})
const editProject = function () {
return ''
}
const deleteProject = function () {
return ''
}
let drawer = $ref(false)
const form = $ref({
project_id_name: '',
conversion_type: '',
type: '',
location_limit: '',
unpaid_list_limit: '',
expire_month: 0,
follower_user_id: '',
division_rule: '',
division_proportion: '',
expire_range_month_start: '',
expire_range_month_end: '',
upload: '',
secondary_channel_id: '',
secondary_division_type: '',
secondary_division_rule: '',
secondary_division_proportion: ''
})
const rules = reactive<FormRules>({
project_id_name: [{ required: true, message: '请选择' }],
conversion_type: [{ required: true, message: '请选择' }],
type: [{ required: true, message: '请选择' }],
follower_user_id: [{ required: true, message: '请选择' }],
division_rule: [{ required: true, message: '请输入' }],
division_proportion: [{ required: true, message: '请输入' }]
})
const upload = function (file: any) {
const contract_document = file.raw
// uploadFile.business_license = file.raw
}
// 用户搜索
interface UserInfo {
id: string
nickname: string
mobile: string
}
const loading = ref(false)
let userListOption = $ref<UserInfo[]>()
const remoteMethod = (q: string) => {
if (q) {
loading.value = true
searchUser({ q: q }).then((res: { data: UserInfo[] }) => {
loading.value = false
userListOption = res.data
})
}
}
// 确认
const ruleFormRef = ref<FormInstance>()
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
list.push(form)
drawer = false
} else {
console.log('error submit!', fields)
}
})
}
const handlerConfirm = function () {
// formRule
// .validateField()
// .then(() => {
// projectList.push(form)
// console.log(projectList, '123')
// })
// .catch(() => {
// return false
// })
// projectList.push(form)
}
</script>
<template>
<div class="project">
<h2 class="app-card-hd__title small">项目信息</h2>
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-button type="primary" @click="drawer = true">关联项目</el-button>
</template>
<!-- #table-x="{ row }" -->
<template>
<el-button text type="primary" @click="editProject()">编辑</el-button>
<el-button text type="primary" @click="deleteProject()">删除</el-button>
</template>
</AppList>
<el-drawer :destroy-on-close="true" size="50%" v-model="drawer" title="关联项目" direction="rtl">
<el-form
ref="ruleFormRef"
:rules="rules"
label-width="130px"
:model="form"
class="demo-form-inline"
:inline="true"
>
<el-form-item label="项目名称" prop="project_id_name">
<el-input v-model="form.project_id_name" type="input" placeholder="请输入" />
</el-form-item>
<el-form-item label="转化类型" prop="conversion_type">
<el-select v-model="form.conversion_type" placeholder="请选择">
<el-option v-for="item in prop.contractConversionType" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="合同类型" prop="type">
<el-select v-model="form.type" placeholder="请选择">
<el-option v-for="item in prop.contractType" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="代理地域">
<el-input v-model="form.location_limit" :rows="2" type="input" placeholder="请输入" />
</el-form-item>
<el-form-item label="学员上线">
<el-input v-model="form.unpaid_list_limit" :rows="2" type="input" placeholder="请输入" />
</el-form-item>
<el-form-item label="有效期(月)">
<el-input-number v-model="form.expire_month" :min="1" :max="10" />
</el-form-item>
<el-form-item label="跟进人" prop="follower_user_id">
<el-select
v-model="form.follower_user_id"
filterable
remote
reserve-keyword
placeholder="请输入"
:remote-method="remoteMethod"
:loading="loading"
>
<el-option
v-for="item in userListOption"
:key="item.id"
:label="item.mobile ? `${item.nickname}(${item.mobile}})` : item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="分成规则" prop="division_rule">
<el-select v-model="form.division_rule" placeholder="请选择">
<el-option
v-for="item in prop.contractDivisionRuleType"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="统一分成比例(%)" prop="division_proportion">
<el-input v-model="form.division_proportion" type="input" placeholder="请输入" />
</el-form-item>
<el-form-item label="有效期开始时间">
<el-date-picker v-model="form.expire_range_month_start" type="date" placeholder="请选择" />
</el-form-item>
<el-form-item label="有效期结束时间">
<el-date-picker v-model="form.expire_range_month_end" type="date" placeholder="请选择" />
</el-form-item>
<el-form-item label="合同">
<AppUploadVue v-model="form.upload" @success="upload"></AppUploadVue>
</el-form-item>
<template v-if="false">
<el-form-item label="二级渠道商">
<el-select
v-model="form.secondary_channel_id"
filterable
remote
reserve-keyword
placeholder="请输入"
:remote-method="remoteMethod"
:loading="loading"
>
<el-option
v-for="item in userListOption"
:key="item.id"
:label="item.mobile ? `${item.nickname}(${item.mobile}})` : item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="二级渠道分成方式">
<el-select v-model="form.secondary_division_type" placeholder="请选择">
<el-option
v-for="item in prop.contractSecondaryDivisionType"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="二级渠道分成规则">
<el-select v-model="form.secondary_division_rule" placeholder="请选择">
<el-option
v-for="item in prop.contractDivisionRuleType"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="统一分成比例(%)">
<el-input v-model="form.secondary_division_proportion" :rows="2" type="input" placeholder="请输入" />
</el-form-item>
<el-form-item label="二级渠道合同">
<AppUploadVue v-model="form.upload" @success="upload"></AppUploadVue>
</el-form-item>
</template>
<div style="display: flex; justify-content: center; margin-top: 20px">
<el-form-item>
<el-button>取消</el-button>
<el-button type="primary" @click="submitForm(ruleFormRef)">确定</el-button>
</el-form-item>
</div>
</el-form>
</el-drawer>
</div>
</template>
<script setup lang="ts">
import AppList from '@/components/base/AppList.vue'
import { getChannelUserList, memberDelete } from '../api'
import { ElMessage } from 'element-plus'
const AddMember = defineAsyncComponent(() => import('../components/AddMember.vue'))
interface User {
nickname: string
mobile: string
email: string
role: string[]
}
const prop = defineProps<{ data: any }>()
const route = useRoute()
let userList = $ref<User[]>([])
const listOptions = $computed(() => {
return {
columns: [
{
label: '姓名',
prop: 'nickname',
computed(row: any) {
let name = ''
if (row.row?.name) {
name = row.row.name
} else {
name = row.row.nickname
}
return name
}
},
{ label: '手机号', prop: 'mobile' },
{ label: '邮箱', prop: 'email' },
{
label: '角色',
prop: 'role',
computed(row: any) {
if (row.row?.role_name) {
return row.row?.role_name
} else {
return row.row.role.reduce((a: any, b: any) => a.push(b.name) && a, []).toString()
}
}
},
{ label: '加入日期', prop: 'updated_time' },
{ label: '操作', prop: 'name', slots: 'table-x', width: 100 }
],
data: userList
}
})
// 选择人员
const changeUser = function (e: any) {
const info = Object.assign(e.userInfo, { role: e.role })
userList.push(info)
}
// 删除人员
const deleteProjectMember = function (row: any) {
console.log(row, 'row')
if (route.params?.id) {
const params = {
user_id: row.user_id,
channel_id: prop.data.channel_id,
role_id: row.role_id
}
memberDelete(params).then(res => {
getChannelUser()
ElMessage({
message: '删除成功',
type: 'success'
})
})
} else {
const index = userList.findIndex((item: any) => item.id === row.id)
userList.splice(index, 1)
}
}
const labelVisible = $ref(false)
// 新建时重构接口需要的数据
const data = function () {
const user = userList.reduce((a: any, b: any) => {
a.push({
user_id: b.id,
roles: b.role.reduce((roleA: any, roleB: any) => roleA.push(roleB.id) && roleA, []).toString()
})
return a
}, [])
return user.length ? JSON.stringify(user) : ''
}
// 获取渠道人员列表
const getChannelUser = function () {
getChannelUserList({ id: route.params.id }).then((res: { data: { list: User[] } }) => {
userList = res.data.list
})
}
// 详情
onMounted(() => {
if (route.params?.id) {
getChannelUser()
}
})
defineExpose({
data
})
</script>
<template>
<div class="user-info">
<h2 class="app-card-hd__title small">成员信息</h2>
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-button type="primary" @click="labelVisible = true">添加成员</el-button>
</template>
<template #table-x="{ row }">
<el-button text type="primary" @click="deleteProjectMember(row)">删除</el-button>
</template>
</AppList>
<AddMember v-model="labelVisible" @changeUser="changeUser"></AddMember>
</div>
</template>
<style lang="scss" scoped></style>
import { getChannelMap } from '../api'
interface State {
id: string
name: string
}
interface Project {
project_id: string
roles: string[]
permissions: string[]
tags: Record<string, string>
}
const authProjectList = ref<Project[]>([])
const tags = ref<Record<string, string>>({})
// 所有下拉的选项
const optionsMap = ref<{
channelType: State[]
channelQuality: number[]
distributionStatus: State[]
caseWithdrawStatus: State[]
serviceDialogStatus: State[]
channelStatus: State[]
channelTags: string[]
contractConversionType: State[]
contractType: State[]
contractDivisionRuleType: State[]
contractSecondaryDivisionType: State[],
agreementType: State[],
channelTaxRate: State[]
}>({
channelType: [],
channelQuality: [],
distributionStatus: [],
caseWithdrawStatus: [],
serviceDialogStatus: [],
channelStatus: [],
channelTags: [],
contractConversionType: [],
contractType: [],
contractDivisionRuleType: [],
contractSecondaryDivisionType: [],
agreementType: [],
channelTaxRate: []
})
// 领导
const leaders = ref<State[]>([])
export function useMap() {
const projectId = ref('')
const prefix = ref('')
function fetchInfo() {
getChannelMap().then((res: any) => {
const data = res.data
optionsMap.value = {
channelTags: data.tags_map || [],
channelType: data.channel_type_map?.slice(0, 3) || [],
channelStatus: data.channel_status_map || [],
channelQuality: data.channel_quality_map || [],
distributionStatus: data.distribution_status_map || [],
caseWithdrawStatus: data.case_withdraw_status_map || [],
serviceDialogStatus: data.service_dialog_status_map || [],
contractConversionType: data.contract_conversion_type_map || [],
contractType: data.contract_type_map || [],
contractDivisionRuleType: data.contract_division_rule_type_map || [],
contractSecondaryDivisionType: data.contract_secondary_division_type_map || [],
agreementType: data.agreement_type_map || [],
channelTaxRate: data.channel_tax_rate_map || []
}
authProjectList.value = data.project_auth_map || []
tags.value = data.tags || {}
leaders.value = data.leaders_map || []
})
}
if (!authProjectList.value.length) fetchInfo()
// 当前项目
const project = computed(() => {
return authProjectList.value.find(item => item.project_id === projectId.value)
})
// 是否需要权限控制
function isAuth(key: string, pre: string = prefix.value) {
const prop = pre + key
return Object.prototype.hasOwnProperty.call(tags.value, prop)
}
// 有没有权限
function hasAuth(key: string, pid: string = projectId.value, pre: string = prefix.value) {
const project = authProjectList.value.find(item => item.project_id === pid)
// 暂时先返回true; 有项目ID的必须定义项目ID,要不等于没做权限处理
if (!project) return true
const prop = pre + key
return Object.prototype.hasOwnProperty.call(project.tags, prop)
}
// 权限校验
function checkAuth(key: string, pid: string = projectId.value, pre: string = prefix.value) {
return isAuth(key, pre) ? hasAuth(key, pid, pre) : true
}
return { leaders, optionsMap, authProjectList, tags, project, projectId, prefix, isAuth, hasAuth, checkAuth }
}
export interface BasicInfoParams {
title: string
service_phone?: string
channel_owner_user_id: string
channel_status: string
tags?: string
summary?: string
comment?: string
}
export interface ChannelListSearch {
channel_id?: string
title?: string
company_short_name?: string
tags?: string
service_dialog_status?: string
case_withdraw_status?: string
distribution_status?: string
channel_quality?: string
['per-page']?: string
page?: string
}
export interface ProjectParams {
project_id_name?: string
conversion_type: string
type: string
location_limit?: string
unpaid_list_limit?: string
expire_month?: number,
follower_user_id: string
division_rule: string
division_proportion: string
expire_range_month_start?: string
expire_range_month_end?: string
upload?: string
secondary_channel_id?: string
secondary_division_type?: string
secondary_division_rule?: string
secondary_division_proportion?: string
}
export interface CreateChannelParams extends BasicInfoParams {
leaders_id: string
members: string
}
\ No newline at end of file
<script setup lang="ts"> <script setup lang="ts">
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import { useMap } from '../composables/useMap'
import { getChannelList } from '../api'
const { optionsMap } = useMap()
const Label = defineAsyncComponent(() => import('../components/Label.vue')) const Label = defineAsyncComponent(() => import('../components/Label.vue'))
const QRCode = defineAsyncComponent(() => import('../components/QRCode.vue')) const QRCode = defineAsyncComponent(() => import('../components/QRCode.vue'))
...@@ -8,66 +12,78 @@ const appList = $ref<InstanceType<typeof AppList> | null>(null) ...@@ -8,66 +12,78 @@ const appList = $ref<InstanceType<typeof AppList> | null>(null)
const listOptions = $computed(() => { const listOptions = $computed(() => {
return { return {
remote: {
httpRequest: getChannelList,
params: {
channel_id: '',
title: '',
company_short_name: '',
tags: '',
service_dialog_status: '',
case_withdraw_status: '',
distribution_status: '',
channel_quality: ''
}
},
filters: [ filters: [
{ type: 'input', prop: 'code', placeholder: '渠道编号' }, { type: 'input', prop: 'channel_id', placeholder: '渠道编号' },
{ type: 'input', prop: 'code', placeholder: '渠道名称' }, { type: 'input', prop: 'title', placeholder: '渠道名称' },
{ type: 'input', prop: 'code', placeholder: '公司字号' }, { type: 'input', prop: 'company_short_name', placeholder: '公司字号' },
{ type: 'select', prop: 'code', placeholder: '渠道标签' }, {
type: 'select',
prop: 'tags',
placeholder: '渠道标签',
options: optionsMap.value.channelTags.reduce((a: any, b: string) => a.push({ label: b, value: b }) && a, [])
},
{ {
type: 'select', type: 'select',
prop: 'code', prop: 'code',
placeholder: '咨询状态框', placeholder: '咨询状态框',
options: [ options: optionsMap.value.serviceDialogStatus,
{ value: '1', label: '隐藏' }, labelKey: 'name',
{ value: '2', label: '显示' } valueKey: 'id'
]
}, },
{ {
type: 'select', type: 'select',
prop: 'code', prop: 'code',
placeholder: '回抽状态', placeholder: '回抽状态',
options: [ options: optionsMap.value.caseWithdrawStatus,
{ value: '1', label: '开启' }, labelKey: 'name',
{ value: '2', label: '关闭' } valueKey: 'id'
]
}, },
{ {
type: 'select', type: 'select',
prop: 'code', prop: 'code',
placeholder: '分配状态', placeholder: '分配状态',
options: [ options: optionsMap.value.distributionStatus
{ value: '1', label: '开启' },
{ value: '2', label: '关闭' }
]
}, },
{ {
type: 'select', type: 'select',
prop: 'code', prop: 'code',
placeholder: '渠道质量', placeholder: '渠道质量',
options: (function () { options: optionsMap.value.channelQuality.reduce((a: any, b: number) => a.push({ label: b, value: b }) && a, [])
const options = []
for (let i = 0; i < 11; i++) {
options.push({ value: i, label: i })
}
return options
})()
} }
],
data: [
{ id: 1, code: 123 },
{ id: 2, code: 456 }
] ]
} }
}) })
const columns = $computed(() => { const columns = $computed(() => {
const columns: Record<string, any>[] = [ const columns: Record<string, any>[] = [
{ label: '渠道编号', prop: 'code' }, { label: '渠道编号', prop: 'channel_id' },
{ label: '渠道名称', prop: 'name' }, { label: '渠道名称', prop: 'title' },
{ label: '渠道标签', prop: 'name' }, {
{ label: '归属人', prop: 'name' }, label: '渠道标签',
{ label: '渠道类型', prop: 'name' }, prop: 'tags',
{ label: '状态', prop: 'name' }, computed(row: any) {
{ label: '更新时间', prop: 'name' }, return Array.isArray(row.row.tags) ? row.row.tags.toString() : row.row.tags
}
},
{
label: '归属人',
prop: 'channel_owner_user_id_name'
},
{ label: '渠道类型', prop: 'channel_type_name' },
{ label: '状态', prop: 'channel_status_name' },
{ label: '更新时间', prop: 'updated_time' },
{ label: '操作', prop: 'name', slots: 'table-x', width: 300 } { label: '操作', prop: 'name', slots: 'table-x', width: 300 }
] ]
if (selectionVisible) columns.unshift({ type: 'selection' }) if (selectionVisible) columns.unshift({ type: 'selection' })
......
<script setup lang="ts"> <script setup lang="ts">
import { useMap } from '../composables/useMap'
import BasicInfo from '../components/BasicInfo.vue'
import CompanyInfo from '../components/CompanyInfo.vue'
import ControlInfo from '../components/ControlInfo.vue'
import UserInfo from '../components/UserInfo.vue'
import Project from '../components/Project.vue'
import Leaders from '../components/Leaders.vue'
import Agreement from '../components/Agreement.vue'
import { createChannel, getChannelDetail } from '../api'
import type { CreateChannelParams, BasicInfoParams } from '../types'
// import AppUploadVue from '@/components/base/AppUpload.vue'
const router = useRouter()
const route = useRoute()
const { optionsMap, leaders } = useMap()
interface Props { interface Props {
isAdd?: boolean isAdd?: boolean
isUpdate?: boolean isUpdate?: boolean
...@@ -9,8 +27,78 @@ const props = defineProps<Props>() ...@@ -9,8 +27,78 @@ const props = defineProps<Props>()
const title = $computed(() => { const title = $computed(() => {
return (props.isAdd && '创建渠道') || (props.isUpdate && '编辑渠道') || (props.isView && '查看渠道') || '' return (props.isAdd && '创建渠道') || (props.isUpdate && '编辑渠道') || (props.isView && '查看渠道') || ''
}) })
// 渠道类型 1:线上渠道,2:线下对公渠道,3:线下个人渠道
const channelTypeValue = $ref('1')
const aa = $ref('')
const update = function (e: any, e2: any) {
console.log(aa, e, 'eeee', e2)
}
// 选择管理人员
const leadersLabelVisible = $ref(false)
// 基本信息
const basicInfoRef = $ref<{ submit: () => BasicInfoParams | false }>()
// 成员信息
const userInfo = $ref<{ data: () => string }>()
const onSubmit = async function (e: string) {
const basicInfoForm = await basicInfoRef.submit()
console.log(userInfo.data(), 'userInfo/data')
if (basicInfoForm) {
const params = Object.assign(
{
channel_type: channelTypeValue,
leaders_id: e,
members: userInfo.data()
},
basicInfoForm
)
console.log(params, 'e', e)
createChannel(params).then(() => {
router.go(-1)
})
}
}
let viewData = $ref<CreateChannelParams>()
onMounted(() => {
if (props?.isUpdate) {
getChannelDetail({ id: route.params.id }).then((res: { data: CreateChannelParams }) => {
viewData = res.data
})
}
})
</script> </script>
<template> <template>
<AppCard :title="title"></AppCard> <AppCard :title="title">
<div style="padding-left: 20px">
<el-form class="demo-form-inline">
<el-form-item label="渠道类型">
<el-select v-model="channelTypeValue" placeholder="请选择">
<el-option v-for="item in optionsMap.channelType" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-form>
<!-- 基本信息(公用) -->
<BasicInfo :data="viewData" ref="basicInfoRef" :type="channelTypeValue" v-bind="optionsMap"></BasicInfo>
<!-- 协议信息 -->
<agreement v-if="channelTypeValue !== '1'" v-bind="optionsMap"></agreement>
<!-- 公司信息 -->
<CompanyInfo v-if="channelTypeValue !== '1'"></CompanyInfo>
<!-- 控制信息 -->
<ControlInfo v-bind="optionsMap" v-if="channelTypeValue !== '1'"></ControlInfo>
<!-- 成员信息 -->
<UserInfo :data="viewData" ref="userInfo"></UserInfo>
<!-- 关联项目 -->
<Project v-bind="optionsMap"></Project>
<!-- 选择管理人员 -->
<Leaders @selectLeaders="onSubmit" v-model="leadersLabelVisible" :leaders="leaders"></Leaders>
<el-button @click="leadersLabelVisible = true" style="margin: 20px auto; display: block" type="primary"
>提交</el-button
>
</div>
</AppCard>
</template> </template>
...@@ -39,3 +39,18 @@ export function updateProject(data?: { id: string | string[]; title?: string; al ...@@ -39,3 +39,18 @@ export function updateProject(data?: { id: string | string[]; title?: string; al
export function getProjectMap() { export function getProjectMap() {
return httpRequest.get('/api/zws/v1/backend/project/conditions') return httpRequest.get('/api/zws/v1/backend/project/conditions')
} }
// 删除人员
export function deleteMember(data: { user_id: string; project_id: string; role_id: string; }) {
return httpRequest.post('/api/zws/v1/backend/project/member-delete', data)
}
// 新增人员
export function addMember(data?: { user_id: string; projects_id: string; roles: string; type?: string }) {
return httpRequest.post('/api/zws/v1/backend/project/member-create', data)
}
// 删除项目
export function deleteProjectRequest(data: { id: string; }) {
return httpRequest.post('/api/zws/v1/backend/project/delete', data)
}
...@@ -37,7 +37,6 @@ getProjectRoles().then((res: { data: ProjectRole[] }) => { ...@@ -37,7 +37,6 @@ getProjectRoles().then((res: { data: ProjectRole[] }) => {
// 选择完成 // 选择完成
const submit = function () { const submit = function () {
if (Object.keys(roleValue).length && userValue) { if (Object.keys(roleValue).length && userValue) {
console.log(projectRoleOption, 'projectRoleOptionprojectRoleOption', roleValue)
const data = { const data = {
userInfo: userListOption.find(item => item.id === userValue), userInfo: userListOption.find(item => item.id === userValue),
role: projectRoleOption.reduce((a: any, b) => { role: projectRoleOption.reduce((a: any, b) => {
......
...@@ -17,7 +17,7 @@ interface Props { ...@@ -17,7 +17,7 @@ interface Props {
isView?: boolean isView?: boolean
} }
const prop = defineProps<{ status?: Props }>() const prop = defineProps<Props>()
interface ProjectInfoBase { interface ProjectInfoBase {
title: string title: string
...@@ -26,6 +26,7 @@ interface ProjectInfoBase { ...@@ -26,6 +26,7 @@ interface ProjectInfoBase {
project_status: string project_status: string
project_uri: string project_uri: string
landing_page_uri: string landing_page_uri: string
project_id: string
} }
let form = reactive<ProjectInfoBase>({ let form = reactive<ProjectInfoBase>({
...@@ -34,14 +35,16 @@ let form = reactive<ProjectInfoBase>({ ...@@ -34,14 +35,16 @@ let form = reactive<ProjectInfoBase>({
project_type: '', project_type: '',
project_status: '', project_status: '',
project_uri: '', project_uri: '',
landing_page_uri: '' landing_page_uri: '',
project_id: ''
}) })
onMounted(() => { onMounted(() => {
if (prop.status?.isView || prop.status?.isUpdate) { if (prop?.isView || prop?.isUpdate) {
getProjectDetail({ id: route.params.id }).then((res: { data: ProjectInfoBase }) => { getProjectDetail({ id: route.params.id }).then((res: { data: ProjectInfoBase }) => {
form = Object.assign(form, res.data) form = Object.assign(form, res.data)
projectId.value = res.data.project_id projectId.value = res.data.project_id
window.localStorage.projectId = res.data.project_id
}) })
} }
}) })
...@@ -63,8 +66,8 @@ defineExpose({ ...@@ -63,8 +66,8 @@ defineExpose({
<template> <template>
<el-card shadow="never" header="基本信息"> <el-card shadow="never" header="基本信息">
<el-form ref="ruleFormRef" :disabled="status?.isView" :model="form" :rules="rules" label-width="140px"> <el-form ref="ruleFormRef" :disabled="prop?.isView" :model="form" :rules="rules" label-width="140px">
<el-form-item label="项目名称"> <el-form-item label="项目名称" v-if="!checkAuth('title')">
<el-input v-model="form.title" :disabled="!checkAuth('title')" /> <el-input v-model="form.title" :disabled="!checkAuth('title')" />
</el-form-item> </el-form-item>
<el-form-item label="项目别名"> <el-form-item label="项目别名">
......
<script setup lang="ts"> <script setup lang="ts">
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import { getProjectUserList } from '../api' import { getProjectUserList, deleteMember } from '../api'
import { useMap } from '../composables/useMap' import { useMap } from '../composables/useMap'
const { hasAuth } = useMap() import { ElMessage } from 'element-plus'
const { checkAuth, hasAuth, projectId } = useMap()
const AddMember = defineAsyncComponent(() => import('../components/AddMember.vue')) const AddMember = defineAsyncComponent(() => import('../components/AddMember.vue'))
const route = useRoute() const route = useRoute()
...@@ -13,7 +14,7 @@ interface Props { ...@@ -13,7 +14,7 @@ interface Props {
isView?: boolean isView?: boolean
} }
const prop = defineProps<{ status?: Props }>() const prop = defineProps<Props>()
interface User { interface User {
nickname: string nickname: string
...@@ -67,14 +68,24 @@ const changeUser = function (e: any) { ...@@ -67,14 +68,24 @@ const changeUser = function (e: any) {
} }
// 删除人员 // 删除人员
const deleteUser = function (row: any) { const deleteProjectMember = function (row: any) {
if (!prop?.isAdd) {
deleteMember({ user_id: row.user_id, role_id: row.role_id, project_id: window.localStorage.projectId }).then(() => {
ElMessage({
message: '删除成功',
type: 'success'
})
getProjectUser()
})
} else {
const index = userList.findIndex((item: any) => item.id === row.id) const index = userList.findIndex((item: any) => item.id === row.id)
userList.splice(index, 1) userList.splice(index, 1)
}
} }
// 新建时重构接口需要的数据 // 新建时重构接口需要的数据
const data = function () { const data = function () {
if (!prop.status?.isUpdate) { if (!prop?.isUpdate) {
return JSON.stringify( return JSON.stringify(
userList.reduce((a: any, b: any) => { userList.reduce((a: any, b: any) => {
a.push({ a.push({
...@@ -89,12 +100,17 @@ const data = function () { ...@@ -89,12 +100,17 @@ const data = function () {
// 详情 // 详情
onMounted(() => { onMounted(() => {
if (prop.status?.isView || prop.status?.isUpdate) { if (prop?.isView || prop?.isUpdate) {
getProjectUser()
}
})
const getProjectUser = function () {
getProjectUserList({ id: route.params.id }).then((res: { data: { list: User[] } }) => { getProjectUserList({ id: route.params.id }).then((res: { data: { list: User[] } }) => {
userList = res.data.list userList = res.data.list
projectId.value = window.localStorage.projectId
}) })
} }
})
defineExpose({ defineExpose({
data data
...@@ -105,10 +121,10 @@ defineExpose({ ...@@ -105,10 +121,10 @@ defineExpose({
<el-card shadow="never" header="成员信息"> <el-card shadow="never" header="成员信息">
<AppList v-bind="listOptions" ref="appList"> <AppList v-bind="listOptions" ref="appList">
<template #header-buttons> <template #header-buttons>
<el-button type="primary" v-if="!prop.status?.isView" @click="labelVisible = true">添加成员</el-button> <el-button v-if="prop?.isAdd" type="primary" @click="labelVisible = true">添加成员</el-button>
</template> </template>
<template #table-x="{ row }"> <template #table-x="{ row }">
<el-button text type="primary" @click="deleteUser(row)" :disabled="prop.status?.isView">删除</el-button> <el-button text type="primary" @click="deleteProjectMember(row)">删除</el-button>
</template> </template>
</AppList> </AppList>
</el-card> </el-card>
......
<script setup lang="ts"> <script setup lang="ts">
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import { getProjectList } from '../api' import { getProjectList, addMember, deleteProjectRequest } from '../api'
import { ElMessage } from 'element-plus'
import { useMap } from '../composables/useMap'
const AddMember = defineAsyncComponent(() => import('../components/AddMember.vue')) const AddMember = defineAsyncComponent(() => import('../components/AddMember.vue'))
const { types, status } = useMap()
const appList = $ref<InstanceType<typeof AppList> | null>(null) const appList = $ref<InstanceType<typeof AppList> | null>(null)
const router = useRouter()
const listOptions = $computed(() => { const listOptions = $computed(() => {
return { return {
remote: { remote: {
...@@ -20,10 +26,22 @@ const listOptions = $computed(() => { ...@@ -20,10 +26,22 @@ const listOptions = $computed(() => {
filters: [ filters: [
{ type: 'input', prop: 'project_id', placeholder: '项目编号' }, { type: 'input', prop: 'project_id', placeholder: '项目编号' },
{ type: 'input', prop: 'title', placeholder: '项目名称' }, { type: 'input', prop: 'title', placeholder: '项目名称' },
{ type: 'input', prop: 'project_uri', placeholder: '项目页' }, {
{ type: 'select', prop: 'project_type_name', placeholder: '项目类型' }, type: 'select',
{ type: 'select', prop: 'project_status_name', placeholder: '状态' }, prop: 'project_type',
{ type: 'select', prop: 'updated_time', placeholder: '更新时间' } placeholder: '项目类型',
options: types.value,
labelKey: 'name',
valueKey: 'id'
},
{
type: 'select',
prop: 'project_status',
placeholder: '状态',
options: status.value,
labelKey: 'name',
valueKey: 'id'
}
] ]
} }
}) })
...@@ -49,12 +67,68 @@ function toggleSelection() { ...@@ -49,12 +67,68 @@ function toggleSelection() {
appList?.tableRef.clearSelection() appList?.tableRef.clearSelection()
} }
let multipleSelection = $ref([]) let multipleSelection = $ref<{ project_id: string }[]>([])
function handleSelectionChange(value: any) { function handleSelectionChange(value: any) {
multipleSelection = value multipleSelection = value
} }
const labelVisible = $ref(false) let labelVisible = $ref(false)
const addProjectMember = function () {
labelVisible = true
multipleSelection = []
}
// 选择人员
// 多项目角色确认弹窗
let memberRoleVisible = $ref(false)
let changeMemberName = $ref('')
let paramsMember = $ref<{ user_id: string; projects_id: string; roles: string; type?: string }>()
const changeMember = function (e: any) {
paramsMember = {
user_id: e.userInfo.id,
projects_id: multipleSelection.reduce((a: any, b: any) => a.push(b.project_id) && a, []).toString(),
roles: e.role.reduce((a: any, b: any) => a.push(b.id) && a, []).toString()
}
changeMemberName = e.userInfo.nickname
addMemberRequest()
}
const addMemberRequest = function (n?: string) {
let params = paramsMember
if (n) {
params = Object.assign(paramsMember, { type: n })
}
addMember(params).then((res: any) => {
if (res.code === 0) {
ElMessage({
message: '添加成功',
type: 'success'
})
router.go(0)
}
if (res.code === 2) {
memberRoleVisible = true
}
})
}
// 列表上的添加成员
const aloneAddMember = function (row: { project_id: string }) {
multipleSelection = [row]
labelVisible = true
}
// 删除项目
const deleteProject = function (row: { id: string }) {
deleteProjectRequest({ id: row.id }).then(() => {
ElMessage({
message: '删除成功',
type: 'success'
})
appList?.refetch()
})
}
</script> </script>
<template> <template>
...@@ -64,9 +138,7 @@ const labelVisible = $ref(false) ...@@ -64,9 +138,7 @@ const labelVisible = $ref(false)
<el-button type="primary"><router-link :to="{ name: 'projectCreate' }">创建项目</router-link></el-button> <el-button type="primary"><router-link :to="{ name: 'projectCreate' }">创建项目</router-link></el-button>
<el-button type="primary" @click="toggleSelection" v-if="!selectionVisible">添加成员</el-button> <el-button type="primary" @click="toggleSelection" v-if="!selectionVisible">添加成员</el-button>
<template v-else> <template v-else>
<el-button type="primary" :disabled="!multipleSelection.length" @click="labelVisible = true" <el-button type="primary" :disabled="!multipleSelection.length" @click="addProjectMember">选择成员</el-button>
>选择成员</el-button
>
<el-button type="primary" @click="toggleSelection">取消</el-button> <el-button type="primary" @click="toggleSelection">取消</el-button>
</template> </template>
</template> </template>
...@@ -77,10 +149,22 @@ const labelVisible = $ref(false) ...@@ -77,10 +149,22 @@ const labelVisible = $ref(false)
<el-button text style="--el-button-text-color: #3276fc"> <el-button text style="--el-button-text-color: #3276fc">
<router-link :to="{ name: 'projectUpdate', params: { id: row.id } }">编辑</router-link> <router-link :to="{ name: 'projectUpdate', params: { id: row.id } }">编辑</router-link>
</el-button> </el-button>
<el-button text style="--el-button-text-color: #00bfbf">添加成员</el-button> <el-button text style="--el-button-text-color: #00bfbf" @click="aloneAddMember(row)">添加成员</el-button>
<el-button text style="--el-button-text-color: #d9001b">删除</el-button> <el-button text style="--el-button-text-color: #d9001b" @click="deleteProject(row)">删除</el-button>
</template> </template>
</AppList> </AppList>
<AddMember v-model="labelVisible"></AddMember> <AddMember @changeUser="changeMember" v-model="labelVisible"></AddMember>
</AppCard> </AppCard>
<el-dialog v-model="memberRoleVisible" title="提示">
<el-form>
<el-form-item label="系统检测到:"> {{ changeMemberName }}在多个项目中已拥有角色 </el-form-item>
<el-form-item label="请选择:">
<el-button @click="addMemberRequest('replace')">全部替换为新角色</el-button>
<el-button @click="addMemberRequest('insert')">在已有角色中新增角色</el-button>
</el-form-item>
<el-form-item label="或者:">
<el-button @click="memberRoleVisible = false">取消本次更新</el-button>
</el-form-item>
</el-form>
</el-dialog>
</template> </template>
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
import InfoBase from '../components/InfoBase.vue' import InfoBase from '../components/InfoBase.vue'
import InfoUsers from '../components/InfoUsers.vue' import InfoUsers from '../components/InfoUsers.vue'
import { createProject, updateProject } from '../api' import { createProject, updateProject } from '../api'
import { ElMessage } from 'element-plus'
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
...@@ -35,10 +36,18 @@ const onSubmit = function () { ...@@ -35,10 +36,18 @@ const onSubmit = function () {
const params = Object.assign(infoBase.form, { members: infoUsers.data() }) const params = Object.assign(infoBase.form, { members: infoUsers.data() })
if (props.isAdd) { if (props.isAdd) {
createProject(params).then((res: any) => { createProject(params).then((res: any) => {
ElMessage({
message: '创建成功',
type: 'success'
})
router.go(-1) router.go(-1)
}) })
} else { } else {
updateProject(Object.assign(params, { id: route.params.id })).then((res: any) => { updateProject(Object.assign(params, { id: route.params.id })).then((res: any) => {
ElMessage({
message: '更新成功',
type: 'success'
})
router.go(-1) router.go(-1)
}) })
} }
...@@ -48,8 +57,8 @@ const onSubmit = function () { ...@@ -48,8 +57,8 @@ const onSubmit = function () {
<template> <template>
<AppCard :title="title"> <AppCard :title="title">
<InfoBase :status="props" ref="infoBase" style="margin: 20px 0"></InfoBase> <InfoBase v-bind="props" ref="infoBase" style="margin: 20px 0"></InfoBase>
<InfoUsers :status="props" ref="infoUsers"></InfoUsers> <InfoUsers v-bind="props" ref="infoUsers"></InfoUsers>
<el-button v-if="!props?.isView" @click="onSubmit" style="margin: 20px auto; display: block" type="primary" <el-button v-if="!props?.isView" @click="onSubmit" style="margin: 20px auto; display: block" type="primary"
>提交</el-button >提交</el-button
> >
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论