【招生平台主控端】 优化# 移除无用代码
parent
ed0fc05be1
commit
13058f0936
|
@ -1,41 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { nextTick, unref, watch } from 'vue'
|
||||
import { useAreaMapOperation } from './hooks/useServiceArea';
|
||||
import { MAP_INJECTION_KEY } from '@/config/symbol'
|
||||
|
||||
const parentApi = inject(MAP_INJECTION_KEY)
|
||||
|
||||
const { mapRef, setMapCenter, drawPolygon, removePolygon, initPolygon } = useAreaMapOperation(parentApi)
|
||||
const isInited = computed(() => parentApi?.isInited.value)
|
||||
const location = computed(() => !isInited.value && parentApi?.address.value.location)
|
||||
|
||||
|
||||
watch(() => unref(parentApi?.address), ({ location }) => {
|
||||
if (isInited.value) return
|
||||
setMapCenter(location)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (isInited.value) return
|
||||
nextTick(() => setMapCenter(location.value))
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
setMapCenter,
|
||||
initPolygon,
|
||||
removePolygon,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="map">
|
||||
<div ref="mapRef" class="map__inner"></div>
|
||||
<div id="toolControl">
|
||||
<div class="toolItem" title="添加区域按钮" @click="drawPolygon"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/components/area-common/styles/map.scss';
|
||||
</style>
|
|
@ -1,52 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { watch, onMounted, type PropType } from 'vue'
|
||||
import area from '@/utils/area'
|
||||
import { MAP_INJECTION_KEY } from '@/config/symbol'
|
||||
|
||||
const cascaderProps = {
|
||||
checkStrictly: true,
|
||||
value: 'label'
|
||||
}
|
||||
const parentApi = inject(MAP_INJECTION_KEY)
|
||||
|
||||
const emit = defineEmits(['handleSearch'])
|
||||
|
||||
const form = reactive<{ area: string[] }>({
|
||||
area: [],
|
||||
})
|
||||
const isDisabled = computed(() => !form.area?.length)
|
||||
const isInited = computed(() => parentApi?.isInited.value)
|
||||
const location = computed(() => !isInited.value ? parentApi?.address.value.address_components : '')
|
||||
|
||||
onMounted(() => {
|
||||
if (isInited.value) return
|
||||
setCascaderValue(location.value)
|
||||
})
|
||||
|
||||
const handleSearch = async () => {
|
||||
emit('handleSearch', form)
|
||||
}
|
||||
function setCascaderValue(location: any) {
|
||||
const { province, city, district } = location
|
||||
form.area = [province, city, district]
|
||||
}
|
||||
defineExpose({
|
||||
setCascaderValue
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="area__search">
|
||||
<el-form :model="form" :inline="true">
|
||||
<el-form-item label="地区选择">
|
||||
<el-cascader v-model="form.area" :options="area" :props="cascaderProps" clearable>
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :disabled="isDisabled" @click="handleSearch">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -1,86 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { ElTable } from 'element-plus'
|
||||
import Pagination from '@/components/pagination/index.vue'
|
||||
import { MAP_INJECTION_KEY, type Pager } from '@/config/symbol'
|
||||
|
||||
interface TableProps {
|
||||
zone: String
|
||||
pager: Pager
|
||||
selectData?: any[]
|
||||
}
|
||||
const props = withDefaults(defineProps<TableProps>(), {
|
||||
pager: {}
|
||||
})
|
||||
const emit = defineEmits(['update:selectData', 'update:pager'])
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const parentApi = inject(MAP_INJECTION_KEY)
|
||||
|
||||
const tableRef = ref<InstanceType<typeof ElTable>>()
|
||||
|
||||
const tableData = computed(() => props.pager?.lists)
|
||||
const getLists = computed(() => props.pager?.getLists)
|
||||
const pathName = computed(() => route.meta.activeMenu)
|
||||
const originSelectData = computed(() => parentApi?.originSelectData?.value)
|
||||
const pager = computed({
|
||||
get() {
|
||||
return props.pager
|
||||
},
|
||||
set(newVal) {
|
||||
emit('update:pager', newVal)
|
||||
}
|
||||
})
|
||||
/**定位 */
|
||||
const handleLocation = (row: any) => {
|
||||
parentApi?.handleLocation(row)
|
||||
}
|
||||
/**删除 */
|
||||
const handleDelete = (id: number) => {
|
||||
parentApi?.handleDelete(id)
|
||||
}
|
||||
/**选中 */
|
||||
const handleSelectionChange = (val: any) => {
|
||||
emit('update:selectData', val)
|
||||
}
|
||||
/**初始化选中 */
|
||||
watch(() => unref(tableData), (val) => {
|
||||
if (val.length && props.selectData?.length) {
|
||||
parentApi?.toggleRowSelection!(originSelectData.value)
|
||||
}
|
||||
})
|
||||
defineExpose({
|
||||
tableRef
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="atable">
|
||||
<div class="atable__top">
|
||||
<span>{{ zone }}已有服务区域</span>
|
||||
</div>
|
||||
<div class="atable-bottom">
|
||||
<el-table ref="tableRef" :data="tableData" row-key="id" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" reserve-selection />
|
||||
<el-table-column prop="name" label="名称" />
|
||||
<el-table-column label="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="handleLocation(row)">定位</el-button>
|
||||
<el-button v-if="!pathName" link type="danger" @click="handleDelete(row.id)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="flex justify-end mt-4">
|
||||
<Pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.atable {
|
||||
background-color: #fff;
|
||||
// width: 450px;
|
||||
}
|
||||
</style>
|
|
@ -1,263 +0,0 @@
|
|||
import { nextTick, type Ref, unref, watch } from "vue"
|
||||
import { useRequest } from "@/hooks/useFetchData"
|
||||
import { usePaging } from "@/hooks/usePaging"
|
||||
import { addArea, apiMapLocation, delArea, getAreaListByLocation, getLonAndLatByArea } from "@/api/service/area"
|
||||
import type { Pager, Location } from '@/config/symbol'
|
||||
import { VITE_MAP_KEY } from "@/config/env"
|
||||
import { toast } from "@/utils/util"
|
||||
|
||||
/**用户操作 */
|
||||
export function useAreaOperation(inited = true) {
|
||||
const areaSearch = ref()
|
||||
const tcMap = ref()
|
||||
const zone = ref('') //地区
|
||||
const regionCode = ref() //地区编码
|
||||
const base = ref<Pager<any>>() //区域列表信息
|
||||
const address = ref() //当前地址信息
|
||||
const isInited = ref(true) //初始化
|
||||
|
||||
// 查询
|
||||
const handleSearch = (form: any) => {
|
||||
const params = {
|
||||
address: encodeURIComponent(form.area.join('')),
|
||||
key: VITE_MAP_KEY
|
||||
}
|
||||
const { runFn } = useRequest({
|
||||
apiFn: getLonAndLatByArea,
|
||||
onSuccess(response) {
|
||||
const { result: { location, address_components, ad_info } } = response
|
||||
searchCommon({ location, address_components, ad_info })
|
||||
},
|
||||
})
|
||||
runFn(params)
|
||||
}
|
||||
// 查询后操作
|
||||
const searchCommon = (payload: any) => {
|
||||
const { location, address_components, ad_info } = payload
|
||||
if (isInited.value) {
|
||||
tcMap.value?.setMapCenter(location)
|
||||
areaSearch.value?.setCascaderValue(address_components)
|
||||
}
|
||||
address.value = payload
|
||||
zone.value = address_components.district
|
||||
regionCode.value = ad_info.adcode
|
||||
fetchAreaList()
|
||||
}
|
||||
// 添加区域
|
||||
const increment = async (payload: any) => {
|
||||
const { runFn } = useRequest({
|
||||
apiFn: addArea,
|
||||
onSuccess(response) {
|
||||
tcMap.value.removePolygon()
|
||||
toast('添加成功', 'success')
|
||||
fetchAreaList()
|
||||
},
|
||||
})
|
||||
runFn(payload)
|
||||
}
|
||||
/**获取区域列表 */
|
||||
const fetchAreaList = async () => {
|
||||
const params = {
|
||||
regionId: regionCode.value
|
||||
}
|
||||
const { pager, getLists } = usePaging({
|
||||
fetchFun: getAreaListByLocation,
|
||||
params
|
||||
})
|
||||
await getLists()
|
||||
base.value = Object.assign(pager, {
|
||||
getLists
|
||||
})
|
||||
}
|
||||
/**初始化当前位置 */
|
||||
const initPosition = async () => {
|
||||
const params = { key: VITE_MAP_KEY }
|
||||
const { runFn } = useRequest({
|
||||
apiFn: apiMapLocation,
|
||||
onSuccess(response) {
|
||||
const { result: { location, ad_info } } = response
|
||||
searchCommon({ location, address_components: ad_info, ad_info })
|
||||
}
|
||||
})
|
||||
runFn(params)
|
||||
isInited.value = inited
|
||||
}
|
||||
|
||||
onMounted(initPosition)
|
||||
|
||||
return {
|
||||
tcMap,
|
||||
areaSearch,
|
||||
zone,
|
||||
regionCode,
|
||||
increment,
|
||||
searchCommon,
|
||||
handleSearch,
|
||||
base,
|
||||
address,
|
||||
isInited
|
||||
}
|
||||
}
|
||||
|
||||
/**表格操作 */
|
||||
export function useAreaTableOperation({ tcMap, base, aTable }: { tcMap: any, base: Ref<Pager>, aTable: any }) {
|
||||
|
||||
/**选中 */
|
||||
const toggleRowSelection = (selectData: any[]) => {
|
||||
const tableData = base.value.lists
|
||||
const selectedIds = selectData?.map(item => item.id) as number[]
|
||||
const selectedList = tableData.filter(data => selectedIds.includes(data.id))
|
||||
|
||||
tableData.forEach(data => {
|
||||
aTable.value.tableRef.toggleRowSelection(data, false)
|
||||
})
|
||||
selectedList.forEach(row => {
|
||||
aTable.value.tableRef.toggleRowSelection(row, true)
|
||||
})
|
||||
}
|
||||
/**定位 */
|
||||
const handleLocation = (row: any) => {
|
||||
const convertPolygons = row.polygongeo.replace("POLYGON((", '').replace("))", '').split(',')
|
||||
const polygonPaths = convertPolygons.map((path: string) => {
|
||||
const [lng, lat] = path.split(' ')
|
||||
return {
|
||||
lat: parseFloat(lat),
|
||||
lng: parseFloat(lng)
|
||||
}
|
||||
})
|
||||
|
||||
tcMap.value.initPolygon({
|
||||
polygonId: row.id,
|
||||
polygonPaths
|
||||
})
|
||||
}
|
||||
/**删除 */
|
||||
const handleDelete = async (id: number) => {
|
||||
const { runFn } = useRequest({
|
||||
apiFn: delArea,
|
||||
onSuccess(response) {
|
||||
toast('删除成功', 'success')
|
||||
base.value.getLists()
|
||||
}
|
||||
})
|
||||
runFn({ id })
|
||||
}
|
||||
|
||||
return {
|
||||
handleLocation,
|
||||
handleDelete,
|
||||
toggleRowSelection,
|
||||
}
|
||||
}
|
||||
|
||||
/**地图 */
|
||||
export function useAreaMapOperation(parentApi: any) {
|
||||
|
||||
let map, polygon, editor;
|
||||
const TMap = (window as any).TMap
|
||||
|
||||
const mapRef = ref()
|
||||
const drawId = ref([])
|
||||
|
||||
/**初始化地图 */
|
||||
function initMap() {
|
||||
map = new TMap.Map(mapRef.value, {
|
||||
zoom: 12,
|
||||
viewMode: '2D'
|
||||
})
|
||||
}
|
||||
/**设置地图中心 */
|
||||
function setMapCenter(location: Location) {
|
||||
const { lat, lng } = location
|
||||
map!.setCenter(new TMap.LatLng(lat, lng))
|
||||
}
|
||||
/**绘制多边形 */
|
||||
const drawPolygon = () => {
|
||||
polygon = new TMap.MultiPolygon({
|
||||
map: map
|
||||
})
|
||||
editor = new TMap.tools.GeometryEditor({
|
||||
map: map,
|
||||
overlayList: [
|
||||
{
|
||||
overlay: polygon,
|
||||
id: 'polygon',
|
||||
}
|
||||
],
|
||||
actionMode: TMap.tools.constants.EDITOR_ACTION.DRAW, // 编辑器的工作模式
|
||||
activeOverlayId: 'polygon', // 激活图层
|
||||
snappable: true,
|
||||
})
|
||||
editor.on('draw_complete', geometry => {
|
||||
drawId.value.push(geometry.id)
|
||||
geometry.paths.splice(geometry.paths.length, 0, geometry.paths[0])
|
||||
parentApi?.showDialog({
|
||||
polygonPaths: geometry.paths
|
||||
})
|
||||
})
|
||||
}
|
||||
/**表格定位=>初始化多边形 */
|
||||
function initPolygon({ polygonId, polygonPaths }: { polygonId: number, polygonPaths: Location[] }) {
|
||||
|
||||
if (polygonId === polygon?.id) return
|
||||
|
||||
polygon = new TMap.MultiPolygon({
|
||||
id: polygonId, // 图层id
|
||||
map: map, // 显示多边形图层的底图
|
||||
styles: {
|
||||
// 多边形的相关样式
|
||||
polygon: new TMap.PolygonStyle({
|
||||
color: 'rgb(250, 250, 122)', // 面填充色
|
||||
showBorder: false, // 是否显示拔起面的边线
|
||||
borderColor: '#00FFFF', // 边线颜色
|
||||
}),
|
||||
},
|
||||
geometries: [
|
||||
{
|
||||
id: 'polygon', // 多边形图形数据的标志信息
|
||||
styleId: 'polygon', // 样式id
|
||||
paths: polygonPaths, // 多边形的位置信息
|
||||
properties: {
|
||||
// 多边形的属性数据
|
||||
title: 'polygon',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
/**移除多边形 (先选中再删除)*/
|
||||
function removePolygon() {
|
||||
editor!.setActionMode(TMap.tools.constants.EDITOR_ACTION.INTERACT).select(drawId.value).setSelectable(true)
|
||||
editor!.delete()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(initMap)
|
||||
})
|
||||
|
||||
return {
|
||||
mapRef,
|
||||
setMapCenter,
|
||||
drawPolygon,
|
||||
removePolygon,
|
||||
initPolygon
|
||||
}
|
||||
}
|
||||
|
||||
/**弹框 */
|
||||
export function useDialogOperation(regionCode: Ref<number>) {
|
||||
const infoDialogRef = ref()
|
||||
|
||||
function showDialog(payload: any) {
|
||||
const params = {
|
||||
title: '绘制确认',
|
||||
rawData: { ...payload, regionCode: regionCode.value }
|
||||
}
|
||||
infoDialogRef.value.acceptParams(params)
|
||||
}
|
||||
|
||||
return {
|
||||
infoDialogRef,
|
||||
showDialog
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
.area {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 50px minmax(100px, auto);
|
||||
gap: 20px;
|
||||
|
||||
&__part {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr minmax(400px, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
.map {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
&__inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#toolControl {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
margin: auto;
|
||||
width: 252px;
|
||||
z-index: 1001;
|
||||
|
||||
.toolItem {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
float: left;
|
||||
margin: 1px;
|
||||
padding: 4px;
|
||||
border-radius: 3px;
|
||||
background-size: 30px 30px;
|
||||
background-position: 4px 4px;
|
||||
background-repeat: no-repeat;
|
||||
box-shadow: 0 1px 2px 0 #e4e7ef;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #ffffff;
|
||||
background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/polygon.png');
|
||||
background-position: center;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
<template>
|
||||
<div class="area-select">
|
||||
<el-cascader :style="{ width }" v-model="areaValue" :options="options" :props="props2" clearable></el-cascader>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import area from '@/utils/area'
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
/** Emit Start **/
|
||||
const emit = defineEmits(['update:province', 'update:city', 'update:district'])
|
||||
/** Emit End **/
|
||||
|
||||
/** Props Start **/
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
province?: any
|
||||
city: any
|
||||
district: any
|
||||
width?: string
|
||||
checkStrictly?: boolean
|
||||
}>(),
|
||||
{
|
||||
province: null,
|
||||
city: null,
|
||||
district: null,
|
||||
width: '340px',
|
||||
checkStrictly: true
|
||||
}
|
||||
)
|
||||
|
||||
const props2 = {
|
||||
checkStrictly: true
|
||||
}
|
||||
/** Props End **/
|
||||
|
||||
/** Data End **/
|
||||
const options = ref<any>(area) // 地区列表
|
||||
/** Data Start **/
|
||||
|
||||
/** Computed Start **/
|
||||
// 更新绑定数据
|
||||
const areaValue = computed({
|
||||
get: () => {
|
||||
return [props.province, props.city, props.district]
|
||||
},
|
||||
set: (value: any) => {
|
||||
emit('update:province', value ? value[0] : '')
|
||||
emit('update:city', value ? value[1] : '')
|
||||
emit('update:district', value ? value[2] : '')
|
||||
}
|
||||
})
|
||||
/** Computed Start **/
|
||||
</script>
|
|
@ -1,87 +0,0 @@
|
|||
<template>
|
||||
<popup class="inline mr-3" :clickModalClose="false" :title="`选择${setTitle}`" :center="true"
|
||||
@close="handleClose(channelFormRef)" @open="handleOpen" @confirm="handleConfirm" width="1200px">
|
||||
<template #trigger>
|
||||
<slot></slot>
|
||||
</template>
|
||||
<component :is="setComponent" ref="componentRef" />
|
||||
</popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, type PropType } from 'vue'
|
||||
import type { ElForm, FormInstance } from 'element-plus'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import distributeTable from './distributeTable.vue'
|
||||
import userTable from './userTable.vue'
|
||||
import { CHANNEL_INJECTION_KEY } from '@/config/symbol'
|
||||
import { ChannelEnum } from '@/enums/modeEnum'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: Object as PropType<any>
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const parent = inject(CHANNEL_INJECTION_KEY)
|
||||
const channel = computed(() => parent?.channel.value)
|
||||
const condition = computed(() => channel.value === ChannelEnum.DISTBUTOR)
|
||||
const setTitle = computed(() => unref(condition) ? '分销员' : '指定用户')
|
||||
const setComponent = computed(() => unref(condition) ? distributeTable : userTable) /**根据渠道切换组件 */
|
||||
const selectObj = computed(() => parent?.selectObj?.value)
|
||||
|
||||
const selectData = ref<Record<number, any[]>>({})
|
||||
const channelFormRef = ref<InstanceType<typeof ElForm>>()
|
||||
const componentRef = ref()
|
||||
|
||||
// 弹窗关闭
|
||||
const handleClose = (formEl: FormInstance | undefined): void => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
}
|
||||
// 确认选择
|
||||
const handleConfirm = (): void => {
|
||||
// 深度克隆防止数据串到父组件
|
||||
selectData.value = {}
|
||||
selectData.value[unref(channel)!] = selectObj.value![unref(channel)!]
|
||||
emit('update:modelValue', selectData.value)
|
||||
}
|
||||
|
||||
const handleOpen = () => {
|
||||
selectedTable()
|
||||
}
|
||||
/**表格选中效果 */
|
||||
function selectedTable() {
|
||||
setTimeout(() => {
|
||||
if (componentRef.value) {
|
||||
const tableData = componentRef.value.pager.lists as any[]
|
||||
const selectedIds = selectData.value[unref(channel)!]?.map(item => item.id) as number[]
|
||||
if (selectedIds) {
|
||||
const selectedList = tableData.filter(data => selectedIds.includes(data.id))
|
||||
tableData.forEach(data => {
|
||||
componentRef.value.tableDataRef?.toggleRowSelection(data, false)
|
||||
})
|
||||
selectedList.forEach(item => {
|
||||
componentRef.value.tableDataRef?.toggleRowSelection(item, true)
|
||||
})
|
||||
}
|
||||
}
|
||||
}, 50)
|
||||
}
|
||||
watch(() => unref(selectData), () => selectedTable(), { deep: true })
|
||||
watch(() => componentRef.value && unref(componentRef).pager.page, () => {
|
||||
selectData.value[unref(channel)!]?.length && selectedTable()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ls-input {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
:deep(.el-table__inner-wrapper) {
|
||||
height: 365px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
|
@ -1,107 +0,0 @@
|
|||
<!--
|
||||
* @Author: micky 1254597151@qq.com
|
||||
* @Date: 2023-09-16 16:26:07
|
||||
* @LastEditors: micky 1254597151@qq.com
|
||||
* @LastEditTime: 2023-09-18 15:15:05
|
||||
* @FilePath: \housekeeping-admin\src\components\channel-select-user\distributeTable.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<el-form :model="channelForm" ref="channelFormRef" :inline="true" label-width="auto">
|
||||
<el-form-item label="组别">
|
||||
<el-select v-model="channelForm.groupId" placeholder="请选择" class="ls-input">
|
||||
<el-option label="全部" value></el-option>
|
||||
<el-option
|
||||
v-for="group in groupLists"
|
||||
:key="group.id"
|
||||
:label="group.groupName"
|
||||
:value="group.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="分销员名称">
|
||||
<el-input
|
||||
class="ls-input"
|
||||
v-model="channelForm.name"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="分销员ID">
|
||||
<el-input
|
||||
class="ls-input"
|
||||
v-model="channelForm.distNum"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="getLists">查询</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div>
|
||||
<el-table
|
||||
ref="tableDataRef"
|
||||
:data="pager.lists"
|
||||
row-key="id"
|
||||
border
|
||||
style="width: 100%"
|
||||
height="500"
|
||||
@selection-change="parent?.handleSelectionChange"
|
||||
>
|
||||
<el-table-column
|
||||
type="selection"
|
||||
width="50"
|
||||
:reserve-selection="true"
|
||||
></el-table-column>
|
||||
<el-table-column property="groupName" label="组别" min-width="200" />
|
||||
<el-table-column property="name" label="分销员名称" min-width="160" />
|
||||
<el-table-column property="distNum" label="分销员ID" min-width="160" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="flex justify-end mt-3">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ElTable } from 'element-plus'
|
||||
import Pagination from '@/components/pagination/index.vue'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { useCommon } from '@/hooks/useCommon'
|
||||
import { apiDistributorLists } from '@/api/distributor/lists'
|
||||
import { CHANNEL_INJECTION_KEY } from '@/config/symbol'
|
||||
|
||||
const tableDataRef = ref<InstanceType<typeof ElTable>>()
|
||||
const channelForm = reactive({
|
||||
name: '',
|
||||
groupId: '',
|
||||
distNum: ''
|
||||
})
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
size: 10,
|
||||
fetchFun: apiDistributorLists,
|
||||
params: channelForm
|
||||
})
|
||||
const { groupLists, fetchGroupList } = useCommon()
|
||||
|
||||
const parent = inject(CHANNEL_INJECTION_KEY)
|
||||
|
||||
onMounted(() => {
|
||||
getLists()
|
||||
fetchGroupList()
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
tableDataRef,
|
||||
pager
|
||||
})
|
||||
</script>
|
||||
<style scoped>
|
||||
.ls-input {
|
||||
width: 210px;
|
||||
}
|
||||
</style>
|
|
@ -1,35 +0,0 @@
|
|||
<template>
|
||||
<div class="flex flex-col">
|
||||
<channel-popup v-model="selectData">
|
||||
<slot name="popup"></slot>
|
||||
</channel-popup>
|
||||
<table-detail v-model="selectData"></table-detail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { PropType } from 'vue'
|
||||
import channelPopup from './channel-popup.vue'
|
||||
import tableDetail from './table-detail.vue'
|
||||
import { CHANNEL_INJECTION_KEY } from '@/config/symbol'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Array as PropType<any>,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const parent = inject(CHANNEL_INJECTION_KEY)
|
||||
// const channel = computed(() => parent?.channel.value)
|
||||
|
||||
const selectData = ref<Record<number, any[]>>({})
|
||||
watch(
|
||||
() => unref(selectData),
|
||||
val => {
|
||||
emit('update:modelValue', unref(val))
|
||||
// emit('update:modelValue', val[unref(channel)!])
|
||||
}
|
||||
)
|
||||
</script>
|
|
@ -1,84 +0,0 @@
|
|||
<!--
|
||||
* @Author: micky 1254597151@qq.com
|
||||
* @Date: 2023-09-16 16:26:07
|
||||
* @LastEditors: micky 1254597151@qq.com
|
||||
* @LastEditTime: 2023-09-18 16:46:02
|
||||
* @FilePath: \housekeeping-admin\src\components\channel-select-user\table-detail.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<template>
|
||||
<div class="mt-5" v-if="selectData.length">
|
||||
<el-table ref="tableDataRef" :data="selectData" height="200">
|
||||
<el-table-column
|
||||
v-for="column in columns"
|
||||
:key="column.prop"
|
||||
:prop="column.prop"
|
||||
:label="column.label"
|
||||
width="160"
|
||||
:formatter="row => parseEmpty(row, column.prop)"
|
||||
/>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="scope">
|
||||
<div class="flex">
|
||||
<el-button type="primary" link @click="handleDeleteItem(scope.$index)">
|
||||
移除
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { CHANNEL_INJECTION_KEY } from '@/config/symbol';
|
||||
import { parseEmpty } from '@/utils/util'
|
||||
import { ChannelEnum } from '@/enums/modeEnum';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue?: any
|
||||
}>(),
|
||||
{
|
||||
modelValue: {},
|
||||
}
|
||||
)
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const parent = inject(CHANNEL_INJECTION_KEY)
|
||||
|
||||
const channel = computed(() => parent?.channel.value)
|
||||
const selectData: any = computed(() => props.modelValue[unref(channel)!] || [])
|
||||
|
||||
const columns = ref<any[]>([])
|
||||
/**生成column字段 */
|
||||
function generateColumns() {
|
||||
if (channel.value === ChannelEnum.DISTBUTOR) {
|
||||
columns.value = [
|
||||
{ prop: 'groupName', label: '组别' },
|
||||
{ prop: 'name', label: '分销员名称' },
|
||||
]
|
||||
} else {
|
||||
columns.value = [
|
||||
{ prop: 'nickname', label: '用户名称' },
|
||||
{ prop: 'username', label: '用户账号' },
|
||||
{ prop: 'mobile', label: '手机号码' },
|
||||
]
|
||||
}
|
||||
}
|
||||
/**切换渠道生成不同的column */
|
||||
watch(() => unref(channel), () => generateColumns(), { immediate: true })
|
||||
|
||||
const handleDeleteItem = (index: number) => {
|
||||
selectData.value.splice(index, 1)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.move {
|
||||
@media screen and (max-width: 1536px) {
|
||||
@apply overflow-scroll;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,74 +0,0 @@
|
|||
<!--
|
||||
* @Author: micky 1254597151@qq.com
|
||||
* @Date: 2023-09-16 16:26:07
|
||||
* @LastEditors: micky 1254597151@qq.com
|
||||
* @LastEditTime: 2023-09-18 15:14:26
|
||||
* @FilePath: \housekeeping-admin\src\components\channel-select-user\userTable.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<el-form :model="userForm" ref="channelFormRef" :inline="true" label-width="auto">
|
||||
<el-form-item label="用户信息">
|
||||
<el-input class="w-[300px]" v-model="userForm.keyword" placeholder="用户名称/用户账号/手机号码" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="getLists">搜索</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div>
|
||||
<el-table
|
||||
ref="tableDataRef"
|
||||
:data="pager.lists"
|
||||
row-key="id"
|
||||
border
|
||||
style="width: 100%"
|
||||
height="480"
|
||||
@selection-change="parent?.handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="50" :reserve-selection="true"></el-table-column>
|
||||
<el-table-column property="nickname" label="用户名称" min-width="200" />
|
||||
<el-table-column property="username" label="用户账号" min-width="160" />
|
||||
<el-table-column property="mobile" label="手机号码" min-width="160" :formatter="row => parseEmpty(row, 'mobile')" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="flex justify-end mt-3">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from 'vue'
|
||||
import type { ElTable } from 'element-plus'
|
||||
import Pagination from '@/components/pagination/index.vue'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { apiUserLists } from '@/api/user'
|
||||
import { parseEmpty } from '@/utils/util'
|
||||
import { CHANNEL_INJECTION_KEY } from '@/config/symbol'
|
||||
|
||||
const tableDataRef = ref<InstanceType<typeof ElTable>>()
|
||||
const userForm = reactive({
|
||||
keyword: '',
|
||||
type: 0
|
||||
})
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
size: 10,
|
||||
fetchFun: apiUserLists,
|
||||
params: userForm
|
||||
})
|
||||
const parent = inject(CHANNEL_INJECTION_KEY)
|
||||
|
||||
onMounted(getLists)
|
||||
|
||||
defineExpose({
|
||||
tableDataRef,
|
||||
pager
|
||||
})
|
||||
</script>
|
||||
<style scoped>
|
||||
.ls-input {
|
||||
width: 210px;
|
||||
}
|
||||
</style>
|
|
@ -1,30 +0,0 @@
|
|||
<template>
|
||||
<div class="footer-btns">
|
||||
<div class="footer-btns__content" :style="fixed ? 'position: fixed' : ''">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineProps({
|
||||
fixed: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.footer-btns {
|
||||
height: 65px;
|
||||
&__content {
|
||||
bottom: 0;
|
||||
height: 65px;
|
||||
right: 0;
|
||||
left: var(--aside-width);
|
||||
z-index: 999;
|
||||
@apply flex justify-center items-center shadow bg-body;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,191 +0,0 @@
|
|||
<template>
|
||||
<popup
|
||||
class="inline mr-3"
|
||||
:clickModalClose="false"
|
||||
title="选择服务"
|
||||
:center="true"
|
||||
@close="handleClose(serviceFormRef)"
|
||||
@confirm="handleConfirm"
|
||||
@open="handleOpen"
|
||||
width="1050px"
|
||||
>
|
||||
<template #trigger>
|
||||
<slot></slot>
|
||||
</template>
|
||||
<el-form :model="serviceForm" ref="serviceFormRef" :inline="true" label-width="auto">
|
||||
<el-form-item label="服务名称">
|
||||
<el-input
|
||||
class="ls-input"
|
||||
v-model="serviceForm.name"
|
||||
placeholder="请输入"
|
||||
clearable
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="服务分类">
|
||||
<el-select
|
||||
v-model="serviceForm.categoryId"
|
||||
placeholder="请选择"
|
||||
class="ls-input"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="category in categoryLists"
|
||||
:key="category.id"
|
||||
:label="category.name"
|
||||
:value="category.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="getLists">搜索</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div>
|
||||
<el-table
|
||||
ref="tableDataRef"
|
||||
:data="pager.lists"
|
||||
row-key="id"
|
||||
border
|
||||
style="width: 100%"
|
||||
@selection-change="handleSelectionChange"
|
||||
height="500"
|
||||
>
|
||||
<el-table-column
|
||||
type="selection"
|
||||
width="50"
|
||||
:reserve-selection="true"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
property="name"
|
||||
label="服务名称"
|
||||
min-width="200"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column property="image" label="服务图片" min-width="100">
|
||||
<template #default="scope">
|
||||
<div class="flex items-center">
|
||||
<el-image
|
||||
style="width: 48px; height: 48px"
|
||||
:src="scope.row.image"
|
||||
:fit="'cover'"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="category" label="服务分类" min-width="160" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="flex justify-end mt-3">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
</popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, watchEffect, ref, reactive } from 'vue'
|
||||
import type { ElForm, ElTable, FormInstance } from 'element-plus'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import Pagination from '@/components/pagination/index.vue'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { apiServiceLists } from '@/api/service/lists'
|
||||
import { deepClone } from '@/utils/util'
|
||||
import { CHANNEL_INJECTION_KEY } from '@/config/symbol'
|
||||
|
||||
interface serviceFormObj {
|
||||
name?: string
|
||||
status?: number | string
|
||||
categoryId: number | string
|
||||
}
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: any
|
||||
}>(),
|
||||
{
|
||||
modelValue: []
|
||||
}
|
||||
)
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const parent = inject(CHANNEL_INJECTION_KEY)
|
||||
const categoryLists = computed(() => parent?.categoryLists.value)
|
||||
|
||||
const serviceFormRef = ref<InstanceType<typeof ElForm>>()
|
||||
const tableDataRef = ref<InstanceType<typeof ElTable>>()
|
||||
const selectData = ref<Array<object> | null>(props.modelValue)
|
||||
const serviceForm = reactive<serviceFormObj>({
|
||||
name: '',
|
||||
status: '',
|
||||
categoryId: ''
|
||||
})
|
||||
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
size: 10,
|
||||
fetchFun: apiServiceLists,
|
||||
params: serviceForm
|
||||
})
|
||||
|
||||
// 表格多选选择的数据
|
||||
const handleSelectionChange = (val: Event | any) => {
|
||||
selectData.value = val
|
||||
}
|
||||
|
||||
// 弹窗关闭
|
||||
const handleClose = (formEl: FormInstance | undefined): void => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
}
|
||||
// 确认选择
|
||||
const handleConfirm = (): void => {
|
||||
// 深度克隆防止数据串到父组件
|
||||
emit('update:modelValue', deepClone(selectData.value))
|
||||
}
|
||||
|
||||
getLists()
|
||||
|
||||
watchEffect(() => {
|
||||
selectData.value = props.modelValue
|
||||
})
|
||||
|
||||
const handleOpen = () => {
|
||||
nextTick(() => selectTable())
|
||||
}
|
||||
/**表格选中效果 */
|
||||
function selectTable() {
|
||||
setTimeout(() => {
|
||||
const tableData = pager.lists
|
||||
const selectedIds = props.modelValue?.map((item: any) => item.id) as number[]
|
||||
const selectedList = tableData.filter(data => selectedIds.includes(data.id))
|
||||
/**避免tableDataRef为undefined */
|
||||
tableData.forEach(data => {
|
||||
tableDataRef.value?.toggleRowSelection(data, false)
|
||||
})
|
||||
selectedList.forEach(item => {
|
||||
tableDataRef.value?.toggleRowSelection(item, true)
|
||||
})
|
||||
}, 50)
|
||||
}
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
() => selectTable(),
|
||||
{ deep: true }
|
||||
)
|
||||
watch(
|
||||
() => pager.page,
|
||||
() => props.modelValue.length && selectTable()
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ls-input {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
:deep(.el-table__inner-wrapper) {
|
||||
height: 365px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
|
@ -1,41 +0,0 @@
|
|||
<template>
|
||||
<div class="flex flex-col">
|
||||
<good-popup v-model="selectData">
|
||||
<slot name="popup"></slot>
|
||||
</good-popup>
|
||||
<table-detail v-model="selectData" :disabled="disabled"></table-detail>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import goodPopup from './good-popup.vue'
|
||||
import tableDetail from './table-detail.vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue?: any
|
||||
selectData: any
|
||||
disabled?: boolean
|
||||
}>(),
|
||||
{
|
||||
modelValue: [],
|
||||
selectData: [],
|
||||
disabled: false
|
||||
}
|
||||
)
|
||||
const emit = defineEmits(['update:modelValue', 'update:selectData'])
|
||||
|
||||
const selectData: any = computed({
|
||||
get: () => {
|
||||
return props.selectData || []
|
||||
},
|
||||
set: (value) => {
|
||||
emit(
|
||||
'update:modelValue',
|
||||
value.map((item: Event | any) => item.id)
|
||||
)
|
||||
emit('update:selectData', value)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,71 +0,0 @@
|
|||
<!--
|
||||
* @Author: micky 1254597151@qq.com
|
||||
* @Date: 2023-09-16 16:26:07
|
||||
* @LastEditors: micky 1254597151@qq.com
|
||||
* @LastEditTime: 2023-09-18 16:48:12
|
||||
* @FilePath: \housekeeping-admin\src\components\good-select\table-detail.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<template>
|
||||
<div class="mt-5" v-if="selectData.length">
|
||||
<el-table ref="tableDataRef" :data="selectData" height="200">
|
||||
<el-table-column label="服务名称" width="240">
|
||||
<template #default="scope">
|
||||
<div class="flex items-center">
|
||||
<div class="w-[60px] h-[60px]">
|
||||
<el-image
|
||||
style="width: 60px; height: 60px"
|
||||
:src="scope.row.image"
|
||||
:fit="'cover'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<el-tooltip :content="scope.row.name" placement="top">
|
||||
<div class="ml-2 truncate">{{ scope.row.name }}</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="category" label="服务分类" width="200" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="scope">
|
||||
<div class="flex">
|
||||
<el-button type="primary" link @click="handleDeleteItem(scope.$index)"
|
||||
:disabled="disabled">移除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: any
|
||||
disabled: boolean
|
||||
}>(),
|
||||
{
|
||||
modelValue: [],
|
||||
disabled: false
|
||||
}
|
||||
)
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const selectData: any = computed(() => {
|
||||
return props.modelValue || []
|
||||
})
|
||||
const handleDeleteItem = (index: number) => {
|
||||
selectData.value.splice(index, 1)
|
||||
emit('update:modelValue', selectData.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.move {
|
||||
@media screen and (max-width: 1536px) {
|
||||
@apply overflow-scroll;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,55 +0,0 @@
|
|||
<template>
|
||||
<popup class="mr-2 flex" :clickModalClose="false" :title="title" :center="true" width="450px" confirmButtonText="" cancelButtonText="关闭">
|
||||
<template #trigger>
|
||||
<div>
|
||||
<el-button type="primary" link>{{ btnText }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="dataForm" ref="formRef" :inline="true" label-width="auto" :disabled="true">
|
||||
<el-form-item label="已提现金额">
|
||||
<el-input v-model="dataForm.alreadyWithdraw">
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="可提现金额">
|
||||
<el-input v-model="dataForm.canWithdrawCommission">
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="待结算金额">
|
||||
<el-input v-model="dataForm.toBeSettledMoney">
|
||||
<template #append>元</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, toRefs, onMounted } from 'vue'
|
||||
const title = ref('查看金额详情')
|
||||
const dataForm = reactive({
|
||||
alreadyWithdraw: '',
|
||||
canWithdrawCommission: '',
|
||||
toBeSettledMoney: ''
|
||||
})
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
rowData: any
|
||||
btnText: string
|
||||
}>(),
|
||||
{
|
||||
rowData: {},
|
||||
btnText: ''
|
||||
}
|
||||
)
|
||||
const showDetail = (row: any) => {
|
||||
const keys = Object.keys(dataForm)
|
||||
keys.map(key => {
|
||||
dataForm[key] = row[key] || '0'
|
||||
})
|
||||
title.value = `${row.name}-金额详情`
|
||||
}
|
||||
|
||||
showDetail(props.rowData)
|
||||
</script>
|
|
@ -1,54 +0,0 @@
|
|||
<!--
|
||||
* @Author: micky 1254597151@qq.com
|
||||
* @Date: 2023-08-14 15:56:31
|
||||
* @LastEditors: micky 1254597151@qq.com
|
||||
* @LastEditTime: 2023-09-04 17:26:11
|
||||
* @FilePath: \housekeeping-admin\src\components\service-area\index.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<!-- 服务选择框 Start -->
|
||||
<area-popup v-model="selectData">
|
||||
<slot name="popup"></slot>
|
||||
</area-popup>
|
||||
<!-- 服务选择框 End -->
|
||||
|
||||
<!-- Table Start -->
|
||||
<table-detail v-model="selectData" :disabled="disabled"></table-detail>
|
||||
<!-- Table End -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { withDefaults, computed } from 'vue'
|
||||
// import areaPopup from './area-popup.vue'
|
||||
import tableDetail from './table-detail.vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue?: any
|
||||
selectData: any
|
||||
disabled?: boolean
|
||||
}>(),
|
||||
{
|
||||
modelValue: [],
|
||||
selectData: [],
|
||||
disabled: false
|
||||
}
|
||||
)
|
||||
const emit = defineEmits(['update:modelValue', 'update:selectData'])
|
||||
|
||||
const selectData: any = computed({
|
||||
get: () => {
|
||||
return props.selectData || []
|
||||
},
|
||||
set: value => {
|
||||
emit(
|
||||
'update:modelValue',
|
||||
value.map((item: Event | any) => item.id)
|
||||
)
|
||||
emit('update:selectData', value)
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,43 +0,0 @@
|
|||
<template>
|
||||
<div class="mt-5" v-if="selectData.length">
|
||||
<el-table ref="tableDataRef" :data="selectData">
|
||||
<el-table-column property="name" label="服务区名称" width="240">
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="scope">
|
||||
<div class="flex">
|
||||
<el-button type="primary" link @click="handleDeleteItem(scope.$index)"
|
||||
:disabled="disabled">移除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, withDefaults } from 'vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: any
|
||||
disabled: boolean
|
||||
}>(),
|
||||
{
|
||||
modelValue: [],
|
||||
disabled: false
|
||||
}
|
||||
)
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const selectData: any = computed(() => {
|
||||
return props.modelValue || []
|
||||
})
|
||||
const handleDeleteItem = (index: number) => {
|
||||
selectData.value.splice(index, 1)
|
||||
emit('update:modelValue', selectData.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
<template>
|
||||
<div class="flex flex-col">
|
||||
<!-- 服务选择框 Start -->
|
||||
<service-popup v-model="selectData">
|
||||
<slot name="popup"></slot>
|
||||
</service-popup>
|
||||
<!-- 服务选择框 End -->
|
||||
|
||||
<!-- Table Start -->
|
||||
<table-detail v-model="selectData" :disabled="disabled"></table-detail>
|
||||
<!-- Table End -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { withDefaults, computed } from 'vue'
|
||||
import servicePopup from './service-popup.vue'
|
||||
import tableDetail from './table-detail.vue'
|
||||
|
||||
/** Props Start **/
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue?: any
|
||||
selectData: any
|
||||
disabled?: boolean
|
||||
}>(),
|
||||
{
|
||||
modelValue: [],
|
||||
selectData: [],
|
||||
disabled: false
|
||||
}
|
||||
)
|
||||
/** Props End **/
|
||||
|
||||
/** Emit Start **/
|
||||
const emit = defineEmits(['update:modelValue', 'update:selectData'])
|
||||
/** Emit End **/
|
||||
|
||||
/** Computed Start **/
|
||||
const selectData: any = computed({
|
||||
get: () => {
|
||||
return props.selectData || []
|
||||
},
|
||||
set: (value) => {
|
||||
emit(
|
||||
'update:modelValue',
|
||||
value.map((item: Event | any) => item.id)
|
||||
)
|
||||
emit('update:selectData', value)
|
||||
}
|
||||
})
|
||||
/** Computed End **/
|
||||
</script>
|
||||
|
||||
<!-- <style lang="scss" scoped>
|
||||
.move {
|
||||
@media screen and (max-width: 1536px) {
|
||||
@apply overflow-scroll;
|
||||
}
|
||||
}
|
||||
</style> -->
|
|
@ -1,170 +0,0 @@
|
|||
<template>
|
||||
<popup class="inline mr-3" :clickModalClose="false" title="选择服务" :center="true" @close="handleClose(serviceFormRef)"
|
||||
@confirm="handleConfirm" @open="toggleSelection" width="1150px">
|
||||
<!-- Trigger Start -->
|
||||
<template #trigger>
|
||||
<!-- trigger -->
|
||||
<slot></slot>
|
||||
</template>
|
||||
<!-- Trigger End -->
|
||||
|
||||
<!-- Form Start -->
|
||||
<el-form :model="serviceForm" ref="serviceFormRef" :inline="true" label-width="auto">
|
||||
<el-form-item label="服务名称">
|
||||
<el-input class="ls-input" v-model="serviceForm.name" placeholder="请输入"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="serviceForm.status" placeholder="请选择" class="ls-input">
|
||||
<el-option label="全部" value></el-option>
|
||||
<el-option label="销售中" value="1"></el-option>
|
||||
<el-option label="仓库中" value="0"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="getLists">搜索</el-button>
|
||||
<el-button @click="resetParams">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- Form End -->
|
||||
|
||||
<!-- Table Start -->
|
||||
<div>
|
||||
<el-table ref="tableDataRef" :data="pager.lists" :row-key="getRowKeys" border style="width: 100%">
|
||||
<el-table-column type="selection" width="50" :reserve-selection="true"></el-table-column>
|
||||
<el-table-column label="服务名称" min-width="200">
|
||||
<template #default="scope">
|
||||
<div class="flex items-center">
|
||||
<el-image style="width: 48px; height: 48px" :src="scope.row.image" :fit="'cover'" />
|
||||
|
||||
<el-tooltip :content="scope.row.name" placement="top">
|
||||
<div class="w-16 ml-2 truncate">{{ scope.row.name }}</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="category" label="服务分类" min-width="160" />
|
||||
<el-table-column property="price" label="价格" min-width="100" />
|
||||
<el-table-column property="unit" label="单位" min-width="100" />
|
||||
<el-table-column property="statusDesc" label="状态" min-width="120">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" v-if="scope.row.status == 1">销售中</el-tag>
|
||||
<el-tag type="info" v-if="scope.row.status == 0">仓库中</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="createTime" label="创建日期" min-width="170" />
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- Table End -->
|
||||
|
||||
<!-- Footer Pagination Start -->
|
||||
<div class="flex justify-end mt-2">
|
||||
<pagination v-model="pager" @change="getLists" />
|
||||
</div>
|
||||
<!-- Footer Pagination End -->
|
||||
</popup>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { apiServiceLists } from '@/api/service/lists'
|
||||
import Popup from '@/components/popup/index.vue'
|
||||
import Pagination from '@/components/pagination/index.vue'
|
||||
import type { ElForm } from 'element-plus'
|
||||
import { ElTable } from 'element-plus'
|
||||
import { usePaging } from '@/hooks/usePaging'
|
||||
import { deepClone } from '@/utils/util'
|
||||
import { computed, withDefaults, watchEffect, ref, reactive } from 'vue'
|
||||
|
||||
interface serviceFormObj {
|
||||
name?: string
|
||||
status?: number | string
|
||||
}
|
||||
type FormInstance = InstanceType<typeof ElForm>
|
||||
const serviceFormRef = ref<FormInstance>()
|
||||
const tableDataRef = ref<InstanceType<typeof ElTable>>()
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: any
|
||||
}>(),
|
||||
{
|
||||
modelValue: []
|
||||
}
|
||||
)
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const selectData = ref<Array<object> | null>(props.modelValue)
|
||||
const serviceForm = reactive<serviceFormObj>({
|
||||
name: '',
|
||||
status: '1'
|
||||
})
|
||||
|
||||
const toggleSelection = () => {
|
||||
if (selectData.value!.length !== 0) {
|
||||
pager.lists.forEach(item => {
|
||||
tableDataRef.value?.toggleRowSelection(item, false)
|
||||
})
|
||||
; (selectData.value as []).forEach((item: any) => {
|
||||
try {
|
||||
pager.lists.forEach(listItem => {
|
||||
setTimeout(() => {
|
||||
if (listItem.id == item.id) {
|
||||
tableDataRef?.value?.toggleRowSelection(listItem, true) //让页面显示选中的数据
|
||||
// throw Error() //通过抛出异常跳过foreach循环
|
||||
}
|
||||
})
|
||||
})
|
||||
} catch { }
|
||||
})
|
||||
} else {
|
||||
tableDataRef.value?.clearSelection()
|
||||
}
|
||||
}
|
||||
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||||
size: 10,
|
||||
fetchFun: apiServiceLists,
|
||||
params: serviceForm,
|
||||
nextFetchFun: toggleSelection
|
||||
})
|
||||
|
||||
// 表格多选选择的数据
|
||||
// const handleSelectionChange = (val: Event | any) => {
|
||||
// selectData.value = [...val]
|
||||
// console.log('selectData.value', val)
|
||||
// }
|
||||
|
||||
// 弹窗关闭
|
||||
const handleClose = (formEl: FormInstance | undefined): void => {
|
||||
if (!formEl) return
|
||||
formEl.resetFields()
|
||||
}
|
||||
// 确认选择
|
||||
const handleConfirm = (): void => {
|
||||
// 深度克隆防止数据串到父组件
|
||||
emit('update:modelValue', tableDataRef?.value?.getSelectionRows())
|
||||
}
|
||||
|
||||
getLists()
|
||||
|
||||
watchEffect(() => {
|
||||
selectData.value = props.modelValue
|
||||
})
|
||||
|
||||
// 用于跨页多选
|
||||
const getRowKeys = row => {
|
||||
return row.id
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ls-input {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
:deep(.el-table__inner-wrapper) {
|
||||
height: 565px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
|
@ -1,91 +0,0 @@
|
|||
<!--
|
||||
* @Author: micky 1254597151@qq.com
|
||||
* @Date: 2023-08-14 15:56:31
|
||||
* @LastEditors: micky 1254597151@qq.com
|
||||
* @LastEditTime: 2023-09-12 12:13:41
|
||||
* @FilePath: \housekeeping-admin\src\components\service-select\table-detail.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<template>
|
||||
<div class="mt-5" v-if="selectData.length">
|
||||
<el-table ref="tableDataRef" :data="selectData">
|
||||
<el-table-column label="服务名称" width="240">
|
||||
<template #default="scope">
|
||||
<div class="flex items-center">
|
||||
<div class="w-[60px] h-[60px]">
|
||||
<el-image style="width: 60px; height: 60px" :src="scope.row.image" :fit="'cover'" />
|
||||
</div>
|
||||
|
||||
<el-tooltip :content="scope.row.name" placement="top">
|
||||
<div class="ml-2 truncate">{{ scope.row.name }}</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column property="category" label="服务分类" width="200" />
|
||||
<el-table-column property="price" label="价格" width="120" />
|
||||
<el-table-column property="unit" label="单位" width="220" />
|
||||
<el-table-column property="statusDesc" label="销售状态" width="200">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" v-if="scope.row.status == 1">销售中</el-tag>
|
||||
<el-tag type="info" v-if="scope.row.status == 0">仓库中</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建日期" min-width="205" />
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="scope">
|
||||
<div class="flex">
|
||||
<el-button type="primary" link @click="handleDeleteItem(scope.$index)" :disabled="disabled">移除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, withDefaults } from 'vue'
|
||||
|
||||
/** Props Start **/
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: any
|
||||
disabled: boolean
|
||||
}>(),
|
||||
{
|
||||
modelValue: [],
|
||||
disabled: false
|
||||
}
|
||||
)
|
||||
/** Props End **/
|
||||
|
||||
/** Emit Start **/
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
/** Emit End **/
|
||||
|
||||
/** Computed Start **/
|
||||
const selectData: any = computed(() => {
|
||||
return props.modelValue || []
|
||||
})
|
||||
/** Computed End **/
|
||||
|
||||
/** Methods Start **/
|
||||
const handleDeleteItem = (index: number) => {
|
||||
selectData.value.splice(index, 1)
|
||||
emit('update:modelValue', selectData.value)
|
||||
}
|
||||
/** Methods End **/
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.move {
|
||||
@media screen and (max-width: 1536px) {
|
||||
@apply overflow-scroll;
|
||||
}
|
||||
}
|
||||
:deep(.el-table) {
|
||||
max-height: 565px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue