333 lines
11 KiB
TypeScript
333 lines
11 KiB
TypeScript
import { ref, type Component } from 'vue'
|
||
import { apiCategoryLists } from '@/api/service/category'
|
||
import feedback from '@/utils/feedback'
|
||
import { OperationEnumMap, OperationTextEnum, dispatchStatusMap } from '@/enums/modeEnum'
|
||
import { apiDistributorGroupLists } from '@/api/distributor/group'
|
||
import { CouponStatusApi, delCoupon, delCouponByDistributor, switchCouponStatus } from '@/api/application/coupon'
|
||
import {
|
||
ElMessageBox,
|
||
genFileId,
|
||
type ElTable,
|
||
type ElUpload,
|
||
type UploadFile,
|
||
type UploadFiles,
|
||
type UploadInstance,
|
||
type UploadRawFile,
|
||
type UploadUserFile
|
||
} from 'element-plus'
|
||
import { apiFeedbackAgreement, apiMasterWorkerApplyAgreement, apiMasterWorkerPhysicalAgreement } from '@/api/master_worker'
|
||
import { applyForEdit } from '@/api/finance/withdraw'
|
||
import { useCreateModal } from './useCreateModal'
|
||
import { toast, formatFileSize } from '@/utils/util'
|
||
import { postLists } from '@/api/account_center/postion'
|
||
|
||
export interface CategoryProp {
|
||
id: number
|
||
name: string
|
||
}
|
||
export interface GroupProp {
|
||
id: number
|
||
groupName: string
|
||
}
|
||
|
||
export function useCommon() {
|
||
const categoryLists = ref<CategoryProp[]>([])
|
||
const groupLists = ref<GroupProp[]>([])
|
||
const couponTable = ref<InstanceType<typeof ElTable>>()
|
||
const selectedIds = ref<number[]>([])
|
||
|
||
const isDisabled = computed(() => !selectedIds.value.length)
|
||
|
||
/**获取服务分类列表 */
|
||
const fetchCategoryList = async () => {
|
||
try {
|
||
const { lists } = await apiCategoryLists('')
|
||
categoryLists.value = lists
|
||
} catch (error) {}
|
||
}
|
||
/**切换发放状态 */
|
||
const handleStatusChange = (row: any, api: () => Promise<void>, type: string) => {
|
||
const { id, status = 1 } = row
|
||
return new Promise(async resolve => {
|
||
try {
|
||
await feedback.confirm(`确定${dispatchStatusMap[status]}发放?`)
|
||
// console.log(id, `${dispatchStatusMap[status]}`);
|
||
type === 'wrapper' ? await CouponStatusApi({ id }) : await switchCouponStatus({ id, status })
|
||
feedback.msgSuccess(`${dispatchStatusMap[status]}成功`)
|
||
api()
|
||
return resolve(true)
|
||
} catch (error) {}
|
||
})
|
||
}
|
||
/**获取分销组别列表 */
|
||
const fetchGroupList = async () => {
|
||
try {
|
||
const params = {
|
||
pageNo: 1,
|
||
pageSize: 10
|
||
}
|
||
const { lists } = await apiDistributorGroupLists(params)
|
||
groupLists.value = lists
|
||
} catch (error) {}
|
||
}
|
||
/**删除优惠券 */
|
||
const handleDelete = async (row: any, type: string, field: string, api: () => Promise<void>) => {
|
||
let couponName = ''
|
||
// 分销商优惠券
|
||
if (field === 'inner') {
|
||
const {
|
||
couponDetailVo: { name }
|
||
} = row
|
||
couponName = name
|
||
} else {
|
||
// 优惠券页面
|
||
const { name } = row
|
||
couponName = name
|
||
}
|
||
try {
|
||
if (type === 'single') couponTable.value?.toggleRowSelection(row, true)
|
||
const text = type === 'multiple' ? '勾选的优惠券' : `优惠券【${couponName}】`
|
||
await feedback.confirm(`此操作不可逆,确定删除${text}?`)
|
||
field === 'inner' ? await delCouponByDistributor({ ids: selectedIds.value }) : await delCoupon({ ids: selectedIds.value })
|
||
feedback.msgSuccess('删除成功')
|
||
api()
|
||
} catch (error) {
|
||
} finally {
|
||
clearSelection()
|
||
}
|
||
}
|
||
|
||
/**多选操作 */
|
||
const handleSelectionChange = (val: any[]) => {
|
||
selectedIds.value = val.map(item => item.id) as number[]
|
||
}
|
||
/**清除选中 */
|
||
function clearSelection() {
|
||
couponTable.value?.clearSelection()
|
||
}
|
||
|
||
return {
|
||
categoryLists,
|
||
groupLists,
|
||
couponTable,
|
||
selectedIds,
|
||
fetchGroupList,
|
||
fetchCategoryList,
|
||
handleStatusChange,
|
||
handleDelete,
|
||
isDisabled,
|
||
handleSelectionChange
|
||
}
|
||
}
|
||
|
||
export function useAuthStaffOperation(component: Component, isGoBack = false, event?: () => void, refresh?: () => Promise<any>) {
|
||
const fields: Record<string, (params?: any) => Promise<void>> = {
|
||
实名认证: apiMasterWorkerApplyAgreement,
|
||
体检报告: apiMasterWorkerPhysicalAgreement,
|
||
意见反馈: apiFeedbackAgreement,
|
||
提现: applyForEdit
|
||
}
|
||
const commandComponent = useCreateModal(component)
|
||
|
||
/**通过和拒绝 */
|
||
const handleOperation = (row: any, type: string, msg = '实名认证') => {
|
||
const field = msg === '实名认证' ? 'name' : msg === '提现' ? 'distributorName' : 'staffName'
|
||
const filedKey = msg === '意见反馈' ? 'reply' : msg === '提现' ? 'failReason' : 'refuseReason'
|
||
const identity = msg == '提现' ? '分销商' : '师傅'
|
||
const { id } = row
|
||
const data = { id, status: OperationEnumMap[type] }
|
||
type === OperationTextEnum.SUCCESS
|
||
? feedback
|
||
.confirm(`您确定通过【${row[field]}】${identity}的${msg}申请吗?`)
|
||
.then(async () => {
|
||
handleConfirm(data, '审核通过', msg)
|
||
})
|
||
.catch(() => {})
|
||
: commandComponent({
|
||
title: `${msg === '意见反馈' ? '回复' : '拒绝'}理由`,
|
||
width: 500,
|
||
onConfirm: async payload => {
|
||
Object.assign(data, {
|
||
[filedKey]: payload.reason
|
||
})
|
||
handleConfirm(data, `已拒绝【${row[field]}】申请`, msg)
|
||
}
|
||
})
|
||
}
|
||
/**确认后操作 */
|
||
async function handleConfirm(data: any, message: string, tip: string) {
|
||
try {
|
||
const api = fields[tip]
|
||
await api(data)
|
||
feedback.msgSuccess(message)
|
||
refresh?.()
|
||
isGoBack && event?.()
|
||
} catch (error) {}
|
||
}
|
||
|
||
return {
|
||
handleOperation
|
||
}
|
||
}
|
||
|
||
/**校验上传图片过程、图片上传操作 */
|
||
export function useUploadMoreAction() {
|
||
/**upload组件实例 */
|
||
const uploadRef = ref<InstanceType<typeof ElUpload>>()
|
||
const fileUploadList = ref<Record<string, UploadFile[]>>({
|
||
avatar: [],
|
||
idCard: [],
|
||
report: [],
|
||
pdf: []
|
||
})
|
||
const imgViewerVisible = ref(false)
|
||
const viewerIndex = ref(0)
|
||
const previewSrcList = ref<string[]>([])
|
||
const uploadPdf = ref<UploadInstance>()
|
||
const pdfDialog = ref()
|
||
|
||
/**判断图片类型 */
|
||
const getFileType = (name: string | undefined) => {
|
||
if (!name) return
|
||
const matches = name.match(/\.([^.]+)$/)
|
||
return matches && matches[1]
|
||
}
|
||
|
||
/**判断图片是否符合格式 */
|
||
const isImage = (file: UploadFile, type: string) => {
|
||
const suffixArr = type === 'pdf' ? ['pdf'] : ['jpg', 'png', 'jpeg']
|
||
const suffix = getFileType(file.raw?.name)
|
||
if (!suffix) return
|
||
return suffixArr.includes(suffix)
|
||
}
|
||
|
||
/**校验图片格式和文件大小 */
|
||
const validate = (file: UploadFile, fileList: UploadFiles, type: string, size: number) => {
|
||
return new Promise((resolve, reject) => {
|
||
const text = type === 'pdf' ? '文件' : '图片'
|
||
if (!isImage(file, type)) {
|
||
const msg = type === 'pdf' ? 'pdf' : 'jpg,png,jpeg'
|
||
toast(`请上传${msg}格式的${text}`, 'error')
|
||
fileList.splice(-1, 1)
|
||
uploadRef.value?.abort(file)
|
||
return false
|
||
}
|
||
if ((file.size as number) > size) {
|
||
toast(`${text}【${file.name}】大小:${formatFileSize(file.size as number)},请上传小于${formatFileSize(size)}的${text}`, 'error', 3000)
|
||
fileList.splice(-1, 1)
|
||
uploadRef.value?.abort(file)
|
||
return false
|
||
}
|
||
fileUploadList.value[type] = fileList
|
||
resolve(true)
|
||
})
|
||
}
|
||
|
||
/**开始上传 */
|
||
const startUpload = async (file: UploadFile, fileList: UploadFiles, type: string, size: number) => {
|
||
const flag = await validate(file, fileList, type, size)
|
||
}
|
||
|
||
/**上传图片 */
|
||
const onSubmit = () => {
|
||
if (!fileUploadList.value.length) {
|
||
toast('请先上传图片', 'warning')
|
||
}
|
||
}
|
||
|
||
/**删除图片 */
|
||
const beforeRemove = (file: UploadFile, fileList: UploadFiles, type: string) => {
|
||
return new Promise((resolve, reject) => {
|
||
ElMessageBox.confirm(`确定删除${file.name}图片`, '温馨提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
})
|
||
.then(() => {
|
||
const index = fileList.indexOf(file)
|
||
fileList.splice(index, 1)
|
||
fileUploadList.value[type] = fileList
|
||
})
|
||
.catch(() => {
|
||
resolve(false)
|
||
})
|
||
})
|
||
}
|
||
|
||
/**预览图片 */
|
||
const handlePreview = (file: UploadFile, type: string) => {
|
||
if (!unref(fileUploadList)[type].length) return
|
||
imgViewerVisible.value = true
|
||
const index = unref(fileUploadList)[type].indexOf(file)
|
||
viewerIndex.value = index
|
||
previewSrcList.value = unref(fileUploadList)[type].map(file => file.url!)
|
||
}
|
||
|
||
// pdf预览
|
||
const previewPdf = (file: UploadFile) => {
|
||
const reader = new FileReader() // 读取文件资源
|
||
reader.readAsDataURL(file.raw!)
|
||
reader.onload = function (e) {
|
||
if (e?.target?.result) pdfDialog.value.openDialog(e?.target.result)
|
||
}
|
||
}
|
||
|
||
/**关闭预览图片 */
|
||
const closeImageViewer = () => {
|
||
imgViewerVisible.value = false
|
||
}
|
||
|
||
/**超出限制重新上传 */
|
||
const handleExceed = (files: File[], uploadFiles: UploadUserFile[], type: string) => {
|
||
switch (type) {
|
||
case 'report':
|
||
toast('体检报告的图片最多上传9张')
|
||
break
|
||
case 'pdf':
|
||
uploadPdf.value?.clearFiles()
|
||
const file = files[0] as UploadRawFile
|
||
file.uid = genFileId()
|
||
uploadPdf.value?.handleStart(file)
|
||
break
|
||
case 'idCard':
|
||
toast('身份证正反面最多上传2张')
|
||
break
|
||
default:
|
||
break
|
||
}
|
||
}
|
||
|
||
return {
|
||
uploadPdf,
|
||
fileUploadList,
|
||
imgViewerVisible,
|
||
viewerIndex,
|
||
previewSrcList,
|
||
startUpload,
|
||
beforeRemove,
|
||
handlePreview,
|
||
closeImageViewer,
|
||
handleExceed,
|
||
pdfDialog,
|
||
previewPdf
|
||
}
|
||
}
|
||
|
||
export function usePositionData() {
|
||
const positionOptions = ref<any[]>([])
|
||
const postId = ref()
|
||
const fetchPostionData = async (callback?: (params: []) => void) => {
|
||
try {
|
||
const result = await postLists()
|
||
positionOptions.value = result.lists ?? []
|
||
if (result.lists.length > 0) postId.value = result.lists[0].id
|
||
callback && callback(result.lists)
|
||
} catch (error) {}
|
||
}
|
||
return {
|
||
positionOptions,
|
||
postId,
|
||
fetchPostionData
|
||
}
|
||
}
|