提交 76665f78 authored 作者: 王鹏飞's avatar 王鹏飞

chore update

上级 730d3267
...@@ -27,12 +27,12 @@ ...@@ -27,12 +27,12 @@
"ali-oss": "^6.17.1", "ali-oss": "^6.17.1",
"chalk": "^5.1.2", "chalk": "^5.1.2",
"eslint": "^8.26.0", "eslint": "^8.26.0",
"eslint-plugin-vue": "^9.6.0", "eslint-plugin-vue": "^9.7.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"sass": "^1.55.0", "sass": "^1.55.0",
"typescript": "~4.8.4", "typescript": "~4.8.4",
"unplugin-auto-import": "^0.11.4", "unplugin-auto-import": "^0.11.4",
"vite": "^3.2.1", "vite": "^3.2.2",
"vue-tsc": "^1.0.9" "vue-tsc": "^1.0.9"
} }
}, },
...@@ -1945,9 +1945,9 @@ ...@@ -1945,9 +1945,9 @@
} }
}, },
"node_modules/eslint-plugin-vue": { "node_modules/eslint-plugin-vue": {
"version": "9.6.0", "version": "9.7.0",
"resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.6.0.tgz", "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.7.0.tgz",
"integrity": "sha512-zzySkJgVbFCylnG2+9MDF7N+2Rjze2y0bF8GyUNpFOnT8mCMfqqtLDJkHBuYu9N/psW1A6DVbQhPkP92E+qakA==", "integrity": "sha512-DrOO3WZCZEwcLsnd3ohFwqCoipGRSTKTBTnLwdhqAbYZtzWl0o7D+D8ZhlmiZvABKTEl8AFsqH1GHGdybyoQmw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
...@@ -4840,9 +4840,9 @@ ...@@ -4840,9 +4840,9 @@
} }
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "3.2.1", "version": "3.2.2",
"resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.1.tgz", "resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.2.tgz",
"integrity": "sha512-ADtMkfHuWq4tskJsri2n2FZkORO8ZyhI+zIz7zTrDAgDEtct1jdxOg3YsZBfHhKjmMoWLOSCr+64qrEDGo/DbQ==", "integrity": "sha512-pLrhatFFOWO9kS19bQ658CnRYzv0WLbsPih6R+iFeEEhDOuYgYCX2rztUViMz/uy/V8cLCJvLFeiOK7RJEzHcw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"esbuild": "^0.15.9", "esbuild": "^0.15.9",
...@@ -6555,9 +6555,9 @@ ...@@ -6555,9 +6555,9 @@
} }
}, },
"eslint-plugin-vue": { "eslint-plugin-vue": {
"version": "9.6.0", "version": "9.7.0",
"resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.6.0.tgz", "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.7.0.tgz",
"integrity": "sha512-zzySkJgVbFCylnG2+9MDF7N+2Rjze2y0bF8GyUNpFOnT8mCMfqqtLDJkHBuYu9N/psW1A6DVbQhPkP92E+qakA==", "integrity": "sha512-DrOO3WZCZEwcLsnd3ohFwqCoipGRSTKTBTnLwdhqAbYZtzWl0o7D+D8ZhlmiZvABKTEl8AFsqH1GHGdybyoQmw==",
"dev": true, "dev": true,
"requires": { "requires": {
"eslint-utils": "^3.0.0", "eslint-utils": "^3.0.0",
...@@ -8859,9 +8859,9 @@ ...@@ -8859,9 +8859,9 @@
} }
}, },
"vite": { "vite": {
"version": "3.2.1", "version": "3.2.2",
"resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.1.tgz", "resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.2.tgz",
"integrity": "sha512-ADtMkfHuWq4tskJsri2n2FZkORO8ZyhI+zIz7zTrDAgDEtct1jdxOg3YsZBfHhKjmMoWLOSCr+64qrEDGo/DbQ==", "integrity": "sha512-pLrhatFFOWO9kS19bQ658CnRYzv0WLbsPih6R+iFeEEhDOuYgYCX2rztUViMz/uy/V8cLCJvLFeiOK7RJEzHcw==",
"dev": true, "dev": true,
"requires": { "requires": {
"esbuild": "^0.15.9", "esbuild": "^0.15.9",
......
...@@ -33,12 +33,12 @@ ...@@ -33,12 +33,12 @@
"ali-oss": "^6.17.1", "ali-oss": "^6.17.1",
"chalk": "^5.1.2", "chalk": "^5.1.2",
"eslint": "^8.26.0", "eslint": "^8.26.0",
"eslint-plugin-vue": "^9.6.0", "eslint-plugin-vue": "^9.7.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"sass": "^1.55.0", "sass": "^1.55.0",
"typescript": "~4.8.4", "typescript": "~4.8.4",
"unplugin-auto-import": "^0.11.4", "unplugin-auto-import": "^0.11.4",
"vite": "^3.2.1", "vite": "^3.2.2",
"vue-tsc": "^1.0.9" "vue-tsc": "^1.0.9"
} }
} }
import AppCard from '@/components/base/AppCard.vue' import AppCard from '@/components/base/AppCard.vue'
import AppList from '@/components/base/AppList.vue' import AppList from '@/components/base/AppList.vue'
import AppUpload from '@/components/base/AppUpload.vue'
declare module 'vue' { declare module '@vue/runtime-core' {
export interface GlobalComponents { export interface GlobalComponents {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
AppCard: typeof AppCard AppCard: typeof AppCard
AppList: typeof AppList AppList: typeof AppList
AppUpload: typeof AppUpload
} }
} }
...@@ -8,26 +8,22 @@ interface IRemoteProps { ...@@ -8,26 +8,22 @@ interface IRemoteProps {
callback?: any callback?: any
} }
const props = withDefaults( interface Props {
defineProps<{ remote?: IRemoteProps
remote?: IRemoteProps filters?: any[]
filters?: any[] filterForm?: any
moreFilters?: any[] columns?: any[]
columns?: any[] data?: any[]
data?: any[] hasPagination?: boolean
hasPagination?: boolean limit?: number
limit?: number }
isLimit?: boolean const props = withDefaults(defineProps<Props>(), {
}>(), hasPagination: true,
{ limit: 10,
isLimit: false, filters: () => [],
hasPagination: true, columns: () => [],
limit: 10, data: () => []
data() { })
return []
}
}
)
const filterFormRef = ref() const filterFormRef = ref()
const loading = ref(false) const loading = ref(false)
...@@ -36,13 +32,12 @@ const dataList = ref<any[]>([]) ...@@ -36,13 +32,12 @@ const dataList = ref<any[]>([])
const page = reactive({ total: 0, size: props.limit, currentPage: 1 }) const page = reactive({ total: 0, size: props.limit, currentPage: 1 })
const params = reactive({ ...props.remote?.params }) const params = reactive({ ...props.remote?.params })
watch( watchEffect(() => {
() => props.data, Object.assign(params, props.remote?.params)
list => { })
dataList.value = list || [] watchEffect(() => {
}, dataList.value = props.data || []
{ immediate: true } })
)
// 获取数据 // 获取数据
const fetchList = (isReset = false) => { const fetchList = (isReset = false) => {
...@@ -60,11 +55,7 @@ const fetchList = (isReset = false) => { ...@@ -60,11 +55,7 @@ const fetchList = (isReset = false) => {
// 翻页参数设置 // 翻页参数设置
if (props.hasPagination) { if (props.hasPagination) {
requestParams.page = page.currentPage requestParams.page = page.currentPage
if (props.isLimit === true) { requestParams['per-page'] = page.size
requestParams.limit = page.size
} else {
requestParams['per-page'] = page.size
}
} }
// 接口请求之前 // 接口请求之前
if (beforeRequest) { if (beforeRequest) {
...@@ -80,7 +71,7 @@ const fetchList = (isReset = false) => { ...@@ -80,7 +71,7 @@ const fetchList = (isReset = false) => {
httpRequest(requestParams) httpRequest(requestParams)
.then((res: any) => { .then((res: any) => {
const { list = [], total = 0 } = callback ? callback(res.data, requestParams) : res.data || {} const { list = [], total = 0 } = callback ? callback(res.data, requestParams) : res.data || {}
page.total = total page.total = parseInt(total)
dataList.value = list dataList.value = list
}) })
// .catch(() => { // .catch(() => {
...@@ -125,7 +116,7 @@ onMounted(() => { ...@@ -125,7 +116,7 @@ onMounted(() => {
fetchList() fetchList()
}) })
defineExpose({ refetch, tableRef, params }) defineExpose({ refetch, tableRef })
</script> </script>
<template> <template>
...@@ -133,7 +124,7 @@ defineExpose({ refetch, tableRef, params }) ...@@ -133,7 +124,7 @@ defineExpose({ refetch, tableRef, params })
<div class="table-list-hd"> <div class="table-list-hd">
<!-- 筛选 --> <!-- 筛选 -->
<div class="table-list-filter" v-if="filters && filters.length"> <div class="table-list-filter" v-if="filters && filters.length">
<el-form :inline="true" :model="params" ref="filterFormRef" @submit.prevent> <el-form :inline="true" :model="params" v-bind="filterForm" ref="filterFormRef" @submit.prevent>
<template v-for="item in filters" :key="item.prop"> <template v-for="item in filters" :key="item.prop">
<el-form-item :label="item.label" :prop="item.prop"> <el-form-item :label="item.label" :prop="item.prop">
<template v-if="item.slots"> <template v-if="item.slots">
...@@ -147,23 +138,20 @@ defineExpose({ refetch, tableRef, params }) ...@@ -147,23 +138,20 @@ defineExpose({ refetch, tableRef, params })
clearable clearable
@change="search" @change="search"
style="width: 200px" style="width: 200px"
v-if="item.type === 'input'" v-if="item.type === 'input'" />
/>
<!-- select --> <!-- select -->
<el-select <el-select
v-model="params[item.prop]" v-model="params[item.prop]"
v-bind="item" v-bind="item"
filterable
clearable clearable
@change="search" @change="search"
v-if="item.type === 'select'" v-if="item.type === 'select'">
style="width: 200px"
>
<el-option <el-option
:label="option[item.labelKey] || option.label" :label="option[item.labelKey] || option.label"
:value="option[item.valueKey] || option.value" :value="option[item.valueKey] || option.value"
v-for="(option, index) in item.options" v-for="(option, index) in item.options"
:key="index" :key="index" />
/>
</el-select> </el-select>
</template> </template>
</el-form-item> </el-form-item>
...@@ -174,21 +162,21 @@ defineExpose({ refetch, tableRef, params }) ...@@ -174,21 +162,21 @@ defineExpose({ refetch, tableRef, params })
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="table-list-hd-aside"><slot name="header-aside" /></div> <!-- <div class="table-list-hd-aside"><slot name="header-aside" /></div> -->
</div> </div>
<div class="table-list-buttons"><slot name="header-buttons"></slot></div>
<slot></slot> <slot></slot>
<!-- 主体 --> <!-- 主体 -->
<div class="table-list-bd"> <div class="table-list-bd">
<slot name="body" v-bind="{ data: dataList }"> <slot name="body" v-bind="{ data: dataList }">
<el-table <el-table
stripe
:header-cell-style="{ background: '#ededed' }"
:data="dataList" :data="dataList"
v-loading="loading" v-loading="loading"
v-bind="$attrs" v-bind="$attrs"
style="height: 100%" ref="tableRef">
ref="tableRef" <el-table-column align="center" v-bind="item || {}" v-for="item in columns" :key="item.prop">
:header-cell-style="{ background: '#EFEFEF' }"
>
<el-table-column v-bind="item || {}" v-for="item in columns" :key="item.prop">
<template #default="scope" v-if="item.slots || item.computed"> <template #default="scope" v-if="item.slots || item.computed">
<slot :name="item.slots" v-bind="scope" v-if="item.slots"></slot> <slot :name="item.slots" v-bind="scope" v-if="item.slots"></slot>
<div v-html="item.computed(scope)" v-if="item.computed"></div> <div v-html="item.computed(scope)" v-if="item.computed"></div>
...@@ -213,8 +201,7 @@ defineExpose({ refetch, tableRef, params }) ...@@ -213,8 +201,7 @@ defineExpose({ refetch, tableRef, params })
@size-change="pageSizeChange" @size-change="pageSizeChange"
@current-change="fetchList()" @current-change="fetchList()"
:hide-on-single-page="true" :hide-on-single-page="true"
v-if="hasPagination" v-if="hasPagination">
>
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
...@@ -230,10 +217,22 @@ defineExpose({ refetch, tableRef, params }) ...@@ -230,10 +217,22 @@ defineExpose({ refetch, tableRef, params })
.table-list-hd { .table-list-hd {
display: flex; display: flex;
margin-bottom: 10px; margin-bottom: 20px;
&:empty {
display: none;
}
} }
.table-list-filter { .table-list-filter {
flex: 1; flex: 1;
// padding: 30px 30px 10px;
// background: #f8f8f8;
// border-radius: 12px;
}
.table-list-buttons {
margin-bottom: 20px;
&:empty {
display: none;
}
} }
// .table-list-bd { // .table-list-bd {
// flex: 1; // flex: 1;
...@@ -250,4 +249,8 @@ defineExpose({ refetch, tableRef, params }) ...@@ -250,4 +249,8 @@ defineExpose({ refetch, tableRef, params })
.el-table-column--selection .cell { .el-table-column--selection .cell {
padding: 0 14px !important; padding: 0 14px !important;
} }
.el-button a {
margin: -8px -15px;
padding: 8px 15px;
}
</style> </style>
<script setup lang="ts"></script>
<template>
<el-dialog title="选择标签" width="400px" :close-on-click-modal="false"></el-dialog>
</template>
<script setup lang="ts"></script>
<template>
<el-dialog title="生成二维码">
<el-form>
<el-form-item label="选择项目">
<el-select></el-select>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script setup lang="ts"></script> <script setup lang="ts">
import AppList from '@/components/base/AppList.vue'
const Label = defineAsyncComponent(() => import('../components/Label.vue'))
const QRCode = defineAsyncComponent(() => import('../components/QRCode.vue'))
const appList = $ref<InstanceType<typeof AppList> | null>(null)
const listOptions = computed(() => {
return {
filters: [
{ type: 'input', prop: 'code', placeholder: '渠道编号' },
{ type: 'input', prop: 'code', placeholder: '渠道名称' },
{ type: 'input', prop: 'code', placeholder: '公司字号' },
{ type: 'select', prop: 'code', placeholder: '渠道标签' },
{ type: 'select', prop: 'code', placeholder: '呼叫状态' },
{ type: 'select', prop: 'code', placeholder: '回抽状态' },
{ type: 'select', prop: 'code', placeholder: '渠道质量' }
],
columns: [
{ label: '渠道编号', prop: 'name' },
{ label: '渠道名称', prop: 'name' },
{ label: '渠道标签', prop: 'name' },
{ label: '归属人', prop: 'name' },
{ label: '渠道类型', prop: 'name' },
{ label: '状态', prop: 'name' },
{ label: '更新时间', prop: 'name' },
{ label: '操作', prop: 'name', slots: 'table-x' }
],
data: [{}]
}
})
const labelVisible = $ref(true)
</script>
<template> <template>
<AppCard title="渠道管理"></AppCard> <AppCard title="渠道管理">
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<el-button type="primary">创建渠道</el-button>
<el-button type="primary">添加标签</el-button>
<el-button type="primary">选择标签</el-button>
<el-button type="primary">取消</el-button>
</template>
<template #table-x>
<el-link type="info">查看</el-link>
<el-link>编辑</el-link>
<el-link>添加成员</el-link>
<el-link>二维码</el-link>
<el-link type="danger">删除</el-link>
</template>
</AppList>
</AppCard>
<Label v-model="labelVisible"></Label>
<QRCode></QRCode>
</template> </template>
<script setup lang="ts"></script>
<template>
<AppCard title="创建项目">
<el-card shadow="never"> Never </el-card>
</AppCard>
</template>
<script setup lang="ts"></script>
<template>
<el-card shadow="never" header="基本信息"></el-card>
</template>
<script setup lang="ts"></script>
<template>
<el-card shadow="never" header="成员信息"></el-card>
</template>
...@@ -5,6 +5,11 @@ export const routes: Array<RouteRecordRaw> = [ ...@@ -5,6 +5,11 @@ export const routes: Array<RouteRecordRaw> = [
{ {
path: '/base/project', path: '/base/project',
component: AppLayout, component: AppLayout,
children: [{ path: '', component: () => import('./views/Index.vue') }] children: [
{ path: '', component: () => import('./views/Index.vue') },
{ path: 'create', component: () => import('./views/Update.vue'), props: { isAdd: true } },
{ path: 'update/:id', component: () => import('./views/Update.vue'), props: { isUpdate: true } },
{ path: 'view/:id', component: () => import('./views/Update.vue'), props: { isView: true } }
]
} }
] ]
<script setup lang="ts"></script> <script setup lang="ts">
import AppList from '@/components/base/AppList.vue'
const appList = $ref<InstanceType<typeof AppList> | null>(null)
const listOptions = computed(() => {
return {
filters: [
{ type: 'input', prop: 'code', placeholder: '项目编号' },
{ type: 'input', prop: 'code', placeholder: '项目名称' },
{ type: 'select', prop: 'code', placeholder: '项目类型' },
{ type: 'select', prop: 'code', placeholder: '状态' }
],
columns: [
{ label: '项目编号', prop: 'name' },
{ label: '项目名称', prop: 'name' },
{ label: '项目网址', prop: 'name' },
{ label: '项目类型', prop: 'name' },
{ label: '状态', prop: 'name' },
{ label: '更新时间', prop: 'name' },
{ label: '操作', prop: 'name', slots: 'table-x' }
],
data: [{}]
}
})
</script>
<template> <template>
<AppCard title="渠道管理"></AppCard> <AppCard title="项目管理">
<AppList v-bind="listOptions" ref="appList">
<template #header-buttons>
<router-link to="/base/project/create">
<el-button type="primary">创建项目</el-button>
</router-link>
<el-button type="primary">添加标签</el-button>
<el-button type="primary">选择标签</el-button>
<el-button type="primary">取消</el-button>
</template>
<template #table-x>
<el-link type="info">查看</el-link>
<el-link>编辑</el-link>
<el-link>添加成员</el-link>
<el-link type="danger">删除</el-link>
</template>
</AppList>
</AppCard>
</template> </template>
<script setup lang="ts">
import InfoBase from '../components/InfoBase.vue'
import InfoMembers from '../components/InfoMembers.vue'
interface Props {
isAdd?: boolean
isUpdate?: boolean
isView?: boolean
}
const props = defineProps<Props>()
const title = $computed(() => {
return (props.isAdd && '创建项目') || (props.isUpdate && '编辑项目') || (props.isView && '查看项目') || ''
})
</script>
<template>
<AppCard :title="title">
<InfoBase style="margin: 20px 0"></InfoBase>
<InfoMembers></InfoMembers>
</AppCard>
</template>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论