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

chore: update

上级 e8f20cdf
差异被折叠。
......@@ -18,6 +18,7 @@
"axios": "^1.2.1",
"blueimp-md5": "^2.19.0",
"element-plus": "^2.2.26",
"lodash-es": "^4.17.21",
"pinia": "^2.0.28",
"qs": "^6.11.0",
"vue": "^3.2.45",
......@@ -37,8 +38,8 @@
"eslint-plugin-vue": "^9.8.0",
"sass": "^1.56.2",
"typescript": "~4.9.4",
"unplugin-auto-import": "^0.12.0",
"vite": "^4.0.0",
"vue-tsc": "^1.0.12"
"unplugin-auto-import": "^0.12.1",
"vite": "^4.0.1",
"vue-tsc": "^1.0.13"
}
}
......@@ -21,16 +21,15 @@ export function getSignature() {
}
// 图片上传
export function uploadFile(data: Record<string, any>) {
return httpRequest
.post('https://webapp-pub.oss-cn-beijing.aliyuncs.com', data, {
withCredentials: false,
headers: { 'Content-Type': 'multipart/form-data' }
})
.then(() => data)
export async function uploadFile(data: Record<string, any>) {
await httpRequest.post('https://webapp-pub.oss-cn-beijing.aliyuncs.com', data, {
withCredentials: false,
headers: { 'Content-Type': 'multipart/form-data' }
})
return data
}
// 获取项目公共map
export function getProjectMap() {
return httpRequest.get('/api/zws/v1/backend/project/conditions')
}
\ No newline at end of file
// 搜索用户
export function searchUser(params: { q: string }) {
return httpRequest.get('/api/zws/v1/backend/common/search-user', { params })
}
<script setup lang="ts">
import type { SearchUser } from '@/types'
import { searchUser } from '@/api/base'
let loading = $ref(false)
let userList = $ref<SearchUser[]>()
const remoteMethod = (q: string) => {
if (!q) return
loading = true
searchUser({ q: q }).then(res => {
loading = false
userList = res.data
})
}
</script>
<template>
<el-select
remote
filterable
reserve-keyword
value-key="id"
placeholder="查找用户"
remote-show-suffix
:loading="loading"
:remote-method="remoteMethod"
style="width: 100%">
<el-option
v-for="item in userList"
:key="item.id"
:label="item.realname || item.nickname || item.username"
:value="item">
<span>{{ item.realname || item.nickname || item.username }}</span>
<template v-if="item.mobile">
<el-divider direction="vertical" />
<span>{{ item.mobile }}</span>
</template>
<template v-if="item.email">
<el-divider direction="vertical" />
<span>{{ item.email }}</span>
</template>
</el-option>
</el-select>
</template>
import httpRequest from '@/utils/axios'
import type { ChannelRequestParams, ChannelListSearch } from './types'
// https://gitlab.ezijing.com/root/api-documents/-/blob/master/%E6%96%B0%E7%9A%84zws%E7%B3%BB%E7%BB%9F/%E6%B8%A0%E9%81%93%E7%AE%A1%E7%90%86.md
// 获取渠道相关的公共map
export function getChannelMap() {
return httpRequest.get('/api/zws/v1/backend/channel/conditions')
}
// 获取渠道角色
export function getRoles() {
return httpRequest.get('/api/zws/v1/backend/common/channel-roles')
}
// 获取渠道列表
export function getChannelList(params?: ChannelListSearch) {
return httpRequest.get('/api/zws/v1/backend/channel/list', { params })
}
// 获取渠道详情
export function getChannelDetail(params?: { id?: string | string[] }) {
export function getChannelDetail(params: { id: string }) {
return httpRequest.get('/api/zws/v1/backend/channel/view', { params })
}
// 创建渠道
export function createChannel(data: ChannelRequestParams) {
return httpRequest.post('/api/zws/v1/backend/channel/create', data)
}
// 更新渠道
export function updateChannel(data: { id: string } & ChannelRequestParams) {
return httpRequest.post('/api/zws/v1/backend/channel/update', data)
}
// 获取成员列表
export function getChannelUserList(params?: { id?: string | string[] }) {
export function getMemberList(params: { id: string; 'per-page'?: number; page?: number }) {
return httpRequest.get('/api/zws/v1/backend/channel/member', { params })
}
......@@ -26,27 +48,22 @@ export function deleteMember(data: { user_id: string; channel_id: string; role_i
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 getProjectList(params: { id: string; 'per-page'?: number; page?: number }) {
return httpRequest.get('/api/zws/v1/backend/channel/project', { params })
}
// 搜索用户
export function searchUser(params: { q: string }) {
return httpRequest.get('/api/zws/v1/backend/common/search-user', { params })
// 新增渠道项目
export function addProject(data: any) {
return httpRequest.post('/api/zws/v1/backend/channel/project-create', data)
}
// 获取渠道角色
export function getRoles() {
return httpRequest.get('/api/zws/v1/backend/common/channel-roles')
// 更新渠道项目
export function updateProject(data: any) {
return httpRequest.post('/api/zws/v1/backend/channel/project-update', data)
}
// 创建渠道
export function createChannel(data: ChannelRequestParams) {
return httpRequest.post('/api/zws/v1/backend/channel/create', data)
}
// 更新渠道
export function updateChannel(data: { id: string } & ChannelRequestParams) {
return httpRequest.post('/api/zws/v1/backend/channel/update', data)
// 删除渠道项目
export function deleteProject(data: { id: string; contract_id: string }) {
return httpRequest.post('/api/zws/v1/backend/channel/project-delete', data)
}
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import type { User, Role } from '../types'
import { searchUser, getRoles } from '../api'
import SelectUser from '@/components/SelectUser.vue'
import { getRoles } from '../api'
interface FormData {
user: User
......@@ -19,17 +20,6 @@ const rules = reactive<FormRules>({
role: { type: 'array', required: true, message: '请选择角色', trigger: 'change' }
})
let userList = $ref<User[]>()
let loading = $ref(false)
const remoteMethod = (q: string) => {
if (!q) return
loading = true
searchUser({ q }).then(res => {
loading = false
userList = res.data
})
}
let roleList = $ref<Role[]>()
function fetchRoles() {
getRoles().then((res: { data: Role[] }) => {
......@@ -42,7 +32,7 @@ onMounted(() => {
// 选择完成
function submit() {
formRef?.validate(() => {
formRef?.validate().then(() => {
emit('submit', form as FormData)
})
}
......@@ -56,22 +46,7 @@ function submit() {
@update:modelValue="$emit('update:modelValue')">
<el-form :rules="rules" :model="form" hide-required-asterisk ref="formRef">
<el-form-item label="选择成员" prop="user">
<el-select
v-model="form.user"
filterable
remote
reserve-keyword
placeholder="请输入"
:remote-method="remoteMethod"
:loading="loading"
value-key="id"
style="width: 100%">
<el-option
v-for="item in userList"
:key="item.id"
:label="item.mobile ? `${item.nickname}(${item.mobile}})` : item.nickname"
:value="item" />
</el-select>
<SelectUser v-model="form.user"></SelectUser>
</el-form-item>
<el-form-item label="选择角色" prop="role">
<el-select v-model="form.role" multiple placeholder="请选择" value-key="id" style="width: 100%">
......
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import type { SearchUser } from '@/types'
import AppUpload from '@/components/base/AppUpload.vue'
import SelectUser from '@/components/SelectUser.vue'
import { useMap } from '../composables/useMap'
import { pickBy } from 'lodash-es'
const { options } = await useMap()
const props = defineProps<{ data?: any }>()
const emit = defineEmits<{
(e: 'update:modelValue', modelValue: boolean): void
(e: 'submit', data: any): void
}>()
const formRef = $ref<FormInstance>()
const form = reactive({
project_id: '',
project_id_name: '',
conversion_type: '',
type: '',
location_limit: '',
unpaid_list_limit: '',
expire_month: 0,
follower_user_id: '',
follower_user_id_name: '',
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: ''
})
watchEffect(() => {
if (props.data) {
Object.assign(form, props.data)
}
})
const rules = reactive<FormRules>({
project_id: [{ required: true, message: '请选择' }],
conversion_type: [{ required: true, message: '请选择' }],
type: [{ required: true, message: '请选择' }],
follower_user_id_name: [{ required: true, message: '请选择' }],
division_rule: [{ required: true, message: '请输入' }],
division_proportion: [{ required: true, message: '请输入' }]
})
// 渠道归属人
function handleChangeUser(user: SearchUser) {
form.follower_user_id = user.id
form.follower_user_id_name = user.realname || user.nickname || user.username
}
// 选择完成
function submit() {
formRef?.validate().then(() => {
const temp = {
...form,
project_id_name: options.value.projects.find(item => item.project_id === form.project_id)?.title,
conversion_type_name: options.value.contractConversionType.find(item => item.id === form.conversion_type)?.name,
division_rule_name: options.value.contractDivisionRuleType.find(item => item.id === form.division_rule)?.name,
division_proportion_name: form.division_proportion ?? form.division_proportion + '%'
}
emit('submit', pickBy(temp))
})
}
</script>
<template>
<el-dialog
title="关联项目"
width="1000px"
:close-on-click-modal="false"
@update:modelValue="$emit('update:modelValue')">
<el-form :model="form" :rules="rules" label-position="top" ref="formRef">
<el-row :gutter="40">
<el-col :span="6">
<el-form-item label="项目名称" prop="project_id">
<el-select v-model="form.project_id" placeholder="请选择" style="width: 100%">
<el-option
v-for="item in options.projects"
:key="item.project_id"
:label="item.title"
:value="item.project_id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="转化类型" prop="conversion_type">
<el-select v-model="form.conversion_type" placeholder="请选择" style="width: 100%">
<el-option
v-for="item in options.contractConversionType"
:key="item.id"
:label="item.name"
:value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="合同类型" prop="type">
<el-select v-model="form.type" placeholder="请选择" style="width: 100%">
<el-option v-for="item in options.contractType" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="代理地域">
<el-input v-model="form.location_limit" :rows="2" type="input" placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="40">
<el-col :span="6">
<el-form-item label="学员上线">
<el-input v-model="form.unpaid_list_limit" :rows="2" type="input" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="有效期(月)">
<el-input-number v-model="form.expire_month" :min="1" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="跟进人" prop="follower_user_id_name">
<SelectUser :model-value="form.follower_user_id_name" @change="handleChangeUser"></SelectUser>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="分成规则" prop="division_rule">
<el-select v-model="form.division_rule" placeholder="请选择" style="width: 100%">
<el-option
v-for="item in options.contractDivisionRuleType"
:key="item.id"
:label="item.name"
:value="item.id" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="40">
<el-col :span="6">
<el-form-item label="统一分成比例(%)" prop="division_proportion">
<el-input v-model="form.division_proportion" type="input" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="有效期开始时间">
<el-date-picker v-model="form.expire_range_month_start" type="date" placeholder="请选择" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="有效期结束时间">
<el-date-picker v-model="form.expire_range_month_end" type="date" placeholder="请选择" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="合同">
<AppUpload v-model="form.upload"></AppUpload>
</el-form-item>
<template v-if="false">
<el-form-item label="二级渠道商">
<SelectUser></SelectUser>
</el-form-item>
<el-form-item label="二级渠道分成方式">
<el-select v-model="form.secondary_division_type" placeholder="请选择">
<el-option
v-for="item in options.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 options.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="二级渠道合同">
<AppUpload v-model="form.upload"></AppUpload>
</el-form-item>
</template>
</el-form>
<el-row justify="center">
<el-button auto-insert-space @click="$emit('update:modelValue', false)">取消</el-button>
<el-button type="primary" auto-insert-space @click="submit">确定</el-button>
</el-row>
</el-dialog>
</template>
<script setup lang="ts">
import type { ChannelFormData } from '../types'
import { provideForm } from '../util'
import { searchUser } from '../api'
import { useMap } from '../composables/useMap'
const { options } = await useMap()
const form = inject(provideForm) as ChannelFormData
// 用户搜索
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>
<el-card shadow="never" header="协议信息" style="margin-top: 20px">
<el-row :gutter="40">
<el-col :span="6">
<el-form-item label="联络人" prop="partner.contact_person">
<el-select
v-model="form.partner.contact_person"
filterable
remote
reserve-keyword
placeholder="请输入"
:remote-method="remoteMethod"
:loading="loading"
style="width: 100%">
<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
label="联络人"
prop="partner.contact_person"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<el-input v-model="form.partner.contact_person" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="联络电话" prop="contact_phone">
<el-form-item
label="联络电话"
prop="partner.contact_phone"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<el-input v-model="form.partner.contact_phone" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="联络邮箱" prop="contact_email">
<el-form-item
label="联络邮箱"
prop="partner.contact_email"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<el-input v-model="form.partner.contact_email" placeholder="请输入" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="服务电话">
<el-input v-model="form.partner.channel_tax_rate" placeholder="请输入" />
<el-input v-model="form.partner.contact_wechat" placeholder="请输入" />
</el-form-item>
</el-col>
</el-row>
......
<script setup lang="ts">
import type { FormRules } from 'element-plus'
import type { SearchUser } from '@/types'
import type { ChannelFormData } from '../types'
import { provideForm } from '../util'
import { searchUser } from '../api'
import { useMap } from '../composables/useMap'
import SelectUser from '@/components/SelectUser.vue'
const { options } = await useMap()
......@@ -15,22 +16,15 @@ const rules = reactive<FormRules>({
channel_status: [{ required: true, message: '请选择', trigger: 'change' }]
})
// 用户搜索
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
})
// 渠道归属人
watchEffect(() => {
if (form.channel_owner_user_id_name) {
user = form.channel_owner_user_id_name
}
})
let user = $ref<SearchUser | string>()
function handleChangeUser(user: SearchUser) {
form.channel_owner_user_id = user.id
}
</script>
......@@ -49,27 +43,13 @@ const remoteMethod = (q: string) => {
</el-col>
<el-col :span="4">
<el-form-item label="渠道归属人" prop="channel_owner_user_id" :rules="rules.channel_owner_user_id">
<el-select
v-model="form.channel_owner_user_id"
filterable
remote
reserve-keyword
placeholder="请输入"
:remote-method="remoteMethod"
:loading="loading"
style="width: 100%">
<el-option
v-for="item in userListOption"
:key="item.id"
:label="item.mobile ? `${item.nickname}(${item.mobile}})` : item.nickname"
:value="item.id" />
</el-select>
<SelectUser v-model="user" @change="handleChangeUser"></SelectUser>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="渠道标签">
<el-select v-model="form.tags" placeholder="请选择" multiple style="width: 100%">
<!-- <el-option v-for="item in prop.channelTags" :key="item" :label="item" :value="item" /> -->
<el-select v-model="form.tags" placeholder="请选择" multiple collapse-tags style="width: 100%">
<el-option v-for="item in options.channelTags" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
......
......@@ -48,7 +48,10 @@ const form = inject(provideForm) as ChannelFormData
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="联络邮箱" prop="contact_email">
<el-form-item
label="联络邮箱"
prop="partner.contact_email"
:rules="[{ required: true, message: '请输入', trigger: 'blur' }]">
<el-input v-model="form.partner.contact_email" placeholder="请输入" />
</el-form-item>
</el-col>
......
<script setup lang="ts">
import type { ChannelFormData, ChannelMember, User, Role } from '../types'
import AppList from '@/components/base/AppList.vue'
import { getChannelUserList, addMember, deleteMember } from '../api'
import { getMemberList, addMember, deleteMember } from '../api'
import { useMap } from '../composables/useMap'
import { ElMessage } from 'element-plus'
import { provideForm } from '../util'
import { useNow, useDateFormat } from '@vueuse/core'
const { hasAuth, projectId } = await useMap()
const { hasAuth, channelId } = await useMap()
const AddMember = defineAsyncComponent(() => import('./AddMember.vue'))
const props = defineProps<{ id?: string }>()
const route = useRoute()
const isAdd = $computed(() => !route.params.id)
const pid = $computed(() => {
return props.id || (route.params.id as string)
})
const isAdd = $computed(() => !pid)
const form = inject(provideForm) as ChannelFormData
watchEffect(() => {
if (form.project_id) {
projectId.value = form.project_id
if (form.channel_id) {
channelId.value = form.channel_id
}
})
const appList = $ref<InstanceType<typeof AppList> | null>(null)
const listOptions = $computed(() => {
return {
remote: !isAdd ? { httpRequest: getChannelUserList, params: { id: route.params.id } } : {},
remote: !isAdd ? { httpRequest: getMemberList, params: { id: pid } } : {},
columns: [
{ label: '姓名', prop: 'name' },
{ label: '手机号', prop: 'mobile' },
......@@ -55,7 +59,7 @@ const handleSubmitMember = function (data: { user: User; role: Role[] }) {
} else {
const params = {
user_id: data.user.id,
projects_id: form.project_id,
channels_id: form.channel_id,
roles: data.role.map(item => item.id).join(',')
}
addMember(params).then(() => {
......@@ -71,7 +75,7 @@ function handleDelete(row: ChannelMember, index: number) {
if (isAdd) {
form.members.splice(index, 1)
} else {
deleteMember({ user_id: row.user_id, role_id: row.role_id, project_id: form.project_id }).then(() => {
deleteMember({ user_id: row.user_id, role_id: row.role_id, channel_id: form.channel_id }).then(() => {
ElMessage({ message: '删除成功', type: 'success' })
appList?.refetch()
})
......@@ -83,12 +87,12 @@ function handleDelete(row: ChannelMember, index: number) {
<el-card shadow="never" header="成员信息" style="margin-top: 20px">
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-button type="primary" @click="memberVisible = true" v-if="hasAuth('project-member-create')">
<el-button type="primary" @click="memberVisible = true" v-if="hasAuth('channel-member-create')">
添加成员
</el-button>
</template>
<template #table-x="{ row, $index }">
<el-button text type="primary" @click="handleDelete(row, $index)" v-if="hasAuth('project-member-delete')">
<el-button text type="danger" @click="handleDelete(row, $index)" v-if="hasAuth('channel-member-delete')">
删除
</el-button>
</template>
......
<script setup lang="ts">
import type { ChannelFormData, ChannelProject } from '../types'
import AppList from '@/components/base/AppList.vue'
import { getProjectList, addProject, updateProject, deleteProject } from '../api'
import { useMap } from '../composables/useMap'
import { ElMessage } from 'element-plus'
import { provideForm } from '../util'
import { useNow, useDateFormat } from '@vueuse/core'
const { hasAuth, channelId } = await useMap()
const AddProject = defineAsyncComponent(() => import('./AddProject.vue'))
const props = defineProps<{ id?: string }>()
const route = useRoute()
const pid = $computed(() => {
return props.id || (route.params.id as string)
})
const isAdd = $computed(() => !pid)
const form = inject(provideForm) as ChannelFormData
watchEffect(() => {
if (form.channel_id) {
channelId.value = form.channel_id
}
})
const appList = $ref<InstanceType<typeof AppList> | null>(null)
const listOptions = $computed(() => {
return {
remote: !isAdd ? { httpRequest: getProjectList, params: { id: pid } } : {},
columns: [
{ label: '项目名称', prop: 'project_id_name' },
{ label: '分成规则', prop: 'division_rule_name' },
{ label: '分成比例', prop: 'division_proportion_name' },
{ label: '学员上限', prop: 'unpaid_list_limit' },
{ label: '有效期', prop: 'expire_range' },
{ label: '跟进人', prop: 'follower_user_id_name' },
{ label: '关联日期', prop: 'updated_time' },
{ label: '操作', prop: 'name', slots: 'table-x', width: 120 }
],
data: form.projects
}
})
let dialogVisible = $ref(false)
// 项目确定
const handleSubmit = function (data: ChannelProject) {
currentRow ? handleUpdateSubmit(data) : handleAddSubmit(data)
}
// 添加
function handleAdd() {
currentRow = undefined
dialogVisible = true
}
function handleAddSubmit(data: ChannelProject) {
if (isAdd) {
const formatted = useDateFormat(useNow(), 'YYYY-MM-DD HH:mm:ss')
const temp = { ...data, updated_time: formatted.value }
form.projects.unshift(temp)
dialogVisible = false
} else {
const params = { ...data, id: pid }
addProject(params).then(() => {
dialogVisible = false
ElMessage({ message: '添加成功', type: 'success' })
appList?.refetch()
})
}
}
// 编辑
let currentIndex = $ref(0)
let currentRow = $ref<ChannelProject>()
function handleUpdate(row: ChannelProject, index: number) {
currentRow = row
currentIndex = index
dialogVisible = true
}
function handleUpdateSubmit(data: ChannelProject) {
if (isAdd) {
form.projects.splice(currentIndex, 1, data)
dialogVisible = false
} else {
const params = { ...data, contract_id: data.id, id: pid }
updateProject(params).then(() => {
dialogVisible = false
ElMessage({ message: '更新成功', type: 'success' })
appList?.refetch()
})
}
}
// 删除项目
function handleDelete(row: ChannelProject, index: number) {
if (isAdd) {
form.projects.splice(index, 1)
} else {
deleteProject({ id: pid, contract_id: row.id }).then(() => {
ElMessage({ message: '删除成功', type: 'success' })
appList?.refetch()
})
}
}
</script>
<template>
<el-card shadow="never" header="项目信息" style="margin-top: 20px">
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-button type="primary" @click="handleAdd" v-if="hasAuth('channel-project-create')"> 关联项目 </el-button>
</template>
<template #table-x="{ row, $index }">
<el-button
text
style="--el-button-text-color: #3276fc"
@click="handleUpdate(row, $index)"
v-if="hasAuth('channel-project-delete')">
编辑
</el-button>
<el-button text type="danger" @click="handleDelete(row, $index)" v-if="hasAuth('channel-project-delete')">
删除
</el-button>
</template>
</AppList>
</el-card>
<AddProject v-model="dialogVisible" :data="currentRow" @submit="handleSubmit" v-if="dialogVisible"></AddProject>
</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>
......@@ -29,6 +29,7 @@ const options = ref<{
contractSecondaryDivisionType: State[]
agreementType: State[]
channelTaxRate: State[]
projects: { project_id: string; title: string }[]
}>({
channelType: [],
channelQuality: [],
......@@ -42,7 +43,8 @@ const options = ref<{
contractDivisionRuleType: [],
contractSecondaryDivisionType: [],
agreementType: [],
channelTaxRate: []
channelTaxRate: [],
projects: []
})
// 领导
......@@ -67,7 +69,8 @@ export async function useMap() {
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 || []
channelTaxRate: data.channel_tax_rate_map || [],
projects: data.projects || []
}
authList.value = data.channel_auth_map || []
tags.value = data.tags || {}
......
......@@ -12,7 +12,6 @@ export interface ChannelListSearch {
}
export interface ChannelRequestParams {
channel_id: string
channel_type: string
title: string
service_phone: string
......@@ -25,6 +24,7 @@ export interface ChannelRequestParams {
distribution_status: string
case_withdraw_status: string
service_dialog_status: string
partner: any
leaders_id: string
members?: string
projects?: string
......@@ -41,9 +41,52 @@ export interface ChannelMember {
role_name: string
}
// 渠道项目
export interface ChannelProject {
id: string
partner_profile_id: string
project_id: string
type: string
conversion_type: string
division_proportion: string
location_limit: string
unpaid_list_limit: string
contract_document: string
contract_signature_time: string
follower_user_id: string
expire_month: string
comment: string
status: string
operator: string
created_time: string
updated_time: string
expire_range_month_start: string
expire_range_month_end: string
division_rule: string
secondary_channel_id: string
secondary_division_type: string
secondary_division_rule: string
secondary_division_proportion: string
secondary_contract_document: string
project_id_name: string
division_rule_name: string
division_proportion_name: string
expire_range: string
follower_user_id_name: null
conversion_type_name: string
type_name: string
secondary_channel_id_name: string
secondary_division_type_name: string
secondary_division_rule_name: string
secondary_division_proportion_name: string
}
export type ChannelFormData = Omit<ChannelRequestParams, 'members' | 'projects'> & {
tags: string[]
channel_id: string
channel_owner_user_id_name: string
members: ChannelMember[]
partner: any
projects: ChannelProject[]
}
// 用户信息
......
......@@ -55,7 +55,9 @@ const listOptions = $computed(() => {
type: 'select',
prop: 'distribution_status',
placeholder: '分配状态',
options: options.value.distributionStatus
options: options.value.distributionStatus,
labelKey: 'name',
valueKey: 'id'
},
{
type: 'select',
......@@ -68,7 +70,7 @@ const listOptions = $computed(() => {
})
const columns = $computed(() => {
const columns: Record<string, any>[] = [
{ label: '渠道编号', prop: 'channel_id' },
{ label: '渠道编号', prop: 'channel_id', width: 100 },
{ label: '渠道名称', prop: 'title' },
{
label: '渠道标签',
......@@ -84,7 +86,7 @@ const columns = $computed(() => {
{ 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: 220 }
]
if (selectionVisible) columns.unshift({ type: 'selection' })
return columns
......@@ -105,10 +107,6 @@ function handleSelectionChange(value: any) {
const labelVisible = $ref(false)
let currentRow = $ref()
// 添加成员
function handleUser(row: any) {
currentRow = row
}
// 二维码
let qrcodeVisible = $ref(false)
function handleQRCode(row: any) {
......@@ -145,7 +143,6 @@ function handleRemove(row: any) {
>编辑</router-link
>
</el-button>
<el-button text style="--el-button-text-color: #00bfbf" @click="handleUser(row)">添加成员</el-button>
<el-button text style="--el-button-text-color: #f59a23" @click="handleQRCode(row)">二维码</el-button>
<el-button text style="--el-button-text-color: #d9001b" @click="handleRemove(row)">删除</el-button>
</template>
......
......@@ -8,12 +8,12 @@ import InfoCompany from '../components/InfoCompany.vue'
import InfoAgreement from '../components/InfoAgreement.vue'
import InfoControl from '../components/InfoControl.vue'
import InfoMember from '../components/InfoMember.vue'
import Project from '../components/Project.vue'
import InfoProject from '../components/InfoProject.vue'
import Leaders from '../components/Leaders.vue'
import { createChannel, updateChannel, getChannelDetail } from '../api'
import { provideForm } from '../util'
const { options } = await useMap()
const { options, channelId, hasAuth } = await useMap()
interface Props {
id?: string
......@@ -38,7 +38,7 @@ const form: ChannelFormData = reactive({
service_phone: '',
channel_owner_user_id: '',
channel_status: '',
tags: '',
tags: [],
summary: '',
comment: '',
channel_quality: '',
......@@ -51,7 +51,11 @@ const form: ChannelFormData = reactive({
projects: []
})
provide(provideForm, form)
watchEffect(() => {
if (form.channel_id) {
channelId.value = form.channel_id
}
})
// 获取基本信息
function fetchInfo() {
if (!props.id) return
......@@ -90,7 +94,12 @@ function handleSubmitRequest() {
const members = form.members.map(item => {
return { user_id: item.user_id, roles: item.role_id }
})
const params = { ...form, members: JSON.stringify(members) }
const params = {
...form,
tags: form.tags.join(','),
members: JSON.stringify(members),
projects: JSON.stringify(form.projects)
}
if (props.action === 'add') handleAdd(params)
if (props.action === 'update') handleUpdate(params)
}
......@@ -112,23 +121,19 @@ function handleUpdate(params: ChannelRequestParams) {
<template>
<AppCard :title="title">
<el-form label-suffix=":" size="large">
<el-row :gutter="40">
<el-col :span="6">
<el-form-item label="渠道类型">
<el-select v-model="form.channel_type" placeholder="请选择" style="width: 100%">
<el-option v-for="item in options.channelType" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6" v-if="props.id">
<el-form-item label="渠道编号">
<el-input v-model="form.channel_id" disabled />
</el-form-item>
</el-col>
<el-form size="large" :disabled="action === 'view'">
<el-row justify="space-between">
<el-form-item label="渠道类型">
<el-select v-model="form.channel_type" placeholder="请选择" :disabled="action === 'update'">
<el-option v-for="item in options.channelType" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="渠道编号" v-if="props.id">
<el-input v-model="form.channel_id" disabled />
</el-form-item>
</el-row>
</el-form>
<el-form :model="form" label-position="top" label-suffix=":" ref="formRef">
<el-form scroll-to-error :model="form" label-position="top" :disabled="action === 'view'" ref="formRef">
<!-- 基本信息 -->
<InfoBase></InfoBase>
<!-- 公司信息 -->
......@@ -138,13 +143,10 @@ function handleUpdate(params: ChannelRequestParams) {
<!-- 协议信息 -->
<InfoAgreement v-if="form.channel_type === '3'"></InfoAgreement>
</el-form>
<!-- 项目信息 -->
<InfoProject v-if="action !== 'update' && hasAuth('channel-member')"></InfoProject>
<!-- 成员信息 -->
<InfoMember></InfoMember>
<!-- 关联项目 -->
<!-- <Project></Project> -->
<!-- 选择管理人员 -->
<Leaders v-model="leaderVisible" @submit="handleSubmitLeader"></Leaders>
<InfoMember v-if="action !== 'update' && hasAuth('channel-member')"></InfoMember>
<el-row justify="center" style="margin-top: 40px">
<template v-if="action === 'view'">
<el-button auto-insert-space @click="handleCancel">关闭</el-button>
......@@ -154,5 +156,7 @@ function handleUpdate(params: ChannelRequestParams) {
<el-button type="primary" auto-insert-space @click="handleSubmit">提交</el-button>
</template>
</el-row>
<!-- 选择管理人员 -->
<Leaders v-model="leaderVisible" @submit="handleSubmitLeader"></Leaders>
</AppCard>
</template>
import httpRequest from '@/utils/axios'
import type { ProjectRequestParams } from './types'
// https://gitlab.ezijing.com/root/api-documents/-/blob/master/%E6%96%B0%E7%9A%84zws%E7%B3%BB%E7%BB%9F/%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86.md
// 获取列表
export function getProjectList(params?: {
project_id?: string
......@@ -13,11 +15,6 @@ export function getProjectList(params?: {
return httpRequest.get('/api/zws/v1/backend/project/list', { params })
}
// 搜索用户
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')
......
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import type { User, Role } from '../types'
import { searchUser, getProjectRoles } from '../api'
import { getProjectRoles } from '../api'
import SelectUser from '@/components/SelectUser.vue'
interface FormData {
user: User
......@@ -19,17 +20,6 @@ const rules = reactive<FormRules>({
role: { type: 'array', required: true, message: '请选择角色', trigger: 'change' }
})
let userList = $ref<User[]>()
let loading = $ref(false)
const remoteMethod = (q: string) => {
if (!q) return
loading = true
searchUser({ q }).then(res => {
loading = false
userList = res.data
})
}
let roleList = $ref<Role[]>()
function fetchRoles() {
getProjectRoles().then((res: { data: Role[] }) => {
......@@ -42,7 +32,7 @@ onMounted(() => {
// 选择完成
function submit() {
formRef?.validate(() => {
formRef?.validate().then(() => {
emit('submit', form as FormData)
})
}
......@@ -56,22 +46,7 @@ function submit() {
@update:modelValue="$emit('update:modelValue')">
<el-form :rules="rules" :model="form" hide-required-asterisk ref="formRef">
<el-form-item label="选择成员" prop="user">
<el-select
v-model="form.user"
filterable
remote
reserve-keyword
placeholder="请输入"
:remote-method="remoteMethod"
:loading="loading"
value-key="id"
style="width: 100%">
<el-option
v-for="item in userList"
:key="item.id"
:label="item.mobile ? `${item.nickname}(${item.mobile}})` : item.nickname"
:value="item" />
</el-select>
<SelectUser v-model="form.user"></SelectUser>
</el-form-item>
<el-form-item label="选择角色" prop="role">
<el-select v-model="form.role" multiple placeholder="请选择" value-key="id" style="width: 100%">
......
......@@ -10,8 +10,12 @@ import { useNow, useDateFormat } from '@vueuse/core'
const { hasAuth, projectId } = await useMap()
const AddMember = defineAsyncComponent(() => import('../components/AddMember.vue'))
const props = defineProps<{ id?: string }>()
const route = useRoute()
const isAdd = $computed(() => !route.params.id)
const pid = $computed(() => {
return props.id || (route.params.id as string)
})
const isAdd = $computed(() => !pid)
const form = inject(provideForm) as ProjectFormData
watchEffect(() => {
......@@ -23,7 +27,7 @@ watchEffect(() => {
const appList = $ref<InstanceType<typeof AppList> | null>(null)
const listOptions = $computed(() => {
return {
remote: !isAdd ? { httpRequest: getProjectUserList, params: { id: route.params.id } } : {},
remote: !isAdd ? { httpRequest: getProjectUserList, params: { id: pid } } : {},
columns: [
{ label: '姓名', prop: 'name' },
{ label: '手机号', prop: 'mobile' },
......@@ -88,7 +92,7 @@ function handleDelete(row: ProjectMember, index: number) {
</el-button>
</template>
<template #table-x="{ row, $index }">
<el-button text type="primary" @click="handleDelete(row, $index)" v-if="hasAuth('project-member-delete')">
<el-button text type="danger" @click="handleDelete(row, $index)" v-if="hasAuth('project-member-delete')">
删除
</el-button>
</template>
......
......@@ -71,6 +71,7 @@ export interface ProjectRequestParams {
project_uri: string
landing_page_uri: string
project_id: string
site_uri: string
members?: string
}
......
......@@ -41,7 +41,7 @@ const listOptions = $computed(() => {
const columns = $computed(() => {
const columns: Record<string, any>[] = [
{ label: '项目编号', prop: 'project_id' },
{ label: '项目编号', prop: 'project_id', width: 100 },
{ label: '项目名称', prop: 'title' },
{ label: '项目网址', prop: 'project_uri' },
{ label: '项目类型', prop: 'project_type_name' },
......
......@@ -64,6 +64,7 @@ function handleSubmit() {
return { user_id: item.user_id, roles: item.role_id }
})
const params = { ...form, members: JSON.stringify(members) }
if (!params.site_uri) params.site_uri = 'https://www.ezijing.com/'
if (props.action === 'add') handleAdd(params)
if (props.action === 'update') handleUpdate(params)
})
......@@ -86,7 +87,7 @@ function handleUpdate(params: ProjectRequestParams) {
<template>
<AppCard :title="title">
<el-form :model="form" label-width="100px" :disabled="action === 'view'" ref="formRef">
<el-form scroll-to-error :model="form" label-width="100px" :disabled="action === 'view'" ref="formRef">
<InfoBase style="margin: 20px 0"></InfoBase>
</el-form>
<InfoUsers v-if="action !== 'update' && hasAuth('project-member')"></InfoUsers>
......
......@@ -54,35 +54,12 @@ export interface PermissionType {
tag: string
}
// 课程信息
export interface CourseType {
auth_view: boolean
belong_operator: string
belong_operator_name: string
big: string
classification: string
classification_name: string
cover: string
created_operator: string
created_operator_name: string
created_time: string
credit: string
department_public: string
elective_type: string
elective_type_name: string
export interface SearchUser {
id: string
name: string
online_type: string
online_type_name: string
organ_id: string
organ_id_name: string
platform_public: string
project_id: string
project_id_name: string
small: string
status: string
status_name: string
updated_operator: string
updated_operator_name: string
updated_time: string
realname: string
nickname: string
username: string
mobile: string
avatar: string
email: string
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论