|
|
@@ -0,0 +1,420 @@
|
|
|
+<!-- 用户管理 -->
|
|
|
+<!-- art-full-height 自动计算出页面剩余高度 -->
|
|
|
+<!-- art-table-card 一个符合系统样式的 class,同时自动撑满剩余高度 -->
|
|
|
+<!-- 更多 useTable 使用示例请移步至 功能示例 下面的 高级表格示例 -->
|
|
|
+<template>
|
|
|
+ <div class="user-page art-full-height">
|
|
|
+ <!-- 搜索栏 -->
|
|
|
+ <UserSearch v-model="searchForm" @search="handleSearch" @reset="resetSearchParams" :school-list="selectList" :company-list="[]"></UserSearch>
|
|
|
+
|
|
|
+ <!-- 跟进弹窗 -->
|
|
|
+ <FollowDialog
|
|
|
+ v-model:visible="followDialogVisible"
|
|
|
+ :user-data="currentRow"
|
|
|
+ :type="'canteen'"
|
|
|
+ :first_id="currentRow.school_id"
|
|
|
+ :second_id="currentRow.id"
|
|
|
+ :selectList="selectList"
|
|
|
+ @submit="handleDialogSubmit"
|
|
|
+ />
|
|
|
+
|
|
|
+ <ElCard class="art-table-card" shadow="never">
|
|
|
+ <!-- 表格头部 -->
|
|
|
+ <ArtTableHeader v-model:columns="columnChecks" @refresh="refreshData">
|
|
|
+ <template #left>
|
|
|
+ <ElButton type="primary" @click="edit()" v-ripple v-auth="130101">新增食堂</ElButton>
|
|
|
+ </template>
|
|
|
+ </ArtTableHeader>
|
|
|
+
|
|
|
+ <!-- 表格 -->
|
|
|
+ <ArtTable
|
|
|
+ :loading="loading"
|
|
|
+ :data="data"
|
|
|
+ :columns="columns"
|
|
|
+ :pagination="pagination"
|
|
|
+ @pagination:size-change="handleSizeChange"
|
|
|
+ @pagination:current-change="handleCurrentChange"
|
|
|
+ >
|
|
|
+ <template #person_num="scope">
|
|
|
+ <ElInput
|
|
|
+ v-model="scope.row.person_num"
|
|
|
+ placeholder="scope.row.person_num"
|
|
|
+ @blur="doUpdateAttr(scope)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #is_eleme_in_school="scope">
|
|
|
+ <ElSwitch
|
|
|
+ v-model="scope.row.is_eleme_in_school"
|
|
|
+ @change="doUpdateAttr(scope)"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
+ :before-change="() => isMounted"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #is_eleme_out_school="scope">
|
|
|
+ <ElSwitch v-model="scope.row.is_eleme_out_school" @change="doUpdateAttr(scope)"/>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #is_meituan_in_school="scope">
|
|
|
+ <ElSwitch v-model="scope.row.is_meituan_in_school" @change="doUpdateAttr(scope)"/>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template #is_meituan_out_school="scope">
|
|
|
+ <ElSwitch v-model="scope.row.is_meituan_out_school" @change="doUpdateAttr(scope)"/>
|
|
|
+ </template>
|
|
|
+ </ArtTable>
|
|
|
+
|
|
|
+ </ElCard>
|
|
|
+
|
|
|
+ <el-drawer
|
|
|
+ v-model="drawer"
|
|
|
+ direction="rtl"
|
|
|
+ size="60%"
|
|
|
+ >
|
|
|
+ <template #header>
|
|
|
+ <span style="font-size: 20px; font-weight: bold;">{{ currentRow.name }}</span>
|
|
|
+ </template>
|
|
|
+ <ElRow>
|
|
|
+ <ElCol :sm="8">
|
|
|
+ <ElRow class="detail">
|
|
|
+
|
|
|
+ <el-col>
|
|
|
+ <label>学校(校区):</label> <span>{{ currentRow.school_name }}</span>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col>
|
|
|
+ <label>档口数量:</label> <span>{{ currentRow.stall_num }}</span>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col>
|
|
|
+ <label>是否直营:</label> <span>{{ currentRow.is_direct ? '直营' : '非直营' }}</span>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col>
|
|
|
+ <label>餐饮公司:</label> <span>{{ currentRow.company_name }}</span>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col>
|
|
|
+ <label>食堂经理:</label> <span>{{ currentRow.username }}</span>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col>
|
|
|
+ <label>手机号:</label> <span>{{ currentRow.phone }}</span>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col>
|
|
|
+ <label>微信号:</label> <span>{{ currentRow.weixin }}</span>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col>
|
|
|
+ <label>档口照片:</label>
|
|
|
+ <el-image
|
|
|
+ v-if="currentRow.stall_imgs.length"
|
|
|
+ ref="imageRef"
|
|
|
+ style="width: 60px; height: 60px"
|
|
|
+ :src="currentRow.stall_imgs[0]"
|
|
|
+ show-progress
|
|
|
+ :preview-src-list="currentRow.stall_imgs"
|
|
|
+ fit="cover"
|
|
|
+ />
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+
|
|
|
+ </ElRow>
|
|
|
+ </ElCol>
|
|
|
+ <ElCol :sm="16">
|
|
|
+ <FollowDrawer :first_id="currentRow.school_id" :second_id="currentRow.id" type="canteen" :uid="drawerUid"/>
|
|
|
+ </ElCol>
|
|
|
+ </ElRow>
|
|
|
+ </el-drawer>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import ArtButtonTable from '@/components/core/forms/art-button-table/index.vue'
|
|
|
+import {ElMessageBox, ElMessage, ElTag, ElImage, ElButton, ElInput} from 'element-plus'
|
|
|
+import {useTable} from '@/composables/useTable'
|
|
|
+import {canteenApi} from '@/api/canteenApi'
|
|
|
+import UserSearch from './user-search.vue'
|
|
|
+import {useUserStore} from '@/store/modules/user'
|
|
|
+import EmojiText from '@utils/ui/emojo'
|
|
|
+import {router} from '@/router'
|
|
|
+import {RoutesAlias} from '@/router/routesAlias'
|
|
|
+import {schoolRelationApi} from "@/api/schoolRelationApi";
|
|
|
+
|
|
|
+defineOptions({name: 'User'})
|
|
|
+
|
|
|
+const {list} = canteenApi
|
|
|
+const drawer = ref(false)
|
|
|
+const followDialogVisible = ref(false)
|
|
|
+
|
|
|
+// 搜索表单
|
|
|
+const searchForm = ref({
|
|
|
+ name: '',
|
|
|
+ is_cooperate: -1,
|
|
|
+ address: []
|
|
|
+})
|
|
|
+
|
|
|
+const defaultValue = <Api.Canteen.ListItem>{
|
|
|
+ id:0,
|
|
|
+ school_id: 0,
|
|
|
+ school_name: "",
|
|
|
+ company_id: 0,
|
|
|
+ company_name: "",
|
|
|
+ name: "",
|
|
|
+ stall_num: 0,
|
|
|
+ is_direct: 0,
|
|
|
+ stall_imgs: [],
|
|
|
+ username: "",
|
|
|
+ phone: "",
|
|
|
+ weixin: "",
|
|
|
+ memo: "",
|
|
|
+ last_user_id: 0,
|
|
|
+ last_user_name: '',
|
|
|
+ last_date: ''
|
|
|
+}
|
|
|
+
|
|
|
+const currentRow = ref<Api.Canteen.ListItem>({...defaultValue})
|
|
|
+
|
|
|
+const selectList = ref<Api.Common.SelectRelationInfo[]>([])
|
|
|
+const getSelectList = async () => {
|
|
|
+ const data = await canteenApi.selectList()
|
|
|
+ selectList.value = data
|
|
|
+}
|
|
|
+getSelectList()
|
|
|
+
|
|
|
+const drawerUid = ref(0)
|
|
|
+
|
|
|
+/**
|
|
|
+ * 处理弹窗提交事件
|
|
|
+ */
|
|
|
+const handleDialogSubmit = async () => {
|
|
|
+ followDialogVisible.value = false
|
|
|
+ drawerUid.value++
|
|
|
+}
|
|
|
+
|
|
|
+const {
|
|
|
+ columns,
|
|
|
+ columnChecks,
|
|
|
+ data,
|
|
|
+ loading,
|
|
|
+ pagination,
|
|
|
+ getData,
|
|
|
+ searchParams,
|
|
|
+ resetSearchParams,
|
|
|
+ handleSizeChange,
|
|
|
+ handleCurrentChange,
|
|
|
+ refreshData
|
|
|
+} = useTable<Api.Canteen.ListItem>({
|
|
|
+ // 核心配置
|
|
|
+ core: {
|
|
|
+ apiFn: list,
|
|
|
+ apiParams: {
|
|
|
+ current: 1,
|
|
|
+ size: 20,
|
|
|
+ ...searchForm.value
|
|
|
+ },
|
|
|
+ // 排除 apiParams 中的属性
|
|
|
+ excludeParams: [],
|
|
|
+ columnsFactory: () => [
|
|
|
+ {
|
|
|
+ prop: 'name', label: '食堂名称', formatter: (row) => {
|
|
|
+ return h(ElButton, {
|
|
|
+ type: 'primary',
|
|
|
+ link: true,
|
|
|
+ onClick: () => showDrawer(row),
|
|
|
+ style: {"text-decoration": 'underline'}
|
|
|
+ }, () => row.name)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { prop:'school_name', label:'学校' },
|
|
|
+ { prop:'stall_num', label:'档口数量' },
|
|
|
+ { prop:'is_direct', label:'是否直营', formatter: (row) => {
|
|
|
+ return h(ElTag, { type: row.is_direct ? 'success' : 'danger' }, () => row.is_direct ? '是' : '不是')
|
|
|
+ } },
|
|
|
+ { prop:'stall_imgs', label:'档口照片', formatter: (row) => {
|
|
|
+ if (row.stall_imgs.length > 0) {
|
|
|
+ return h(ElImage, {
|
|
|
+ src: row.stall_imgs[0],
|
|
|
+ previewSrcList: row.stall_imgs,
|
|
|
+ showProgress: true,
|
|
|
+ fit: "cover",
|
|
|
+ title: '点击预览全部图片',
|
|
|
+ style: {"max-width": "50px", "max-height": "50px"},
|
|
|
+ // 图片预览是否插入至 body 元素上,用于解决表格内部图片预览样式异常
|
|
|
+ previewTeleported: true
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ return ''
|
|
|
+ }
|
|
|
+ }},
|
|
|
+ { prop:'username', label:'食堂经理' },
|
|
|
+ { prop:'phone', label:'手机号' },
|
|
|
+ { prop:'weixin', label:'微信号' },
|
|
|
+ { prop:'memo', label:'备注', showOverflowTooltip:true },
|
|
|
+ { prop:'last_user_name', label:'最后一次跟进人' },
|
|
|
+ { prop:'last_date', label:'最后一次跟进时间' },
|
|
|
+ {
|
|
|
+ prop: '', label: '跟进记录', formatter: (row) => {
|
|
|
+ return h(ElButton, {
|
|
|
+ type: 'primary',
|
|
|
+ onClick: () => follow(row),
|
|
|
+ }, () => '跟进')
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'operation',
|
|
|
+ label: '操作',
|
|
|
+ width: 120,
|
|
|
+ fixed: 'right', // 固定列
|
|
|
+ formatter: (row) =>
|
|
|
+ h('div', [
|
|
|
+ h(ArtButtonTable, {
|
|
|
+ type: 'view',
|
|
|
+ onClick: () => view(row.id)
|
|
|
+ }),
|
|
|
+ useUserStore().checkAuth(130102) && h(ArtButtonTable, {
|
|
|
+ type: 'edit',
|
|
|
+ onClick: () => edit(row.id)
|
|
|
+ }),
|
|
|
+ useUserStore().checkAuth(130203) &&
|
|
|
+ h(ArtButtonTable, {
|
|
|
+ type: 'delete',
|
|
|
+ onClick: () => deleteUser(row.id)
|
|
|
+ })
|
|
|
+ ])
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+// TODO:不知道为什么初始化会触发switch的change事件
|
|
|
+const isMounted = ref(false)
|
|
|
+onMounted(() => {
|
|
|
+ setTimeout(() => {
|
|
|
+ isMounted.value = true
|
|
|
+ }, 1000)
|
|
|
+})
|
|
|
+
|
|
|
+const doUpdateAttr = (scope: any) => {
|
|
|
+ console.log(`%c scope == `, 'background:#41b883 ; padding:1px; color:#fff', scope)
|
|
|
+ if (!scope.row.id || !isMounted.value) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ canteenApi
|
|
|
+ .updateAttr({id: scope.row.id, attr: scope.prop, value: scope.row[scope.prop]})
|
|
|
+ .then(() => {
|
|
|
+ ElMessage.success(`${EmojiText[200]} 修改成功`)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 搜索处理
|
|
|
+ * @param params 参数
|
|
|
+ */
|
|
|
+const handleSearch = (params: Record<string, any>) => {
|
|
|
+ Object.assign(searchParams, {...params})
|
|
|
+ getData()
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 编辑
|
|
|
+ */
|
|
|
+const edit = (id?: number): void => {
|
|
|
+ router.push({
|
|
|
+ path: RoutesAlias.CanteenEdit,
|
|
|
+ query: {
|
|
|
+ id: id
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 显示跟进弹窗
|
|
|
+ */
|
|
|
+const follow = (row: Api.Canteen.ListItem): void => {
|
|
|
+ currentRow.value = row || {}
|
|
|
+ nextTick(() => {
|
|
|
+ followDialogVisible.value = true
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 查看
|
|
|
+ */
|
|
|
+const view = (id: number): void => {
|
|
|
+ router.push({
|
|
|
+ path: RoutesAlias.CanteenInfo,
|
|
|
+ query: {
|
|
|
+ id: id
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const showDrawer = (row: Api.Canteen.ListItem): void => {
|
|
|
+ drawer.value = true;
|
|
|
+ currentRow.value = row
|
|
|
+}
|
|
|
+
|
|
|
+const showContact = (row: Api.Canteen.ListItem):void => {
|
|
|
+ router.push({
|
|
|
+ path: RoutesAlias.SchoolRelation,
|
|
|
+ query: {
|
|
|
+ school_id: row.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 删除
|
|
|
+ */
|
|
|
+const deleteUser = (id: number): void => {
|
|
|
+ ElMessageBox.confirm(`确定要删除该食堂吗?`, '删除食堂', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'error'
|
|
|
+ }).then(() => {
|
|
|
+ canteenApi.delete({id: id}).then(() => {
|
|
|
+ ElMessage.success(`${EmojiText[200]} 删除成功`)
|
|
|
+ setTimeout(() => {
|
|
|
+ getData()
|
|
|
+ }, 1000)
|
|
|
+ })
|
|
|
+ })
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.user-page {
|
|
|
+ :deep(.user) {
|
|
|
+ .avatar {
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ margin-left: 0;
|
|
|
+ border-radius: 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ > div {
|
|
|
+ margin-left: 10px;
|
|
|
+
|
|
|
+ .user-name {
|
|
|
+ font-weight: 500;
|
|
|
+ color: var(--art-text-gray-800);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.detail {
|
|
|
+ //padding-top: 20px;
|
|
|
+ font-size: 14px;
|
|
|
+ .el-col {
|
|
|
+ margin-bottom: 30px;
|
|
|
+ label {
|
|
|
+ font-weight: bold;
|
|
|
+ margin-right: 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|