【招生用户端】 新增# 对接总结记录列表、子账号管理设置组长

main
kaeery 2025-02-28 22:42:58 +08:00
parent 8b92a8407f
commit 1f314a43f1
9 changed files with 109 additions and 46 deletions

View File

@ -20,3 +20,7 @@ export function templateDetail(params: any) {
export function templateDelete(params: any) { export function templateDelete(params: any) {
return request.post({ url: '/template/del', params }) return request.post({ url: '/template/del', params })
} }
// 总结列表
export function summaryRecordLists(params: any) {
return request.get({ url: '/summary/template/list', params })
}

View File

@ -1,7 +1,17 @@
<template> <template>
<el-date-picker v-model="content" :type="type" range-separator="-" :format="format" :valueFormat="format" <el-date-picker
start-placeholder="开始时间" end-placeholder="结束时间" clearable :disabled-date="setDisabledDate" v-model="content"
:disabled-hours="setDisabledHours"></el-date-picker> :type="type"
range-separator="-"
:format="format"
:valueFormat="format"
start-placeholder="开始时间"
end-placeholder="结束时间"
clearable
:disabled-date="setDisabledDate"
:disabled-hours="setDisabledHours"
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]"
></el-date-picker>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -12,10 +22,10 @@ import type { DatePickType } from 'element-plus'
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
startTime?: string | number startTime?: string | number
endTime?: string | number, endTime?: string | number
type?: DatePickType, type?: DatePickType
format?: string, format?: string
isDisabledDate?: boolean, isDisabledDate?: boolean
isDisabledHours?: boolean isDisabledHours?: boolean
}>(), }>(),
{ {

View File

@ -92,6 +92,10 @@ export const clueStepMap: Record<clueStepEnum, string> = {
[clueStepEnum.CLUE_COMPLETED]: '转化完成', [clueStepEnum.CLUE_COMPLETED]: '转化完成',
[clueStepEnum.UPDATE_CLUSE_PROGRESS]: '修改跟进' [clueStepEnum.UPDATE_CLUSE_PROGRESS]: '修改跟进'
} }
export enum groupLeaderEnum {
YES = 1,
NO = 0
}
const keys: Record<string, any> = { const keys: Record<string, any> = {
conversionMap: conversionMap, conversionMap: conversionMap,

View File

@ -28,6 +28,7 @@ export interface GroupProp {
id: number id: number
groupName: string groupName: string
} }
export function useCommon() { export function useCommon() {
const categoryLists = ref<CategoryProp[]>([]) const categoryLists = ref<CategoryProp[]>([])
const groupLists = ref<GroupProp[]>([]) const groupLists = ref<GroupProp[]>([])
@ -133,7 +134,7 @@ export function useAuthStaffOperation(component: Component, isGoBack = false, ev
const filedKey = msg === '意见反馈' ? 'reply' : msg === '提现' ? 'failReason' : 'refuseReason' const filedKey = msg === '意见反馈' ? 'reply' : msg === '提现' ? 'failReason' : 'refuseReason'
const identity = msg == '提现' ? '分销商' : '师傅' const identity = msg == '提现' ? '分销商' : '师傅'
const { id } = row const { id } = row
let data = { id, status: OperationEnumMap[type] } const data = { id, status: OperationEnumMap[type] }
type === OperationTextEnum.SUCCESS type === OperationTextEnum.SUCCESS
? feedback ? feedback
.confirm(`您确定通过【${row[field]}${identity}${msg}申请吗?`) .confirm(`您确定通过【${row[field]}${identity}${msg}申请吗?`)
@ -204,7 +205,7 @@ export function useUploadMoreAction() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const text = type === 'pdf' ? '文件' : '图片' const text = type === 'pdf' ? '文件' : '图片'
if (!isImage(file, type)) { if (!isImage(file, type)) {
let msg = type === 'pdf' ? 'pdf' : 'jpgpngjpeg' const msg = type === 'pdf' ? 'pdf' : 'jpgpngjpeg'
toast(`请上传${msg}格式的${text}`, 'error') toast(`请上传${msg}格式的${text}`, 'error')
fileList.splice(-1, 1) fileList.splice(-1, 1)
uploadRef.value?.abort(file) uploadRef.value?.abort(file)
@ -242,7 +243,7 @@ export function useUploadMoreAction() {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
let index = fileList.indexOf(file) const index = fileList.indexOf(file)
fileList.splice(index, 1) fileList.splice(index, 1)
fileUploadList.value[type] = fileList fileUploadList.value[type] = fileList
}) })
@ -256,7 +257,7 @@ export function useUploadMoreAction() {
const handlePreview = (file: UploadFile, type: string) => { const handlePreview = (file: UploadFile, type: string) => {
if (!unref(fileUploadList)[type].length) return if (!unref(fileUploadList)[type].length) return
imgViewerVisible.value = true imgViewerVisible.value = true
let index = unref(fileUploadList)[type].indexOf(file) const index = unref(fileUploadList)[type].indexOf(file)
viewerIndex.value = index viewerIndex.value = index
previewSrcList.value = unref(fileUploadList)[type].map(file => file.url!) previewSrcList.value = unref(fileUploadList)[type].map(file => file.url!)
} }

View File

@ -47,9 +47,8 @@
<el-radio v-for="option in channelOptions" :key="option.value" :label="option.value">{{ option.label }}</el-radio> <el-radio v-for="option in channelOptions" :key="option.value" :label="option.value">{{ option.label }}</el-radio>
</el-radio-group> </el-radio-group>
<template v-if="form.dataFlow == 1"> <template v-if="form.dataFlow == 1">
<el-select class="mt-[10px]" v-model="form.teacher" placeholder="请选择指定招生老师"> <el-select class="mt-[10px]" v-model="form.designatedTeacherId" placeholder="请选择指定招生老师">
<el-option label="Zone one" value="shanghai" /> <el-option v-for="item in recrutList" :key="item.id" :label="item.username" :value="item.id" />
<el-option label="Zone two" value="beijing" />
</el-select> </el-select>
</template> </template>
</el-form-item> </el-form-item>
@ -66,7 +65,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { organzationLists } from '@/api/account_center/organization' import { organzationLists } from '@/api/account_center/organization'
import { postLists } from '@/api/account_center/postion' import { postLists } from '@/api/account_center/postion'
import { subAccountAdd, subAccountDetail, subAccountEdit } from '@/api/account_center/sub_account' import { subAccountAdd, subAccountDetail, subAccountEdit, subAccountList } from '@/api/account_center/sub_account'
import ProDialog, { type IParams } from '@/components/ProDialog/index.vue' import ProDialog, { type IParams } from '@/components/ProDialog/index.vue'
import { DataFlowEnum, isDisabledEnum } from '@/enums' import { DataFlowEnum, isDisabledEnum } from '@/enums'
import { validateContact } from '@/utils/validate' import { validateContact } from '@/utils/validate'
@ -109,7 +108,7 @@ const form = ref({
postIds: [], postIds: [],
dataFlow: 0, dataFlow: 0,
isDisable: 0, isDisable: 0,
teacher: '' designatedTeacherId: ''
}) })
const fetchPostionData = async (callback?: (params: []) => void) => { const fetchPostionData = async (callback?: (params: []) => void) => {
try { try {
@ -173,10 +172,23 @@ const findNodeById = (nodes: any[], id: number): any | undefined => {
} }
return undefined return undefined
} }
const recrutList = ref<any[]>([])
const fetchRecrutList = async (organizationId: number) => {
try {
const params = {
organizationId,
postId: 5
}
const result = await subAccountList(params)
recrutList.value = result ?? []
} catch (error) {}
}
const openDialog = async (params: IParams) => { const openDialog = async (params: IParams) => {
const { organizationId, id } = params.data
fetchPostionData() fetchPostionData()
fetchOrganizationData(params.data.organizationId) fetchOrganizationData(organizationId)
if (params.data.id) fetchDetail(params.data) fetchRecrutList(organizationId)
if (id) fetchDetail(params.data)
proDialogRef.value?.openDialog(params) proDialogRef.value?.openDialog(params)
} }
const handleCancel = (callback: () => void) => { const handleCancel = (callback: () => void) => {

View File

@ -25,10 +25,10 @@
</el-space> </el-space>
</div> </div>
<ProTable ref="proTableRef" :columns="columns" :tableData="tableData" :loading="loading" :maxHeight="530"> <ProTable ref="proTableRef" :columns="columns" :tableData="tableData" :loading="loading" :maxHeight="530">
<template #accountName="{ row }"> <template #username="{ row }">
<el-space> <el-space>
<div class="w-[50px] h-[50px] bg-primary rounded-[6px] text-white flex-row-center-center">{{ row.accountName }}</div> <div class="w-[50px] h-[50px] bg-primary rounded-[6px] text-white flex-row-center-center">{{ row.username }}</div>
<span>{{ row.accountName }}</span> <span>{{ row.username }}</span>
<span <span
v-if="isGroupLeader(row.groupLeader)" v-if="isGroupLeader(row.groupLeader)"
class="px-[6px] text-green border border-solid border-green rounded-[4px] text-center text-xs" class="px-[6px] text-green border border-solid border-green rounded-[4px] text-center text-xs"
@ -61,8 +61,8 @@ import feedback from '@/utils/feedback'
import { Plus, Delete } from '@element-plus/icons-vue' import { Plus, Delete } from '@element-plus/icons-vue'
import accountDialog from '../components/account-list/account-dialog.vue' import accountDialog from '../components/account-list/account-dialog.vue'
import { useDebounceFn } from '@vueuse/core' import { useDebounceFn } from '@vueuse/core'
import { subAccountDelete, subAccountList } from '@/api/account_center/sub_account' import { subAccountDelete, subAccountEdit, subAccountList } from '@/api/account_center/sub_account'
import { StatusEnum, isDisabledEnum } from '@/enums' import { StatusEnum, groupLeaderEnum, isDisabledEnum } from '@/enums'
import { omit } from 'lodash-es' import { omit } from 'lodash-es'
const props = defineProps({ const props = defineProps({
@ -96,7 +96,7 @@ const columns = reactive([
{ prop: 'operation', label: '操作', fixed: 'right', width: 250 } { prop: 'operation', label: '操作', fixed: 'right', width: 250 }
]) ])
const isGroupLeader = computed(() => (groupLeader: number) => groupLeader == 1) const isGroupLeader = computed(() => (groupLeader: number) => groupLeader === groupLeaderEnum.YES)
const btnText = computed(() => (groupLeader: number) => isGroupLeader.value(groupLeader) ? '取消设为组长' : '设置组长') const btnText = computed(() => (groupLeader: number) => isGroupLeader.value(groupLeader) ? '取消设为组长' : '设置组长')
const isDisabledAdd = computed(() => props.curOrganization.status == StatusEnum.Stop) const isDisabledAdd = computed(() => props.curOrganization.status == StatusEnum.Stop)
const fetchTableList = async (nodeId?: number) => { const fetchTableList = async (nodeId?: number) => {
@ -118,12 +118,21 @@ const handleStatusChange = row => {
resolve(true) resolve(true)
}) })
} }
//
const setGroupLeader = async row => { const setGroupLeader = async row => {
const { accountName, id, groupLeader } = row const { username, id, groupLeader } = row
const message = isGroupLeader.value(groupLeader) ? `确定要取消【${accountName}】的组长身份吗?` : `确定将【${accountName}】设置为组长?` const message = isGroupLeader.value(groupLeader) ? `确定要取消【${username}】的组长身份吗?` : `确定将【${username}】设置为组长?`
const flag = await useHandleData(message) const flag = await useHandleData(message)
if (!flag) return if (!flag) return
try {
const params = {
id,
groupLeader: isGroupLeader.value(groupLeader) ? groupLeaderEnum.YES : groupLeaderEnum.NO
}
await subAccountEdit(params)
feedback.msgSuccess('设置成功') feedback.msgSuccess('设置成功')
fetchTableList()
} catch (error) {}
} }
const isDisabled = computed(() => proTableRef?.value?.selectedListIds?.length == 0) const isDisabled = computed(() => proTableRef?.value?.selectedListIds?.length == 0)
const handleBatchDelete = () => { const handleBatchDelete = () => {

View File

@ -24,8 +24,9 @@ const queryParams = ref<Record<string, any>>({
postId: '' postId: ''
}, },
record: { record: {
submitName: '', userName: '',
submitDate: '' startTime: '',
endTime: ''
} }
}) })
const componentName = computed(() => (activeTab.value == 'template' ? templateSearchForm : recordSearchForm)) const componentName = computed(() => (activeTab.value == 'template' ? templateSearchForm : recordSearchForm))
@ -39,6 +40,8 @@ const resetPage = () => {
summaryTemplateRef.value?.resetPage() summaryTemplateRef.value?.resetPage()
break break
case 'record': case 'record':
console.log(queryParams.value[activeTab.value])
summaryRecordRef.value?.resetPage() summaryRecordRef.value?.resetPage()
break break
} }

View File

@ -2,15 +2,14 @@
<el-card shadow="never" class="!border-none"> <el-card shadow="never" class="!border-none">
<el-form ref="formRef" class="mb-[-16px]" :model="modelValue" :inline="true"> <el-form ref="formRef" class="mb-[-16px]" :model="modelValue" :inline="true">
<el-form-item label="提交人"> <el-form-item label="提交人">
<el-input class="w-[280px]" placeholder="请输入" v-model="modelValue.submitName" clearable @keyup.enter="$emit('resetPage')" /> <el-input class="w-[280px]" placeholder="请输入" v-model="modelValue.userName" clearable @keyup.enter="$emit('resetPage')" />
</el-form-item> </el-form-item>
<el-form-item label="提交时间"> <el-form-item label="提交时间">
<el-date-picker <daterange-picker
v-model="modelValue.submitDate"
type="datetimerange" type="datetimerange"
range-separator="至" format="YYYY-MM-DD HH:mm:ss"
start-placeholder="开始时间" v-model:startTime="modelValue.startTime"
end-placeholder="结束时间" v-model:endTime="modelValue.endTime"
/> />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@ -27,7 +26,8 @@ defineProps({
type: Object, type: Object,
default: () => ({ default: () => ({
submitName: '', submitName: '',
submitDate: '' startTime: '',
endTime: ''
}) })
} }
}) })

View File

@ -1,34 +1,54 @@
<template> <template>
<ProTable ref="proTableRef" :columns="columns" :tableData="pager.lists" :loading="pager.loading" :maxHeight="530" /> <ProTable ref="proTableRef" :columns="columns" :tableData="pager.lists" :loading="pager.loading" :maxHeight="530">
<template #postId="{ row }">
<span>{{ parsePositionText(row.postId) }}</span>
</template>
<template #templateFormList="{ row }">
<div v-for="(item, index) in row.templateFormList" :key="index">
<span>{{ item.formTitle }}</span>
<span>{{ item.value }}</span>
</div>
</template>
</ProTable>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { postLists } from '@/api/org/post' import { postLists } from '@/api/account_center/postion'
import { summaryRecordLists } from '@/api/summary'
import { usePaging } from '@/hooks/usePaging' import { usePaging } from '@/hooks/usePaging'
const props = defineProps({ const props = defineProps({
queryParams: { queryParams: {
type: Object, type: Object,
default: () => ({ default: () => ({
submitName: '', userName: '',
submitDate: '' submitDate: []
}) })
} }
}) })
const { pager, getLists, resetPage, resetParams } = usePaging({ const { pager, getLists, resetPage, resetParams } = usePaging({
fetchFun: postLists, fetchFun: summaryRecordLists,
params: props.queryParams params: props.queryParams
}) })
getLists() getLists()
const proTableRef = ref() const proTableRef = ref()
const columns = reactive([ const columns = reactive([
{ prop: 'name', label: '提交人', width: 180 }, { prop: 'userName', label: '提交人', width: 180 },
{ prop: 'type', label: '岗位', width: 180 }, { prop: 'postId', label: '岗位', width: 180 },
{ prop: 'type', label: '提交时间', width: 180 }, { prop: 'addTime', label: '提交时间', width: 180 },
{ prop: 'type', label: '总结情况', width: 180 } { prop: 'templateFormList', label: '总结情况', width: 180 }
]) ])
const positionOptions = ref<any[]>([])
const parsePositionText = computed(() => (postId: number) => positionOptions.value.find(item => item.id == postId).name ?? '--')
const fetchPostionData = async () => {
try {
const result = await postLists()
positionOptions.value = result.lists
} catch (error) {}
}
fetchPostionData()
defineExpose({ defineExpose({
resetPage, resetPage,
resetParams, resetParams,