feat:【antd】【mp】mp 的代码评审(draft)
This commit is contained in:
@@ -187,8 +187,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- TODO @hw:按照微信群沟通的,换下卡片的样式。 -->
|
||||||
<template #content="{ row }">
|
<template #content="{ row }">
|
||||||
<DraftTableCell :row="row" />
|
<DraftTableCell :row="row" />
|
||||||
|
<!-- TODO @hw:增加一列,更新时间。 -->
|
||||||
</template>
|
</template>
|
||||||
<template #actions="{ row }">
|
<template #actions="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ function onUploadError(err: Error) {
|
|||||||
支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M
|
支持 bmp/png/jpeg/jpg/gif 格式,大小不超过 2M
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- TODO @hw:这个貌似不行;ele 我试了下,可以的 -->
|
||||||
<Modal
|
<Modal
|
||||||
v-model:open="dialogVisible"
|
v-model:open="dialogVisible"
|
||||||
title="图片选择"
|
title="图片选择"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { MpDraftApi } from '#/api/mp/draft';
|
|||||||
|
|
||||||
import { WxNews } from '#/views/mp/components';
|
import { WxNews } from '#/views/mp/components';
|
||||||
|
|
||||||
|
// TODO @hw:按照微信里说的,感觉这个可以干掉。少点组件哈。= = mp 模块,小组件可太多了。。。
|
||||||
defineOptions({ name: 'DraftTableCell' });
|
defineOptions({ name: 'DraftTableCell' });
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ function plusNews() {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- TODO @hw:1)每个文章的选中框太粗了;2)没完全覆盖住文章;;;最好首个文章,和第个文章的情况,都看看 -->
|
||||||
<div
|
<div
|
||||||
class="group relative mx-auto w-full cursor-pointer border-t border-[#eaeaea] bg-white py-[5px]"
|
class="group relative mx-auto w-full cursor-pointer border-t border-[#eaeaea] bg-white py-[5px]"
|
||||||
v-if="index > 0"
|
v-if="index > 0"
|
||||||
@@ -141,6 +142,8 @@ function plusNews() {
|
|||||||
<img class="h-full w-full" :src="news.thumbUrl" />
|
<img class="h-full w-full" :src="news.thumbUrl" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- TODO @hw:这里的按钮,交互不太对。应该在每个卡片的里面;或者类似公众号现在的交互,放到右侧;。。。复现本周:如果有 2 个文章的时候 -->
|
||||||
|
<!-- TODO @hw:当有 2 个文章的时候,挪到第二个文章的时候,卡片会变大。期望:不变大 -->
|
||||||
<div
|
<div
|
||||||
class="relative -bottom-[25px] hidden text-center group-hover:block"
|
class="relative -bottom-[25px] hidden text-center group-hover:block"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -24,6 +24,49 @@ export namespace MpDraftApi {
|
|||||||
articles: Article[];
|
articles: Article[];
|
||||||
createTime?: Date;
|
createTime?: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 图文项(包含预览字段) */
|
||||||
|
export interface NewsItem {
|
||||||
|
title: string;
|
||||||
|
thumbMediaId: string;
|
||||||
|
author: string;
|
||||||
|
digest: string;
|
||||||
|
showCoverPic: number;
|
||||||
|
content: string;
|
||||||
|
contentSourceUrl: string;
|
||||||
|
needOpenComment: number;
|
||||||
|
onlyFansCanComment: number;
|
||||||
|
thumbUrl: string;
|
||||||
|
picUrl?: string; // 用于预览封面
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 图文列表 */
|
||||||
|
export interface NewsItemList {
|
||||||
|
newsItem: NewsItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 草稿文章(用于展示) */
|
||||||
|
export interface DraftArticle {
|
||||||
|
mediaId: string;
|
||||||
|
content: NewsItemList;
|
||||||
|
updateTime: number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 创建空的图文项 */
|
||||||
|
export function createEmptyNewsItem(): MpDraftApi.NewsItem {
|
||||||
|
return {
|
||||||
|
title: '',
|
||||||
|
thumbMediaId: '',
|
||||||
|
author: '',
|
||||||
|
digest: '',
|
||||||
|
showCoverPic: 0,
|
||||||
|
content: '',
|
||||||
|
contentSourceUrl: '',
|
||||||
|
needOpenComment: 0,
|
||||||
|
onlyFansCanComment: 0,
|
||||||
|
thumbUrl: '',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询草稿列表 */
|
/** 查询草稿列表 */
|
||||||
|
|||||||
@@ -21,13 +21,6 @@ export namespace MpUserApi {
|
|||||||
tagIds?: number[];
|
tagIds?: number[];
|
||||||
createTime?: Date;
|
createTime?: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 用户分页查询参数 */
|
|
||||||
export interface UserPageQuery extends PageParam {
|
|
||||||
accountId?: number;
|
|
||||||
nickname?: string;
|
|
||||||
tagId?: number;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 更新公众号粉丝 */
|
/** 更新公众号粉丝 */
|
||||||
@@ -43,7 +36,7 @@ export function getUser(id: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 获取公众号粉丝分页 */
|
/** 获取公众号粉丝分页 */
|
||||||
export function getUserPage(params: MpUserApi.UserPageQuery) {
|
export function getUserPage(params: PageParam) {
|
||||||
return requestClient.get<PageResult<MpUserApi.User>>('/mp/user/page', {
|
return requestClient.get<PageResult<MpUserApi.User>>('/mp/user/page', {
|
||||||
params,
|
params,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { VbenFormSchema } from '#/adapter/form';
|
import type { VbenFormSchema } from '#/adapter/form';
|
||||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
/** 获取表格列配置 */
|
/** 获取表格列配置 */
|
||||||
export function useGridColumns(): VxeTableGridOptions['columns'] {
|
export function useGridColumns(): VxeTableGridOptions['columns'] {
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ function handleAccountChange(accountId: number) {
|
|||||||
gridApi.formApi.submitForm();
|
gridApi.formApi.submitForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @hw:代码风格,要和对应的 antd index.vue 一致,类似方法的顺序,注释等。原因是,这样后续两端迭代,会方便很多。
|
||||||
|
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
formOptions: {
|
formOptions: {
|
||||||
schema: useGridFormSchema(),
|
schema: useGridFormSchema(),
|
||||||
@@ -189,7 +191,7 @@ async function handleDelete(row: Article) {
|
|||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
{
|
{
|
||||||
label: '新增',
|
label: $t('ui.actionTitle.create', ['图文草稿']),
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
icon: ACTION_ICON.ADD,
|
icon: ACTION_ICON.ADD,
|
||||||
auth: ['mp:draft:create'],
|
auth: ['mp:draft:create'],
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// TODO @hw:要不要删除
|
||||||
export default {
|
export default {
|
||||||
list: [
|
list: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { ElButton, ElDialog, ElImage, ElMessage, ElUpload } from 'element-plus';
|
|||||||
import { UploadType, useBeforeUpload } from '#/utils/useUpload';
|
import { UploadType, useBeforeUpload } from '#/utils/useUpload';
|
||||||
import MaterialSelect from '#/views/mp/components/wx-material-select/wx-material-select.vue';
|
import MaterialSelect from '#/views/mp/components/wx-material-select/wx-material-select.vue';
|
||||||
|
|
||||||
// 设置上传的请求头部
|
// TODO @hw:代码风格,要和对应的 antd index.vue 一致,类似方法的顺序,注释等。原因是,这样后续两端迭代,会方便很多。
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
isFirst: boolean;
|
isFirst: boolean;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { Article } from './types';
|
|||||||
|
|
||||||
import News from '#/views/mp/components/wx-news/wx-news.vue';
|
import News from '#/views/mp/components/wx-news/wx-news.vue';
|
||||||
|
|
||||||
|
// TODO @hw:按照微信里说的,感觉这个可以干掉。少点组件哈。= = mp 模块,小组件可太多了。。。
|
||||||
defineOptions({ name: 'DraftTableCell' });
|
defineOptions({ name: 'DraftTableCell' });
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import NewsForm from './news-form.vue';
|
|||||||
|
|
||||||
const emit = defineEmits(['success']);
|
const emit = defineEmits(['success']);
|
||||||
|
|
||||||
|
// TODO @hw:代码风格,要和对应的 antd index.vue 一致,类似方法的顺序,注释等。原因是,这样后续两端迭代,会方便很多。
|
||||||
|
|
||||||
const formData = ref<{
|
const formData = ref<{
|
||||||
accountId: number;
|
accountId: number;
|
||||||
isCreating: boolean;
|
isCreating: boolean;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { NewsItem } from './types';
|
|||||||
|
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
|
import { confirm } from '@vben/common-ui';
|
||||||
import { IconifyIcon } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -12,7 +13,6 @@ import {
|
|||||||
ElContainer,
|
ElContainer,
|
||||||
ElInput,
|
ElInput,
|
||||||
ElMain,
|
ElMain,
|
||||||
ElMessageBox,
|
|
||||||
ElRow,
|
ElRow,
|
||||||
} from 'element-plus';
|
} from 'element-plus';
|
||||||
|
|
||||||
@@ -28,7 +28,6 @@ const props = defineProps<{
|
|||||||
modelValue: NewsItem[] | null;
|
modelValue: NewsItem[] | null;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// v-model=newsList
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:modelValue', v: NewsItem[]): void;
|
(e: 'update:modelValue', v: NewsItem[]): void;
|
||||||
}>();
|
}>();
|
||||||
@@ -53,7 +52,7 @@ const activeNewsItem = computed(() => {
|
|||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 将图文向下移动
|
/** 将图文向下移动 */
|
||||||
function moveDownNews(index: number) {
|
function moveDownNews(index: number) {
|
||||||
const current = newsList.value[index];
|
const current = newsList.value[index];
|
||||||
const next = newsList.value[index + 1];
|
const next = newsList.value[index + 1];
|
||||||
@@ -64,7 +63,7 @@ function moveDownNews(index: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将图文向上移动
|
/** 将图文向上移动 */
|
||||||
function moveUpNews(index: number) {
|
function moveUpNews(index: number) {
|
||||||
const current = newsList.value[index];
|
const current = newsList.value[index];
|
||||||
const prev = newsList.value[index - 1];
|
const prev = newsList.value[index - 1];
|
||||||
@@ -75,20 +74,16 @@ function moveUpNews(index: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除指定 index 的图文
|
/** 删除指定 index 的图文 */
|
||||||
async function removeNews(index: number) {
|
async function removeNews(index: number) {
|
||||||
try {
|
await confirm('确定删除该图文吗?');
|
||||||
await ElMessageBox.confirm('确定删除该图文吗?');
|
newsList.value.splice(index, 1);
|
||||||
newsList.value.splice(index, 1);
|
if (activeNewsIndex.value === index) {
|
||||||
if (activeNewsIndex.value === index) {
|
activeNewsIndex.value = 0;
|
||||||
activeNewsIndex.value = 0;
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// empty
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加一个图文
|
/** 添加一个图文 */
|
||||||
function plusNews() {
|
function plusNews() {
|
||||||
newsList.value.push(createEmptyNewsItem());
|
newsList.value.push(createEmptyNewsItem());
|
||||||
activeNewsIndex.value = newsList.value.length - 1;
|
activeNewsIndex.value = newsList.value.length - 1;
|
||||||
@@ -139,6 +134,7 @@ function plusNews() {
|
|||||||
</ElButton>
|
</ElButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- TODO @hw:1)每个文章的选中框太粗了;2)没完全覆盖住文章;;;最好首个文章,和第个文章的情况,都看看 -->
|
||||||
<div
|
<div
|
||||||
class="group mx-auto w-full cursor-pointer border-t border-gray-200 bg-white py-1.5"
|
class="group mx-auto w-full cursor-pointer border-t border-gray-200 bg-white py-1.5"
|
||||||
v-if="index > 0"
|
v-if="index > 0"
|
||||||
@@ -153,6 +149,8 @@ function plusNews() {
|
|||||||
<img class="h-full w-full" :src="news.thumbUrl" width="100%" />
|
<img class="h-full w-full" :src="news.thumbUrl" width="100%" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- TODO @hw:这里的按钮,交互不太对。应该在每个卡片的里面;或者类似公众号现在的交互,放到右侧;。。。复现本周:如果有 2 个文章的时候 -->
|
||||||
|
<!-- TODO @hw:当有 2 个文章的时候,挪到第二个文章的时候,卡片会变大。期望:不变大 -->
|
||||||
<div
|
<div
|
||||||
class="relative -bottom-6 hidden text-center group-hover:block"
|
class="relative -bottom-6 hidden text-center group-hover:block"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
/** 提交表单 */
|
// 提交表单
|
||||||
const values = (await formApi.getValues()) as MpUserApi.User;
|
const values = (await formApi.getValues()) as MpUserApi.User;
|
||||||
try {
|
try {
|
||||||
await updateUser({ ...formData.value, ...values });
|
await updateUser({ ...formData.value, ...values });
|
||||||
/** 关闭并提示 */
|
// 关闭并提示
|
||||||
await modalApi.close();
|
await modalApi.close();
|
||||||
emit('success');
|
emit('success');
|
||||||
ElMessage.success($t('ui.actionMessage.operationSuccess'));
|
ElMessage.success($t('ui.actionMessage.operationSuccess'));
|
||||||
@@ -56,7 +56,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
formData.value = undefined;
|
formData.value = undefined;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/** 加载数据 */
|
// 加载数据
|
||||||
const data = modalApi.getData<{ id: number }>();
|
const data = modalApi.getData<{ id: number }>();
|
||||||
if (!data || !data.id) {
|
if (!data || !data.id) {
|
||||||
return;
|
return;
|
||||||
@@ -64,7 +64,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
modalApi.lock();
|
modalApi.lock();
|
||||||
try {
|
try {
|
||||||
formData.value = await getUser(data.id);
|
formData.value = await getUser(data.id);
|
||||||
/** 设置到 values */
|
// 设置到 values
|
||||||
await formApi.setValues(formData.value);
|
await formApi.setValues(formData.value);
|
||||||
} finally {
|
} finally {
|
||||||
modalApi.unlock();
|
modalApi.unlock();
|
||||||
|
|||||||
Reference in New Issue
Block a user