Merge branch 'dev' of codeup.aliyun.com:61c14a7efa282c88e103c23f/oak-general-business into dev
This commit is contained in:
commit
2d732106cd
|
|
@ -105,5 +105,50 @@ export type GeneralAspectDict<ED extends EntityDict, Cxt extends BackendRuntimeC
|
|||
result: string;
|
||||
times?: number;
|
||||
}>;
|
||||
getCurrentMenu: (params: {
|
||||
applicationId: string;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
getMenu: (params: {
|
||||
applicationId: string;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
createMenu: (params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
createConditionalMenu: (params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
deleteConditionalMenu: (params: {
|
||||
applicationId: string;
|
||||
menuid: number;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
batchGetArticle: (params: {
|
||||
applicationId: string;
|
||||
offset?: number;
|
||||
count: number;
|
||||
noContent?: 0 | 1;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
getArticle: (params: {
|
||||
applicationId: string;
|
||||
article_id: string;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
createMaterial: (params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'voice' | 'video' | 'thumb';
|
||||
media: FormData;
|
||||
description?: FormData;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
batchGetMaterialList: (params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
offset?: number;
|
||||
count: number;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
getMaterial: (params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
media_id: string;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
};
|
||||
export default GeneralAspectDict;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { createWechatLogin } from './wechatLogin';
|
|||
import { unbindingWechat } from './wechatUser';
|
||||
import { getMpUnlimitWxaCode } from './wechatQrCode';
|
||||
import { confirmUserEntityGrant } from './userEntityGrant';
|
||||
import { getCurrentMenu, getMenu, createMenu, createConditionalMenu, deleteConditionalMenu, batchGetArticle, getArticle, createMaterial, batchGetMaterialList, getMaterial } from './wechatMenu';
|
||||
declare const aspectDict: {
|
||||
mergeUser: typeof mergeUser;
|
||||
switchTo: typeof switchTo;
|
||||
|
|
@ -31,5 +32,15 @@ declare const aspectDict: {
|
|||
updateUserPassword: typeof updateUserPassword;
|
||||
getMpUnlimitWxaCode: typeof getMpUnlimitWxaCode;
|
||||
confirmUserEntityGrant: typeof confirmUserEntityGrant;
|
||||
getCurrentMenu: typeof getCurrentMenu;
|
||||
getMenu: typeof getMenu;
|
||||
createMenu: typeof createMenu;
|
||||
createConditionalMenu: typeof createConditionalMenu;
|
||||
deleteConditionalMenu: typeof deleteConditionalMenu;
|
||||
batchGetArticle: typeof batchGetArticle;
|
||||
getArticle: typeof getArticle;
|
||||
createMaterial: typeof createMaterial;
|
||||
batchGetMaterialList: typeof batchGetMaterialList;
|
||||
getMaterial: typeof getMaterial;
|
||||
};
|
||||
export default aspectDict;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { createWechatLogin } from './wechatLogin';
|
|||
import { unbindingWechat } from './wechatUser';
|
||||
import { getMpUnlimitWxaCode } from './wechatQrCode';
|
||||
import { confirmUserEntityGrant } from './userEntityGrant';
|
||||
import { getCurrentMenu, getMenu, createMenu, createConditionalMenu, deleteConditionalMenu, batchGetArticle, getArticle, createMaterial, batchGetMaterialList, getMaterial, } from './wechatMenu';
|
||||
const aspectDict = {
|
||||
mergeUser,
|
||||
switchTo,
|
||||
|
|
@ -31,5 +32,15 @@ const aspectDict = {
|
|||
updateUserPassword,
|
||||
getMpUnlimitWxaCode,
|
||||
confirmUserEntityGrant,
|
||||
getCurrentMenu,
|
||||
getMenu,
|
||||
createMenu,
|
||||
createConditionalMenu,
|
||||
deleteConditionalMenu,
|
||||
batchGetArticle,
|
||||
getArticle,
|
||||
createMaterial,
|
||||
batchGetMaterialList,
|
||||
getMaterial,
|
||||
};
|
||||
export default aspectDict;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { BackendRuntimeContext } from '../context/BackendRuntimeContext';
|
||||
export declare function getCurrentMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function getMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function createMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function createConditionalMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function deleteConditionalMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
menuid: number;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function batchGetArticle<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
offset?: number;
|
||||
count: number;
|
||||
noContent?: 0 | 1;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function getArticle<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
article_id: string;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function createMaterial<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'voice' | 'video' | 'thumb';
|
||||
media: FormData;
|
||||
description?: FormData;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function batchGetMaterialList<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
offset?: number;
|
||||
count: number;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function getMaterial<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
media_id: string;
|
||||
}, context: Cxt): Promise<any>;
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
import { WechatSDK, } from 'oak-external-sdk';
|
||||
async function getWechatPublicConfig(applicationId, context) {
|
||||
const [application] = await context.select('application', {
|
||||
data: {
|
||||
id: 1,
|
||||
config: 1,
|
||||
type: 1,
|
||||
},
|
||||
filter: {
|
||||
id: applicationId,
|
||||
type: 'wechatPublic'
|
||||
},
|
||||
}, {
|
||||
dontCollect: true
|
||||
});
|
||||
return application;
|
||||
}
|
||||
export async function getCurrentMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.getCurrentMenu();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export async function getMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.getMenu();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export async function createMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.createMenu(params.menuConfig);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export async function createConditionalMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.createConditionalMenu(params.menuConfig);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export async function deleteConditionalMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.deleteConditionalMenu(params.menuid);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export async function batchGetArticle(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.batchGetArticle(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export async function getArticle(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.getArticle(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export async function createMaterial(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.createMaterial(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export async function batchGetMaterialList(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.batchGetMaterialList(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export async function getMaterial(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.getMaterial(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../oak-app-domain").EntityDict, keyof import("../../oak-app-domain").EntityDict, false, {
|
||||
type: "image" | "video" | "news" | "voice";
|
||||
getMenuContent: (menuContent: any) => void;
|
||||
applicationId: string;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
export default OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
type: '',
|
||||
getMenuContent: (menuContent) => undefined,
|
||||
applicationId: '',
|
||||
},
|
||||
lifetimes: {
|
||||
async ready() {
|
||||
const { type, applicationId } = this.props;
|
||||
let result;
|
||||
if (type === 'news') {
|
||||
result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId, offset: 0, count: 10, noContent: 0 });
|
||||
const modifiedResult = await Promise.all(result.item.map(async (ele) => {
|
||||
const news_item = await Promise.all(ele.content.news_item.map(async (ele2) => {
|
||||
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
|
||||
return {
|
||||
...ele2,
|
||||
coverUrl
|
||||
};
|
||||
}));
|
||||
return {
|
||||
...ele,
|
||||
content: {
|
||||
...ele.content,
|
||||
news_item
|
||||
}
|
||||
};
|
||||
}));
|
||||
this.setState({
|
||||
materials: modifiedResult,
|
||||
total: result.total_count,
|
||||
});
|
||||
}
|
||||
else {
|
||||
result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId, type: type, offset: 0, count: 10 });
|
||||
this.setState({
|
||||
materials: result.item,
|
||||
total: result.total_count,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getMaterialList(page) {
|
||||
const { applicationId } = this.props;
|
||||
const { type } = this.props;
|
||||
const offset = (page - 1) * 10;
|
||||
const result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId, type: type, offset, count: 10 });
|
||||
this.setState({
|
||||
materials: result.item,
|
||||
total: result.total_count,
|
||||
});
|
||||
},
|
||||
async getArticleList(page) {
|
||||
const { applicationId } = this.props;
|
||||
const offset = (page - 1) * 10;
|
||||
const result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId, offset, count: 10, noContent: 0 });
|
||||
const modifiedResult = await Promise.all(result.item.map(async (ele) => {
|
||||
const news_item = await Promise.all(ele.content.news_item.map(async (ele2) => {
|
||||
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
|
||||
return {
|
||||
...ele2,
|
||||
coverUrl
|
||||
};
|
||||
}));
|
||||
return {
|
||||
...ele,
|
||||
content: {
|
||||
...ele.content,
|
||||
news_item
|
||||
}
|
||||
};
|
||||
}));
|
||||
this.setState({
|
||||
materials: modifiedResult,
|
||||
total: result.total_count,
|
||||
});
|
||||
},
|
||||
async upload(media, description) {
|
||||
const { applicationId } = this.props;
|
||||
const { type } = this.props;
|
||||
console.log(media);
|
||||
const result = await this.features.wechatMenu.createMaterial({ applicationId: applicationId, type: type, media, description });
|
||||
if (result && result.media_id) {
|
||||
this.setMessage({
|
||||
type: 'success',
|
||||
content: '上传成功',
|
||||
});
|
||||
this.getMaterialList(1);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
async getMaterialImg(media_id) {
|
||||
const { applicationId } = this.props;
|
||||
const imgFile = await this.features.wechatMenu.getMaterial({ applicationId: applicationId, type: 'image', media_id });
|
||||
return new Promise((resolve) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(imgFile);
|
||||
reader.onload = function (e) {
|
||||
resolve(e.target?.result);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.upload {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin: 20px 0 0 0;
|
||||
.help {
|
||||
color: #B1B2B3;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.list {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { EntityDict } from "../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, true, {
|
||||
type: string;
|
||||
materials: any[];
|
||||
total: number;
|
||||
getMenuContent: (menuContent: any) => void;
|
||||
}, {
|
||||
getMaterialList: (page: number) => void;
|
||||
getArticleList: (page: number) => void;
|
||||
upload: (media: FormData, description?: FormData) => boolean;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Modal, Button, Table, Space, Upload, Form, Input, Popover } from 'antd';
|
||||
const { TextArea } = Input;
|
||||
import { DownloadOutlined } from '@ant-design/icons';
|
||||
import Style from './web.module.less';
|
||||
import dayjs from 'dayjs';
|
||||
import ShowNews from '../wechatMenu/showNews';
|
||||
export default function Render(props) {
|
||||
const { type, materials, total, getMenuContent } = props.data;
|
||||
const { getMaterialList, setMessage, upload, getArticleList } = props.methods;
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [upsertOpen, setUpsertOpen] = useState(false);
|
||||
const [title, setTitle] = useState('');
|
||||
const [introduction, setIntroduction] = useState('');
|
||||
const [fileList, setFileList] = useState([]);
|
||||
const [video, setVideo] = useState(new FormData);
|
||||
const checkFileType = (filename) => {
|
||||
const fileExtension = filename?.split('.')?.pop()?.toLowerCase();
|
||||
let allowedExtensions = [];
|
||||
if (type === 'image') {
|
||||
allowedExtensions = ['bmp', 'png', 'jpeg', 'jpg', 'gif'];
|
||||
}
|
||||
else if (type === 'voice') {
|
||||
allowedExtensions = ['mp3', 'wma', 'wav', 'amr'];
|
||||
}
|
||||
else {
|
||||
allowedExtensions = ['mp4'];
|
||||
}
|
||||
if (allowedExtensions.includes(fileExtension)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
setMessage({
|
||||
content: '文件类型错误',
|
||||
type: 'error'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const uploadFile = async (file) => {
|
||||
if (checkFileType(file.name)) {
|
||||
const formData = new FormData();
|
||||
formData.append('media', file);
|
||||
console.log(file);
|
||||
upload(formData);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
};
|
||||
const fileChange = (info) => {
|
||||
setFileList(info.fileList);
|
||||
};
|
||||
const uploadVideo = async (file) => {
|
||||
if (checkFileType(file.name)) {
|
||||
const formData = new FormData();
|
||||
formData.append('media', file);
|
||||
setVideo(formData);
|
||||
const updataFileList = fileList.map((ele) => {
|
||||
return {
|
||||
...ele,
|
||||
status: 'done'
|
||||
};
|
||||
});
|
||||
fileChange({ fileList: updataFileList });
|
||||
}
|
||||
else {
|
||||
const updataFileList = fileList.map((ele) => {
|
||||
return {
|
||||
...ele,
|
||||
status: 'error'
|
||||
};
|
||||
});
|
||||
fileChange({ fileList: updataFileList });
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
setTitle('');
|
||||
setIntroduction('');
|
||||
setFileList([]);
|
||||
}
|
||||
}, [open]);
|
||||
const columns = [
|
||||
{
|
||||
dataIndex: 'serial-number',
|
||||
title: '序号',
|
||||
render: (value, record, index) => {
|
||||
return index + 1;
|
||||
},
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: '名称',
|
||||
},
|
||||
{
|
||||
dataIndex: 'update_time',
|
||||
title: '更新时间',
|
||||
render: (value, record, index) => {
|
||||
return _jsx(_Fragment, { children: dayjs(value).format('YYYY-MM-DD HH:mm') });
|
||||
}
|
||||
},
|
||||
];
|
||||
const newsColumns = [
|
||||
{
|
||||
dataIndex: 'serial-number',
|
||||
title: '序号',
|
||||
render: (value, record, index) => {
|
||||
return index + 1;
|
||||
},
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
dataIndex: 'coverImg',
|
||||
title: '封面图',
|
||||
render: (value, record, index) => {
|
||||
return (_jsx("div", { children: record.content.news_item.map((ele) => (_jsx("div", { children: _jsx("img", { style: { width: 100 }, src: ele.coverUrl }) }))) }));
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'title',
|
||||
title: '图文消息标题',
|
||||
render: (value, record, index) => {
|
||||
return (_jsx("div", { children: record.content.news_item.map((ele) => (_jsx("div", { children: ele.title }))) }));
|
||||
}
|
||||
},
|
||||
{
|
||||
// dataIndex: 'author',
|
||||
title: '作者',
|
||||
render: (value, record, index) => {
|
||||
return (_jsx("div", { children: record.content.news_item.map((ele) => (_jsx("div", { children: ele.author }))) }));
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'digest',
|
||||
title: '图文信息摘要',
|
||||
render: (value, record, index) => {
|
||||
return (_jsx("div", { children: record.content.news_item.map((ele) => (_jsx("div", { children: ele.digest }))) }));
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'update_time',
|
||||
title: '更新时间',
|
||||
render: (value, record, index) => {
|
||||
return _jsx(_Fragment, { children: dayjs(value).format('YYYY-MM-DD HH:mm') });
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'op',
|
||||
title: '操作',
|
||||
render: (value, record, index) => {
|
||||
return _jsx(Popover, { content: _jsx("div", { style: { padding: 12 }, children: _jsx(ShowNews, { oakAutoUnmount: true, news: record.content.news_item }) }), children: _jsx("div", { style: { cursor: 'pointer', color: '#1677ff' }, children: "\u9884\u89C8" }) });
|
||||
}
|
||||
}
|
||||
];
|
||||
if (type === 'image') {
|
||||
columns.splice(1, 0, {
|
||||
dataIndex: 'url',
|
||||
title: '图片',
|
||||
render: (value, record, index) => {
|
||||
return _jsx("img", { style: { width: 120, height: 70 }, src: value });
|
||||
},
|
||||
});
|
||||
}
|
||||
else if (type === 'voice') {
|
||||
columns.splice(1, 0, {
|
||||
dataIndex: 'url',
|
||||
title: '音频',
|
||||
render: (value, record, index) => {
|
||||
return _jsxs("a", { href: value, download: true, style: { color: '#1677FF', cursor: 'pointer' }, children: [_jsx(DownloadOutlined, {}), record.media_id] });
|
||||
},
|
||||
});
|
||||
}
|
||||
else if (type === 'video') {
|
||||
columns.splice(1, 0, {
|
||||
dataIndex: 'url',
|
||||
title: '视频',
|
||||
render: (value, record, index) => {
|
||||
return _jsxs("a", { href: value, download: true, style: { color: '#1677FF', cursor: 'pointer' }, children: [_jsx(DownloadOutlined, {}), record.media_id] });
|
||||
},
|
||||
});
|
||||
}
|
||||
else {
|
||||
}
|
||||
return (_jsxs("div", { className: Style.container, children: [_jsx("div", { className: Style.title, children: type === 'news' ? '选择图文' : type === 'image' ? '选择图片' : type === 'voice' ? '插入音频' : '选择视频' }), type !== 'news' && _jsxs("div", { className: Style.upload, children: [_jsx("div", { className: Style.help, children: type === 'image' ? '大小不超过10M' : type === 'voice' ? '由于版本兼容的原因,你暂时只可以选择60秒内的音频发送' : null }), type === 'video' ? (_jsx(Button, { onClick: () => {
|
||||
setUpsertOpen(true);
|
||||
}, children: "\u4E0A\u4F20\u89C6\u9891" })) : (_jsx(Upload, { maxCount: 1, showUploadList: false, customRequest: ({ file }) => {
|
||||
uploadFile(file);
|
||||
}, children: _jsxs(Button, { children: ["\u4E0A\u4F20", type === 'image' ? '图片' : '音频'] }) })), _jsx(Modal, { open: upsertOpen, onCancel: () => setUpsertOpen(false), title: '上传视频', footer: _jsxs(Space, { children: [_jsx(Button, { type: 'primary', onClick: () => {
|
||||
if (title.length === 0) {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: '标题不能为空'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (introduction.length === 0) {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: '视频介绍不能为空'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (fileList.length === 0 || fileList[0].status === 'error') {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: '请上传视频文件'
|
||||
});
|
||||
return;
|
||||
}
|
||||
const formData = new FormData;
|
||||
const descriptionData = {
|
||||
title,
|
||||
introduction,
|
||||
};
|
||||
formData.append('description', JSON.stringify(descriptionData));
|
||||
if (upload(video, formData)) {
|
||||
setUpsertOpen(false);
|
||||
}
|
||||
}, children: "\u4E0A\u4F20" }), _jsx(Button, { onClick: () => setUpsertOpen(false), children: "\u53D6\u6D88" })] }), children: _jsxs("div", { children: [_jsx(Form.Item, { label: _jsx("div", { className: Style.label, children: "\u6807\u9898" }), required: true, labelAlign: 'right', labelCol: { span: 4 }, children: _jsx(Input, { showCount: true, maxLength: 20, value: title, onChange: (val) => setTitle(val.target.value) }) }), _jsx(Form.Item, { label: _jsx("div", { className: Style.label, children: "\u89C6\u9891\u4ECB\u7ECD" }), required: true, children: _jsx(TextArea, { showCount: true, maxLength: 300, value: introduction, autoSize: { minRows: 5 }, onChange: (val) => setIntroduction(val.target.value) }) }), _jsx(Form.Item, { label: _jsx("div", { className: Style.label, children: "\u4E0A\u4F20\u89C6\u9891" }), required: true, children: _jsx(Upload, { customRequest: ({ file }) => uploadVideo(file), maxCount: 1, onChange: fileChange, fileList: fileList, children: _jsxs(Button, { children: [_jsx(DownloadOutlined, {}), fileList.length > 0 ? '重新' : '', "\u4E0A\u4F20"] }) }) })] }) })] }), _jsx("div", { className: Style.list, children: _jsx(Table, { rowKey: type === 'news' ? 'article_id' : 'media_id', dataSource: materials, columns: type === 'news' ? newsColumns : columns, pagination: {
|
||||
total: total,
|
||||
pageSize: 10,
|
||||
current: currentPage,
|
||||
onChange: (page, pageSize) => {
|
||||
setCurrentPage(page);
|
||||
if (type === 'news') {
|
||||
getArticleList(page);
|
||||
}
|
||||
else {
|
||||
getMaterialList(page);
|
||||
}
|
||||
},
|
||||
}, rowSelection: {
|
||||
type: 'radio',
|
||||
onSelect: (record) => {
|
||||
if (type === 'news') {
|
||||
getMenuContent(record);
|
||||
}
|
||||
else {
|
||||
getMenuContent(record);
|
||||
}
|
||||
},
|
||||
} }) })] }));
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
id: string;
|
||||
config: any;
|
||||
menuIndex: number;
|
||||
changeConfig: (config: any) => void;
|
||||
menuType: string;
|
||||
getSelectedBtn: (selectedBtn: number) => void;
|
||||
getSelectedSubBtn: (selectedSubBtn: number) => void;
|
||||
getCurrentIndex: (currentIndex: number) => void;
|
||||
errorIndex: number[];
|
||||
isPreview: boolean;
|
||||
open: boolean;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
export default OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
id: '',
|
||||
config: null,
|
||||
menuIndex: 0,
|
||||
changeConfig: (config) => undefined,
|
||||
menuType: '',
|
||||
getSelectedBtn: (selectedBtn) => undefined,
|
||||
getSelectedSubBtn: (selectedSubBtn) => undefined,
|
||||
getCurrentIndex: (currentIndex) => undefined,
|
||||
errorIndex: [],
|
||||
isPreview: false,
|
||||
open: false,
|
||||
},
|
||||
data: {},
|
||||
methods: {
|
||||
deleteMenuItem(index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
config.button.splice(index, 1);
|
||||
changeConfig(config);
|
||||
this.setMessage({
|
||||
content: '操作成功',
|
||||
type: 'success'
|
||||
});
|
||||
},
|
||||
toRight(index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
config.button = [
|
||||
...config.button.slice(0, index - 1),
|
||||
config.button[index],
|
||||
config.button[index - 1],
|
||||
...config.button.slice(index + 1)
|
||||
];
|
||||
changeConfig(config);
|
||||
},
|
||||
toLeft(index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
config.button = [
|
||||
...config.button.slice(0, index - 2),
|
||||
config.button[index - 1],
|
||||
config.button[index - 2],
|
||||
...config.button.slice(index)
|
||||
];
|
||||
changeConfig(config);
|
||||
},
|
||||
toUp(currentIndex, index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
let menu = config.button[currentIndex];
|
||||
const subMenu = [
|
||||
...menu.sub_button.slice(0, index - 2),
|
||||
menu.sub_button[index - 1],
|
||||
menu.sub_button[index - 2],
|
||||
...menu.sub_button.slice(index)
|
||||
];
|
||||
config.button[currentIndex].sub_button = subMenu;
|
||||
changeConfig(config);
|
||||
},
|
||||
toDown(currentIndex, index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
let menu = config.button[currentIndex];
|
||||
const subMenu = [
|
||||
...menu.sub_button.slice(0, index - 1),
|
||||
menu.sub_button[index],
|
||||
menu.sub_button[index - 1],
|
||||
...menu.sub_button.slice(index + 1)
|
||||
];
|
||||
config.button[currentIndex].sub_button = subMenu;
|
||||
changeConfig(config);
|
||||
},
|
||||
deleteSubMenuItem(index, currentIndex) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
config.button[currentIndex].sub_button.splice(index, 1);
|
||||
changeConfig(config);
|
||||
this.setMessage({
|
||||
content: '操作成功',
|
||||
type: 'success'
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
.container {
|
||||
width: 100%;
|
||||
.phone {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
background: #fcfcfc;
|
||||
border-radius: 8px;
|
||||
|
||||
.topBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
margin: 8px 16px 10px 16px;
|
||||
align-items: center;
|
||||
|
||||
.time {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.actionBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.page {
|
||||
height: 412px;
|
||||
}
|
||||
|
||||
.bottomBar {
|
||||
height: 68px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background: #fcfcfc;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-top: 1px solid #EDEEEF;
|
||||
|
||||
.keyBoard {
|
||||
width: 60px;
|
||||
|
||||
}
|
||||
|
||||
.menu {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
cursor: pointer;
|
||||
|
||||
.buttonGroup {
|
||||
top: 73px;
|
||||
position: absolute;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 48px;
|
||||
min-width: 48px;
|
||||
border-radius: 24px;
|
||||
background: #fcfcfc;
|
||||
font-size: 24px;
|
||||
padding: 5px;
|
||||
box-shadow: 0 1px 6px #e4e8eb;
|
||||
|
||||
.buttonItem {
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
.buttonItem:hover {
|
||||
background: #EDEEEF;
|
||||
}
|
||||
}
|
||||
|
||||
.menuItem {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 68px;
|
||||
width: 80px;
|
||||
position: relative;
|
||||
|
||||
.menuName {
|
||||
width: 100%;
|
||||
height: 33px;
|
||||
border-left: 1px solid #EDEEEF;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.button2 {
|
||||
margin: 17px 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-left: 1px solid #EDEEEF;
|
||||
color: #4C4D4E;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1px dashed #1677FF;
|
||||
font-size: 14px;
|
||||
color: #1677FF;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-popover-inner {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
.subMenuContent {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
.subButtonGroup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 48px;
|
||||
min-height: 48px;
|
||||
border-radius: 24px;
|
||||
background: #fcfcfc;
|
||||
font-size: 24px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
left: 90px;
|
||||
box-shadow: 0 1px 6px #e4e8eb;
|
||||
|
||||
.buttonItem {
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
.buttonItem:hover {
|
||||
background: #EDEEEF;
|
||||
}
|
||||
}
|
||||
}
|
||||
.subMenuItem {
|
||||
width: 86px;
|
||||
height: 49px;
|
||||
text-align: center;
|
||||
padding: 12px 2px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-bottom: 1px solid #EDEEEF;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { WechatPublicInstance } from 'oak-external-sdk';
|
||||
import { EntityDict } from "../../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, {
|
||||
config: any;
|
||||
menuIndex: number;
|
||||
file: File;
|
||||
wechatInstance: WechatPublicInstance;
|
||||
errorIndex: number[];
|
||||
menuType: string;
|
||||
changeConfig: (config: any) => void;
|
||||
getSelectedBtn: (selectedBtn: number) => void;
|
||||
getSelectedSubBtn: (selectedSubBtn: number) => void;
|
||||
getCurrentIndex: (currentIndex: number) => void;
|
||||
isPreview: boolean;
|
||||
open: boolean;
|
||||
}, {
|
||||
setConfig: (index: number, content: any, currentIndex?: number) => void;
|
||||
deleteMenuItem: (index: number) => void;
|
||||
deleteSubMenuItem: (index: number, currentIndex: number) => void;
|
||||
toRight: (index: number) => void;
|
||||
toLeft: (index: number) => void;
|
||||
toUp: (currentIndex: number, index: number) => void;
|
||||
toDown: (currentIndex: number, index: number) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Modal, Popover } from 'antd';
|
||||
const { confirm } = Modal;
|
||||
import Style from './web.module.less';
|
||||
import { WifiOutlined, LeftOutlined, ArrowLeftOutlined, ArrowRightOutlined, UserOutlined, ArrowDownOutlined, DeleteOutlined, ArrowUpOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
export default function Render(props) {
|
||||
const { config, errorIndex, menuIndex, menuType, changeConfig, getSelectedBtn, getSelectedSubBtn, getCurrentIndex, isPreview, open, } = props.data;
|
||||
const { deleteMenuItem, toRight, toLeft, toUp, toDown, deleteSubMenuItem, } = props.methods;
|
||||
const [selectedBtn, setSelectedBtn] = useState(0);
|
||||
const [selectedSubBtn, setSelectedSubBtn] = useState(0);
|
||||
const [currentIndex, setCurrentIndex] = useState(1);
|
||||
const [onlyOne, setOnlyOne] = useState(true);
|
||||
const [currentMenuType, setCurrentMenuType] = useState(0);
|
||||
useEffect(() => {
|
||||
if (config && config.button && config.button[0] && onlyOne) {
|
||||
setSelectedBtn(1);
|
||||
getSelectedBtn(1);
|
||||
setOnlyOne(false);
|
||||
}
|
||||
}, [config]);
|
||||
useEffect(() => {
|
||||
if (selectedBtn !== 0) {
|
||||
setSelectedSubBtn(0);
|
||||
getSelectedSubBtn(0);
|
||||
setCurrentIndex(selectedBtn - 1);
|
||||
getCurrentIndex(selectedBtn - 1);
|
||||
}
|
||||
}, [selectedBtn]);
|
||||
useEffect(() => {
|
||||
if (selectedSubBtn !== 0) {
|
||||
setSelectedBtn(0);
|
||||
getSelectedBtn(0);
|
||||
}
|
||||
}, [selectedSubBtn]);
|
||||
useEffect(() => {
|
||||
if (menuType && menuType === 'common') {
|
||||
setCurrentMenuType(1);
|
||||
return;
|
||||
}
|
||||
if (menuType && menuType === 'conditional') {
|
||||
setCurrentMenuType(2);
|
||||
return;
|
||||
}
|
||||
}, [menuType]);
|
||||
return (_jsx("div", { className: Style.container, children: _jsxs("div", { className: Style.phone, children: [_jsxs("div", { className: Style.topBar, children: [_jsx("div", { className: Style.time, children: "1:21" }), _jsx("div", { className: Style.icons, children: _jsx(WifiOutlined, { style: { fontSize: 12 } }) })] }), _jsxs("div", { className: Style.actionBar, children: [_jsx(LeftOutlined, { style: { fontSize: 18 } }), _jsx(UserOutlined, { style: { fontSize: 18 } })] }), _jsx("div", { className: Style.page }), _jsxs("div", { className: Style.bottomBar, children: [_jsx("div", { className: Style.keyBoard }), config && config.button && config.button.length > 0 ? (_jsxs("div", { className: Style.menu, children: [config.button.map((ele, index) => (_jsx(Popover, { open: !open && !isPreview && currentIndex === index && ((menuType === 'common' && currentMenuType === 1) || (menuType === 'conditional' && currentMenuType === 2)), trigger: 'click', content: _jsx("div", { className: Style.subMenu, children: config.button[index].sub_button.length > 0 ? (_jsxs(_Fragment, { children: [config.button[index].sub_button.map((ele, index2) => (_jsxs("div", { className: Style.subMenuContent, children: [_jsx("div", { className: Style.subMenuItem, style: errorIndex?.includes((index + 1) * 10 + index2) ? {
|
||||
border: '1px solid #FF4D4F',
|
||||
color: '#FF4D4F'
|
||||
}
|
||||
:
|
||||
selectedSubBtn === index2 + 1 ?
|
||||
{
|
||||
border: '1px solid #1677FF',
|
||||
color: '#1677FF'
|
||||
} :
|
||||
{}, onClick: () => {
|
||||
setSelectedSubBtn(index2 + 1);
|
||||
getSelectedSubBtn(index2 + 1);
|
||||
}, children: ele.name }), selectedSubBtn === index2 + 1 &&
|
||||
_jsxs("div", { className: Style.subButtonGroup, children: [selectedSubBtn > 1
|
||||
&& config.button[currentIndex].sub_button.length !== 1 &&
|
||||
_jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
toUp(currentIndex, selectedSubBtn);
|
||||
setSelectedSubBtn(selectedSubBtn - 1);
|
||||
getSelectedSubBtn(selectedSubBtn - 1);
|
||||
}, children: _jsx(ArrowUpOutlined, {}) }), _jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
const modal = confirm({
|
||||
title: '确定删除该菜单吗?',
|
||||
content: '删除后不可恢复',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: async (e) => {
|
||||
if (selectedSubBtn !== 1 && config.button[currentIndex].sub_button.length > 1) {
|
||||
setSelectedSubBtn(selectedSubBtn - 1);
|
||||
getSelectedSubBtn(selectedSubBtn - 1);
|
||||
}
|
||||
else if (selectedSubBtn === 1 && config.button[currentIndex].sub_button.length > 1) {
|
||||
setSelectedSubBtn(1);
|
||||
getSelectedSubBtn(1);
|
||||
}
|
||||
else {
|
||||
setSelectedBtn(currentIndex + 1);
|
||||
getSelectedBtn(currentIndex + 1);
|
||||
}
|
||||
deleteSubMenuItem(selectedSubBtn - 1, currentIndex);
|
||||
modal.destroy();
|
||||
},
|
||||
});
|
||||
}, children: _jsx(DeleteOutlined, {}) }), selectedSubBtn < config.button[currentIndex].sub_button.length
|
||||
&& config.button[currentIndex].sub_button.length > 1 &&
|
||||
_jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
toDown(currentIndex, selectedSubBtn);
|
||||
setSelectedSubBtn(selectedSubBtn + 1);
|
||||
getSelectedSubBtn(selectedSubBtn + 1);
|
||||
}, children: _jsx(ArrowDownOutlined, {}) })] })] }))), config.button[index].sub_button.length !== 5 &&
|
||||
_jsxs("div", { style: { border: 0 }, className: Style.subMenuItem, onClick: () => {
|
||||
config.button[index] = {
|
||||
name: config.button[index].name,
|
||||
sub_button: [
|
||||
...config.button[index].sub_button,
|
||||
{
|
||||
name: '子菜单名称',
|
||||
}
|
||||
]
|
||||
};
|
||||
changeConfig(config);
|
||||
setSelectedSubBtn(config.button[index].sub_button.length);
|
||||
getSelectedSubBtn(config.button[index].sub_button.length);
|
||||
}, children: [_jsx(PlusOutlined, {}), "\u6DFB\u52A0"] })] })) : (_jsxs("div", { style: { border: 0 }, className: Style.subMenuItem, onClick: () => {
|
||||
config.button[index] = {
|
||||
name: config.button[index].name,
|
||||
sub_button: [
|
||||
{
|
||||
name: '子菜单名称',
|
||||
}
|
||||
]
|
||||
};
|
||||
changeConfig(config);
|
||||
setSelectedSubBtn(1);
|
||||
getSelectedSubBtn(1);
|
||||
}, children: [_jsx(PlusOutlined, {}), "\u6DFB\u52A0"] })) }), children: _jsxs("div", { className: Style.menuItem, onClick: () => { setSelectedBtn(index + 1); getSelectedBtn(index + 1); }, style: errorIndex?.includes(index) ?
|
||||
{ margin: 0, border: '1px solid #FF4D4F' }
|
||||
:
|
||||
selectedBtn === index + 1 ?
|
||||
{ margin: 0, border: '1px solid #1677FF', color: '#1677FF' }
|
||||
:
|
||||
{}, children: [_jsx("div", { className: Style.menuName, style: errorIndex?.includes(index) ? {
|
||||
color: '#FF4D4F'
|
||||
} : {}, children: ele.name }), selectedBtn === index + 1 &&
|
||||
_jsxs("div", { className: Style.buttonGroup, children: [selectedBtn > 1
|
||||
&& config.button.length !== 1
|
||||
&& _jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
toLeft(selectedBtn);
|
||||
setSelectedBtn(selectedBtn - 1);
|
||||
getSelectedBtn(selectedBtn - 1);
|
||||
}, style: { color: '#1F1F1F' }, children: _jsx(ArrowLeftOutlined, {}) }), _jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
const modal = confirm({
|
||||
title: '确定删除该菜单吗?',
|
||||
content: '删除后不可恢复',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: async (e) => {
|
||||
if (selectedBtn !== 1 && config.button.length > 1) {
|
||||
setSelectedBtn(selectedBtn - 1);
|
||||
getSelectedBtn(selectedBtn - 1);
|
||||
}
|
||||
else if (selectedBtn === 1 && config.button.length > 1) {
|
||||
setSelectedBtn(1);
|
||||
getSelectedBtn(1);
|
||||
}
|
||||
else {
|
||||
setSelectedBtn(currentIndex + 1);
|
||||
getSelectedBtn(currentIndex + 1);
|
||||
}
|
||||
deleteMenuItem(selectedBtn - 1);
|
||||
modal.destroy();
|
||||
},
|
||||
});
|
||||
}, style: { color: '#1F1F1F' }, children: _jsx(DeleteOutlined, {}) }), selectedBtn < config.button.length
|
||||
&& config.button.length > 1 &&
|
||||
_jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
toRight(selectedBtn);
|
||||
setSelectedBtn(selectedBtn + 1);
|
||||
getSelectedBtn(selectedBtn + 1);
|
||||
}, style: { color: '#1F1F1F' }, children: _jsx(ArrowRightOutlined, {}) })] })] }) }))), config.button.length !== 3 &&
|
||||
_jsx("div", { className: Style.button2, onClick: () => {
|
||||
config.button = [
|
||||
...config.button, {
|
||||
name: '菜单名称',
|
||||
sub_button: [],
|
||||
}
|
||||
];
|
||||
changeConfig(config);
|
||||
setSelectedBtn(config.button.length);
|
||||
getSelectedBtn(config.button.length);
|
||||
}, children: _jsx(PlusOutlined, {}) })] })) : (_jsxs("div", { className: Style.button, onClick: () => {
|
||||
config.button = [{
|
||||
name: '菜单名称',
|
||||
sub_button: [],
|
||||
}];
|
||||
changeConfig(config);
|
||||
setSelectedBtn(1);
|
||||
getSelectedBtn(1);
|
||||
}, children: [_jsx(PlusOutlined, {}), "\u6DFB\u52A0\u83DC\u5355"] }))] })] }) }));
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "wechatMenu", true, {
|
||||
applicationId: string;
|
||||
tagId: string;
|
||||
menuType: string;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
export default OakComponent({
|
||||
isList: true,
|
||||
entity: 'wechatMenu',
|
||||
projection: {
|
||||
id: 1,
|
||||
menuConfig: 1,
|
||||
applicationId: 1,
|
||||
application: {
|
||||
id: 1,
|
||||
type: 1,
|
||||
config: 1,
|
||||
},
|
||||
publishState: 1,
|
||||
wechatPublicTagId: 1,
|
||||
menuId: 1,
|
||||
},
|
||||
formData({ data: rows }) {
|
||||
return {
|
||||
id: rows?.[0]?.id,
|
||||
config: rows?.[0]?.menuConfig,
|
||||
menuId: rows?.[0]?.menuId,
|
||||
};
|
||||
},
|
||||
properties: {
|
||||
applicationId: '',
|
||||
tagId: '',
|
||||
menuType: '',
|
||||
},
|
||||
lifetimes: {
|
||||
async ready() {
|
||||
const { applicationId, tagId } = this.props;
|
||||
const [conditionalmenu] = this.features.cache.get('wechatMenu', {
|
||||
data: {
|
||||
id: 1,
|
||||
menuConfig: 1,
|
||||
menuId: 1,
|
||||
wechatPublicTagId: 1,
|
||||
applicationId: 1,
|
||||
publishState: 1,
|
||||
},
|
||||
filter: {
|
||||
applicationId,
|
||||
wechatPublicTagId: tagId
|
||||
}
|
||||
});
|
||||
if (!conditionalmenu) {
|
||||
this.addItem({
|
||||
wechatPublicTagId: tagId,
|
||||
menuConfig: { button: [], matchrule: { tag_id: tagId } }
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
filters: [
|
||||
{
|
||||
filter() {
|
||||
const { applicationId, tagId } = this.props;
|
||||
return {
|
||||
applicationId,
|
||||
wechatPublicTagId: tagId
|
||||
};
|
||||
}
|
||||
},
|
||||
],
|
||||
methods: {},
|
||||
});
|
||||
|
|
@ -0,0 +1,450 @@
|
|||
.container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.tagList {
|
||||
width: 20%;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.tagHelp {
|
||||
background: var(--oak-bg-color-container);
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
|
||||
.leftBar {
|
||||
width: 300px;
|
||||
margin-right: 25px;
|
||||
|
||||
.phone {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
background: #fcfcfc;
|
||||
border-radius: 8px;
|
||||
|
||||
.topBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
margin: 8px 16px 10px 16px;
|
||||
align-items: center;
|
||||
|
||||
.time {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.actionBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.page {
|
||||
height: 412px;
|
||||
}
|
||||
|
||||
.bottomBar {
|
||||
height: 68px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background: #fcfcfc;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-top: 1px solid #EDEEEF;
|
||||
|
||||
.keyBoard {
|
||||
width: 60px;
|
||||
|
||||
}
|
||||
|
||||
.menu {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
.buttonGroup {
|
||||
position: absolute;
|
||||
top: 73px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 48px;
|
||||
min-width: 48px;
|
||||
border-radius: 24px;
|
||||
background: #fcfcfc;
|
||||
font-size: 24px;
|
||||
padding: 5px;
|
||||
box-shadow: 0 1px 6px #e4e8eb;
|
||||
|
||||
.buttonItem {
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
.buttonItem:hover {
|
||||
background: #EDEEEF;
|
||||
}
|
||||
}
|
||||
|
||||
.menuItem {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.menuName {
|
||||
width: 100%;
|
||||
height: 33px;
|
||||
border-left: 1px solid #EDEEEF;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.button2 {
|
||||
margin: 17px 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-left: 1px solid #EDEEEF;
|
||||
color: #4C4D4E;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1px dashed #1677FF;
|
||||
font-size: 14px;
|
||||
color: #1677FF;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.rightBar {
|
||||
flex: 1;
|
||||
|
||||
.editor {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid #dbdbdb;
|
||||
width: 600px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 40px;
|
||||
border-bottom: 1px solid #EDEEEF;
|
||||
background: #fcfcfc;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 94px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.coverImage {
|
||||
width: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.img {
|
||||
width: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.fileCover {
|
||||
width: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.buttonGroup {
|
||||
margin-left: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 36px;
|
||||
min-height: 36px;
|
||||
border-radius: 18px;
|
||||
background: #fcfcfc;
|
||||
font-size: 18px;
|
||||
padding: 3px;
|
||||
box-shadow: 0 1px 6px #e4e8eb;
|
||||
.buttonItem {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
.buttonItem:hover {
|
||||
background: #EDEEEF;
|
||||
}
|
||||
}
|
||||
|
||||
.menuContent {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
background: #F6F7F8;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
color: #1677FF;
|
||||
}
|
||||
}
|
||||
|
||||
.delete {
|
||||
font-size: 14px;
|
||||
color: #FF5557;
|
||||
cursor: pointer;
|
||||
width: 60px;
|
||||
}
|
||||
.delete:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.actionBar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
background: #fcfcfc;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
padding: 20px 40px 20px 40px;
|
||||
}
|
||||
|
||||
.news {
|
||||
width: 310px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid #dbdbdb;
|
||||
border-radius: 4px;
|
||||
.multiNews {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.cover {
|
||||
width: 308px;
|
||||
height: 130px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
.img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.articleTitle {
|
||||
// color: #fff;
|
||||
padding: 0 12px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
}
|
||||
}
|
||||
.newsItem {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 12px;
|
||||
align-items: center;
|
||||
.articleTitle {
|
||||
width: 220px;
|
||||
font-size: 14px;
|
||||
color: #353535;
|
||||
line-height: 48px;
|
||||
border-bottom: 1px solid #dbdbdb;
|
||||
font-weight: 500;
|
||||
}
|
||||
.imgCover {
|
||||
object-fit: cover;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.newsItem:last-child {
|
||||
.articleTitle {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.singleNews {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.cover {
|
||||
width: 308px;
|
||||
height: 130px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
.img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.articleTitle {
|
||||
padding: 12px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #353535;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.phone {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 374px;
|
||||
background: #f0f0f0;
|
||||
border-radius: 8px;
|
||||
|
||||
.topBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
margin: 8px 16px 12px 16px;
|
||||
align-items: center;
|
||||
|
||||
.time {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.actionBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.page {
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
.bottomBar {
|
||||
height: 68px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #fcfcfc;
|
||||
.keyBoard {
|
||||
width: 60px;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
:global {
|
||||
.ant-popover-inner {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
.subMenuContent {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
.subButtonGroup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 48px;
|
||||
min-height: 48px;
|
||||
border-radius: 24px;
|
||||
background: #fcfcfc;
|
||||
font-size: 24px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
left: 90px;
|
||||
box-shadow: 0 1px 6px #e4e8eb;
|
||||
|
||||
.buttonItem {
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
.buttonItem:hover {
|
||||
background: #EDEEEF;
|
||||
}
|
||||
}
|
||||
}
|
||||
.subMenuItem {
|
||||
width: 86px;
|
||||
height: 49px;
|
||||
text-align: center;
|
||||
padding: 12px 2px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-bottom: 1px solid #EDEEEF;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from "../../../oak-app-domain";
|
||||
export default function Render(props: WebComponentProps<EntityDict, 'wechatMenu', true, {
|
||||
id: string;
|
||||
config: any;
|
||||
file: File;
|
||||
errorIndex: number[];
|
||||
oakId: string;
|
||||
menuIndex: number;
|
||||
applicationId: string;
|
||||
menuType: string;
|
||||
menuId: number;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element | null;
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import Style from './web.module.less';
|
||||
import { Modal } from 'antd';
|
||||
import Preview from '../preview';
|
||||
import ActionPhone from '../actionPhone';
|
||||
import MenuInfo from '../menuInfo';
|
||||
export default function Render(props) {
|
||||
const { data, methods } = props;
|
||||
const { id, oakFullpath, config, menuIndex, applicationId, menuType, menuId, } = data;
|
||||
const { updateItem, removeItem, execute, } = methods;
|
||||
const [isPreview, setIsPreview] = useState(false);
|
||||
const [selectedBtn, setSelectedBtn] = useState(0);
|
||||
const [selectedSubBtn, setSelectedSubBtn] = useState(0);
|
||||
const [currentIndex, setCurrentIndex] = useState(1);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [errorIndex, setErrorIndex] = useState([]);
|
||||
const changeConfig = (config) => {
|
||||
updateItem({
|
||||
menuConfig: config
|
||||
}, id);
|
||||
};
|
||||
const changePublishState = (publishState) => {
|
||||
updateItem({
|
||||
publishState,
|
||||
}, id);
|
||||
};
|
||||
const changeMenuId = (menuId) => {
|
||||
updateItem({
|
||||
menuId
|
||||
}, id);
|
||||
};
|
||||
const deleteMenu = () => {
|
||||
removeItem(id);
|
||||
};
|
||||
const getSelectedBtn = (selectedBtn) => {
|
||||
setSelectedBtn(selectedBtn);
|
||||
};
|
||||
const getSelectedSubBtn = (selectedSubBtn) => {
|
||||
setSelectedSubBtn(selectedSubBtn);
|
||||
};
|
||||
const getCurrentIndex = (currentIndex) => {
|
||||
setCurrentIndex(currentIndex);
|
||||
};
|
||||
const getErrorIndex = (errorIndex) => {
|
||||
setErrorIndex(errorIndex);
|
||||
};
|
||||
const createMenu = async () => {
|
||||
await execute();
|
||||
};
|
||||
const changeIsPreview = (isPreview) => {
|
||||
setIsPreview(isPreview);
|
||||
};
|
||||
const getOpen = (open) => {
|
||||
setOpen(open);
|
||||
};
|
||||
if (oakFullpath) {
|
||||
return (_jsx("div", { className: Style.container, children: _jsxs("div", { className: Style.content, children: [_jsx("div", { className: Style.leftBar, children: _jsx(ActionPhone, { oakAutoUnmount: true, config: config, menuIndex: menuIndex, changeConfig: changeConfig, menuType: menuType, getSelectedBtn: getSelectedBtn, getSelectedSubBtn: getSelectedSubBtn, getCurrentIndex: getCurrentIndex, errorIndex: errorIndex, isPreview: isPreview, open: open }) }), _jsx("div", { className: Style.rightBar, children: _jsx(MenuInfo, { oakAutoUnmount: true, config: config, menuIndex: menuIndex, changeConfig: changeConfig, changePublishState: changePublishState, selectedBtn: selectedBtn, selectedSubBtn: selectedSubBtn, currentIndex: currentIndex, getErrorIndex: getErrorIndex, createMenu: createMenu, changeIsPreview: changeIsPreview, getOpen: getOpen, menuType: menuType, applicationId: applicationId, changeMenuId: changeMenuId, deleteMenu: deleteMenu, menuId: menuId }) }), _jsx(Modal, { title: '\u83DC\u5355\u9884\u89C8', open: isPreview, onCancel: () => setIsPreview(false), footer: null, width: 424, children: _jsx(Preview, { button: config?.button, applicationId: applicationId }) })] }) }));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../oak-app-domain").EntityDict, keyof import("../../oak-app-domain").EntityDict, true, {
|
||||
applicationId: string;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
export default OakComponent({
|
||||
isList: true,
|
||||
properties: {
|
||||
applicationId: '',
|
||||
},
|
||||
lifetimes: {
|
||||
async ready() {
|
||||
const { applicationId } = this.props;
|
||||
const result = await this.features.wechatMenu.getCurrentMenu({ applicationId: applicationId });
|
||||
if (result.is_menu_open === 1) {
|
||||
const { data: wechatMenu } = await this.features.cache.refresh('wechatMenu', {
|
||||
data: {
|
||||
id: 1,
|
||||
applicationId: 1,
|
||||
},
|
||||
filter: {
|
||||
applicationId,
|
||||
}
|
||||
});
|
||||
if (wechatMenu && wechatMenu[0]) {
|
||||
this.setState({
|
||||
menuId: wechatMenu[0].id,
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
is_menu_open: true,
|
||||
applicationId,
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.setState({
|
||||
is_menu_open: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
});
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "wechatMenu", true, {
|
||||
applicationId: string;
|
||||
menuId: string;
|
||||
menuType: string;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
export default OakComponent({
|
||||
isList: true,
|
||||
entity: 'wechatMenu',
|
||||
projection: {
|
||||
id: 1,
|
||||
menuConfig: 1,
|
||||
applicationId: 1,
|
||||
application: {
|
||||
id: 1,
|
||||
type: 1,
|
||||
config: 1,
|
||||
},
|
||||
publishState: 1,
|
||||
wechatPublicTagId: 1,
|
||||
menuId: 1,
|
||||
},
|
||||
formData({ data: rows }) {
|
||||
return {
|
||||
id: rows?.[0]?.id,
|
||||
config: rows?.[0]?.menuConfig,
|
||||
totalConfig: rows?.[0]?.menuConfig,
|
||||
};
|
||||
},
|
||||
filters: [
|
||||
{
|
||||
filter() {
|
||||
const { applicationId } = this.props;
|
||||
return {
|
||||
applicationId,
|
||||
wechatPublicTagId: {
|
||||
$exists: false
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
],
|
||||
properties: {
|
||||
applicationId: '',
|
||||
menuId: '',
|
||||
menuType: '',
|
||||
},
|
||||
lifetimes: {
|
||||
async ready() {
|
||||
const { menuId, applicationId } = this.props;
|
||||
if (!menuId) {
|
||||
const menuConfig = await this.features.wechatMenu.getMenu({ applicationId: applicationId });
|
||||
console.log(menuConfig);
|
||||
this.addItem({
|
||||
menuConfig: { button: menuConfig.menu.button },
|
||||
applicationId,
|
||||
publishState: 'wait',
|
||||
menuId: menuConfig.menu.menuid
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
});
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
.container {
|
||||
width: 100%;
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
|
||||
.leftBar {
|
||||
width: 300px;
|
||||
margin-right: 25px;
|
||||
}
|
||||
|
||||
.rightBar {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.phone {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 374px;
|
||||
background: #f0f0f0;
|
||||
border-radius: 8px;
|
||||
|
||||
.topBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
margin: 8px 16px 12px 16px;
|
||||
align-items: center;
|
||||
|
||||
.time {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.actionBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.page {
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
.bottomBar {
|
||||
height: 68px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #fcfcfc;
|
||||
.keyBoard {
|
||||
width: 60px;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { WechatPublicInstance } from 'oak-external-sdk';
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from "../../../oak-app-domain";
|
||||
export default function Render(props: WebComponentProps<EntityDict, 'wechatMenu', true, {
|
||||
id: string;
|
||||
config: any;
|
||||
totalConfig: any;
|
||||
file: File;
|
||||
wechatInstance: WechatPublicInstance;
|
||||
errorIndex: number[];
|
||||
oakId: string;
|
||||
menuType: string;
|
||||
applicationId: string;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element | null;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import Style from './web.module.less';
|
||||
import { Modal } from 'antd';
|
||||
import Preview from '../preview';
|
||||
import ActionPhone from '../actionPhone';
|
||||
import MenuInfo from '../menuInfo';
|
||||
export default function Render(props) {
|
||||
const { data, methods } = props;
|
||||
const { id, oakFullpath, config, wechatInstance, totalConfig, menuType, applicationId } = data;
|
||||
const { updateItem, execute } = methods;
|
||||
const [open, setOpen] = useState(false);
|
||||
const [isPreview, setIsPreview] = useState(false);
|
||||
const [selectedBtn, setSelectedBtn] = useState(0);
|
||||
const [selectedSubBtn, setSelectedSubBtn] = useState(0);
|
||||
const [currentIndex, setCurrentIndex] = useState(1);
|
||||
const [errorIndex, setErrorIndex] = useState([]);
|
||||
const changeConfig = (config) => {
|
||||
updateItem({
|
||||
menuConfig: config
|
||||
}, id);
|
||||
};
|
||||
const changePublishState = (publishState) => {
|
||||
updateItem({
|
||||
publishState,
|
||||
}, id);
|
||||
};
|
||||
const getSelectedBtn = (selectedBtn) => {
|
||||
setSelectedBtn(selectedBtn);
|
||||
};
|
||||
const getSelectedSubBtn = (selectedSubBtn) => {
|
||||
setSelectedSubBtn(selectedSubBtn);
|
||||
};
|
||||
const getCurrentIndex = (currentIndex) => {
|
||||
setCurrentIndex(currentIndex);
|
||||
};
|
||||
const getErrorIndex = (errorIndex) => {
|
||||
setErrorIndex(errorIndex);
|
||||
};
|
||||
const createMenu = async () => {
|
||||
await execute();
|
||||
};
|
||||
const changeIsPreview = (isPreview) => {
|
||||
setIsPreview(isPreview);
|
||||
};
|
||||
const getOpen = (open) => {
|
||||
setOpen(open);
|
||||
};
|
||||
if (oakFullpath) {
|
||||
return (_jsx("div", { className: Style.container, children: _jsxs("div", { className: Style.content, children: [_jsx("div", { className: Style.leftBar, children: _jsx(ActionPhone, { oakAutoUnmount: true, config: config, changeConfig: changeConfig, menuType: menuType, getSelectedBtn: getSelectedBtn, getSelectedSubBtn: getSelectedSubBtn, getCurrentIndex: getCurrentIndex, errorIndex: errorIndex, isPreview: isPreview, open: open }) }), _jsx("div", { className: Style.rightBar, children: _jsx(MenuInfo, { oakAutoUnmount: true, config: config, changeConfig: changeConfig, changePublishState: changePublishState, selectedBtn: selectedBtn, selectedSubBtn: selectedSubBtn, currentIndex: currentIndex, getErrorIndex: getErrorIndex, createMenu: createMenu, changeIsPreview: changeIsPreview, getOpen: getOpen, menuType: menuType, applicationId: applicationId }) }), _jsx(Modal, { title: '\u83DC\u5355\u9884\u89C8', open: isPreview, onCancel: () => setIsPreview(false), footer: null, width: 424, children: _jsx(Preview, { button: config?.button, applicationId: applicationId }) })] }) }));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
id: string;
|
||||
config: any;
|
||||
menuIndex: number;
|
||||
changeConfig: (config: any) => void;
|
||||
changePublishState: (publish: "wait" | "success" | "fail") => void;
|
||||
getErrorIndex: (errorIndex: number[]) => void;
|
||||
createMenu: () => Promise<void>;
|
||||
selectedBtn: number;
|
||||
selectedSubBtn: number;
|
||||
currentIndex: number;
|
||||
changeIsPreview: (isPreview: boolean) => void;
|
||||
getOpen: (open: boolean) => void;
|
||||
menuType: string;
|
||||
applicationId: string;
|
||||
changeMenuId: (menuId: number) => void;
|
||||
deleteMenu: () => void;
|
||||
menuId: number;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
export default OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
id: '',
|
||||
config: null,
|
||||
menuIndex: 0,
|
||||
changeConfig: (config) => undefined,
|
||||
changePublishState: (publish) => undefined,
|
||||
getErrorIndex: (errorIndex) => undefined,
|
||||
createMenu: async () => undefined,
|
||||
selectedBtn: 0,
|
||||
selectedSubBtn: 0,
|
||||
currentIndex: 1,
|
||||
changeIsPreview: (isPreview) => undefined,
|
||||
getOpen: (open) => undefined,
|
||||
menuType: '',
|
||||
applicationId: '',
|
||||
changeMenuId: (menuId) => undefined,
|
||||
deleteMenu: () => undefined,
|
||||
menuId: null,
|
||||
},
|
||||
data: {},
|
||||
methods: {
|
||||
setConfig(index, content, currentIndex) {
|
||||
const { config, changeConfig } = this.props;
|
||||
if (typeof currentIndex === 'number') {
|
||||
content.name = config.button[currentIndex].sub_button[index].name;
|
||||
config.button[currentIndex].sub_button[index] = content;
|
||||
changeConfig(config);
|
||||
}
|
||||
else {
|
||||
content.name = config.button[index].name;
|
||||
content.sub_button = [...config.button[index].sub_button];
|
||||
config.button[index] = content;
|
||||
changeConfig(config);
|
||||
}
|
||||
},
|
||||
confirmName(menuName) {
|
||||
if (Object.prototype.toString.call(menuName).slice(8, -1).toLowerCase() !== 'string') {
|
||||
throw Error('param str type error ');
|
||||
}
|
||||
else if (!menuName) {
|
||||
return '请输入菜单名称';
|
||||
}
|
||||
else if (!/^[\u4e00-\u9fa5a-zA-Z0-9]+$/.test(menuName)) {
|
||||
return '字符串中包含除中文、数字、英文以外的字符!';
|
||||
}
|
||||
else if (menuName.replace(/[\u4e00-\u9fa5]/g, "**").length > 8) {
|
||||
return '字符串长度超过限制!';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
confirmSubName(menuName) {
|
||||
if (Object.prototype.toString.call(menuName).slice(8, -1).toLowerCase() !== 'string') {
|
||||
throw Error('param str type error ');
|
||||
}
|
||||
else if (!menuName) {
|
||||
return '请输入子菜单名称';
|
||||
}
|
||||
else if (!/^[\u4e00-\u9fa5a-zA-Z0-9]+$/.test(menuName)) {
|
||||
return '字符串中包含除中文、数字、英文以外的字符!';
|
||||
}
|
||||
else if (menuName.replace(/[\u4e00-\u9fa5]/g, "**").length > 16) {
|
||||
return '字符串长度超过限制!';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
editMenuName(index, name, currentIndex) {
|
||||
const { config, changeConfig } = this.props;
|
||||
if (typeof currentIndex === 'number') {
|
||||
config.button[currentIndex].sub_button[index].name = name;
|
||||
changeConfig(config);
|
||||
}
|
||||
else {
|
||||
config.button[index].name = name;
|
||||
changeConfig(config);
|
||||
}
|
||||
},
|
||||
deleteMenuContent(index, currentIndex) {
|
||||
const { config, changeConfig } = this.props;
|
||||
if (typeof currentIndex === 'number') {
|
||||
config.button[currentIndex].sub_button[index] = { name: config.button[currentIndex].sub_button[index].name };
|
||||
changeConfig(config);
|
||||
}
|
||||
else {
|
||||
config.button[index] = { name: config.button[index].name, sub_button: [...config.button[index].sub_button] };
|
||||
changeConfig(config);
|
||||
}
|
||||
},
|
||||
async getMaterialImgAndVoice(type, media_id) {
|
||||
const { applicationId } = this.props;
|
||||
return new Promise((resolve, reject) => {
|
||||
this.features.wechatMenu.getMaterial({ applicationId: applicationId, type, media_id })
|
||||
.then(file => {
|
||||
let reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = function (e) {
|
||||
resolve(e.target?.result);
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
async getMaterialVideo(media_id) {
|
||||
const { applicationId } = this.props;
|
||||
const result = await this.features.wechatMenu.getMaterial({ applicationId: applicationId, type: 'video', media_id });
|
||||
if (result && result.down_url) {
|
||||
return { url: result.down_url, media_id };
|
||||
}
|
||||
},
|
||||
decideMenuContentLabel(decidedMenuContent, type) {
|
||||
if (!decidedMenuContent && type !== 'text') {
|
||||
return '菜单内容';
|
||||
}
|
||||
else if (decidedMenuContent) {
|
||||
switch (type) {
|
||||
case 'news':
|
||||
return '图文信息';
|
||||
case 'image':
|
||||
return '图片';
|
||||
case 'voice':
|
||||
return '音频';
|
||||
case 'video':
|
||||
return '视频';
|
||||
default:
|
||||
return '文字';
|
||||
}
|
||||
}
|
||||
else {
|
||||
return '文字'; // 默认值
|
||||
}
|
||||
},
|
||||
async getArticle(article_id) {
|
||||
const { applicationId } = this.props;
|
||||
const result = await this.features.wechatMenu.getArticle({ applicationId: applicationId, article_id });
|
||||
if (result && result.news_item) {
|
||||
const modifiedResult = await Promise.all(result.news_item.map(async (ele) => {
|
||||
const coverUrl = await this.getMaterialImgAndVoice('image', ele.thumb_media_id);
|
||||
return {
|
||||
...ele,
|
||||
coverUrl
|
||||
};
|
||||
}));
|
||||
return modifiedResult;
|
||||
}
|
||||
},
|
||||
checkError(arr) {
|
||||
const { getErrorIndex } = this.props;
|
||||
const errorIndex = [];
|
||||
arr.map((ele, index) => {
|
||||
if (ele.sub_button && ele.sub_button.length > 0) {
|
||||
ele.sub_button.map((ele, index2) => {
|
||||
if (Object.keys(ele).length === 1 && ele.hasOwnProperty('name')) {
|
||||
errorIndex.push((index + 1) * 10 + index2);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (Object.keys(ele).length === 2 && ele.hasOwnProperty('name')) {
|
||||
console.log(index);
|
||||
errorIndex.push(index);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.setState({
|
||||
errorIndex,
|
||||
});
|
||||
getErrorIndex(errorIndex);
|
||||
return errorIndex;
|
||||
},
|
||||
async createMenu() {
|
||||
const { applicationId, config, changeConfig, changePublishState, createMenu, menuType, changeMenuId } = this.props;
|
||||
if (this.checkError(config.button).length === 0 && config.button.length > 0) {
|
||||
changeConfig(config);
|
||||
const removeSubTypeAndContent = (obj) => {
|
||||
const { subType, content, ...newObj } = obj;
|
||||
return newObj;
|
||||
};
|
||||
const menuConfig = config.button.map((item) => {
|
||||
if (item.sub_button && item.sub_button.length > 0) {
|
||||
const sub_button = item.sub_button.map(removeSubTypeAndContent);
|
||||
return { ...removeSubTypeAndContent(item), sub_button };
|
||||
}
|
||||
else {
|
||||
return removeSubTypeAndContent(item);
|
||||
}
|
||||
});
|
||||
if (menuType === 'common') {
|
||||
const result = await this.features.wechatMenu.createMenu({ applicationId: applicationId, menuConfig: { button: menuConfig } });
|
||||
if (result.success) {
|
||||
changePublishState('success');
|
||||
}
|
||||
else {
|
||||
changePublishState('fail');
|
||||
}
|
||||
await createMenu();
|
||||
}
|
||||
else {
|
||||
const button = { button: menuConfig, matchrule: config.matchrule };
|
||||
const result = await this.features.wechatMenu.createConditionalMenu({ applicationId: applicationId, menuConfig: button });
|
||||
if (result.success) {
|
||||
changeMenuId(result.menuid);
|
||||
changePublishState('success');
|
||||
}
|
||||
else {
|
||||
changePublishState('fail');
|
||||
}
|
||||
await createMenu();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (config.button.length === 0) {
|
||||
this.setMessage({
|
||||
content: '请添加自定义菜单',
|
||||
type: 'warning'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if ((this.checkError(config.button).length > 0)) {
|
||||
this.setMessage({
|
||||
content: '请添加菜单消息',
|
||||
type: 'warning'
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
async deleteConditionalMenu() {
|
||||
const { applicationId, deleteMenu, menuIndex, menuId, createMenu } = this.props;
|
||||
const result = await this.features.wechatMenu.deleteConditionalMenu({ applicationId: applicationId, menuid: menuId });
|
||||
if (result.success) {
|
||||
deleteMenu();
|
||||
await createMenu();
|
||||
}
|
||||
else {
|
||||
this.setMessage({
|
||||
type: 'error',
|
||||
content: result.errmsg
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
.container {
|
||||
width: 100%;
|
||||
|
||||
.editor {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid #dbdbdb;
|
||||
width: 600px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 40px;
|
||||
border-bottom: 1px solid #EDEEEF;
|
||||
background: #fcfcfc;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 94px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.coverImage {
|
||||
width: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.img {
|
||||
width: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.fileCover {
|
||||
width: 300px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.buttonGroup {
|
||||
margin-left: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 36px;
|
||||
min-height: 36px;
|
||||
border-radius: 18px;
|
||||
background: #fcfcfc;
|
||||
font-size: 18px;
|
||||
padding: 3px;
|
||||
box-shadow: 0 1px 6px #e4e8eb;
|
||||
.buttonItem {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
.buttonItem:hover {
|
||||
background: #EDEEEF;
|
||||
}
|
||||
}
|
||||
|
||||
.menuContent {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
background: #F6F7F8;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
color: #1677FF;
|
||||
}
|
||||
}
|
||||
|
||||
.delete {
|
||||
font-size: 14px;
|
||||
color: #FF5557;
|
||||
cursor: pointer;
|
||||
width: 60px;
|
||||
}
|
||||
.delete:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.actionBar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
background: #fcfcfc;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
padding: 20px 40px 20px 40px;
|
||||
}
|
||||
|
||||
.news {
|
||||
width: 310px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid #dbdbdb;
|
||||
border-radius: 4px;
|
||||
.multiNews {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.cover {
|
||||
width: 308px;
|
||||
height: 130px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
.img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.articleTitle {
|
||||
// color: #fff;
|
||||
padding: 0 12px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
}
|
||||
}
|
||||
.newsItem {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 12px;
|
||||
align-items: center;
|
||||
.articleTitle {
|
||||
width: 220px;
|
||||
font-size: 14px;
|
||||
color: #353535;
|
||||
line-height: 48px;
|
||||
border-bottom: 1px solid #dbdbdb;
|
||||
font-weight: 500;
|
||||
}
|
||||
.imgCover {
|
||||
object-fit: cover;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.newsItem:last-child {
|
||||
.articleTitle {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.singleNews {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.cover {
|
||||
width: 308px;
|
||||
height: 130px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
.img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.articleTitle {
|
||||
padding: 12px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #353535;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { EntityDict } from "../../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, {
|
||||
id: string;
|
||||
config: any;
|
||||
menuIndex: number;
|
||||
file: File;
|
||||
errorIndex: number[];
|
||||
oakId: string;
|
||||
menuType: string;
|
||||
selectedBtn: number;
|
||||
selectedSubBtn: number;
|
||||
currentIndex: number;
|
||||
getNewSelectedBtn: (selectedBtn: number) => void;
|
||||
getNewSelectedSubBtn: (selectedSubBtn: number) => void;
|
||||
getNewCurrentIndex: (currentIndex: number) => void;
|
||||
changeIsPreview: (isPreview: boolean) => void;
|
||||
getOpen: (open: boolean) => void;
|
||||
applicationId: string;
|
||||
menuId: number;
|
||||
}, {
|
||||
setConfig: (index: number, content: any, currentIndex?: number) => void;
|
||||
confirmName: (menuName: string) => string;
|
||||
confirmSubName: (menuName: string) => string;
|
||||
toRight: (index: number) => void;
|
||||
toLeft: (index: number) => void;
|
||||
toUp: (currentIndex: number, index: number) => void;
|
||||
toDown: (currentIndex: number, index: number) => void;
|
||||
editMenuName: (index: number, name: string, currentIndex?: number) => void;
|
||||
deleteMenuContent: (index: number, currentIndex?: number) => void;
|
||||
getMaterialImgAndVoice: (type: string, media_id: string) => Promise<string>;
|
||||
getMaterialVideo: (media_id: string) => void;
|
||||
decideMenuContentLabel: (obj: any, type: 'news' | 'image' | 'video' | 'voice' | 'text') => string;
|
||||
getArticle: (article_id: string) => void;
|
||||
createMenu: () => void;
|
||||
deleteConditionalMenu: () => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,399 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Modal, Button, Space, Radio, Form, Input } from 'antd';
|
||||
const { Search } = Input;
|
||||
const { confirm } = Modal;
|
||||
import Style from './web.module.less';
|
||||
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
||||
import { EyeOutlined, CheckOutlined, DeleteOutlined, DownloadOutlined, SwapOutlined, } from '@ant-design/icons';
|
||||
import ShowNews from '../showNews';
|
||||
import WechatMaterialLibrary from '../../wechatMaterialLibrary';
|
||||
import SelectMiniprogram from '../selectMiniprogram';
|
||||
import SelectArticle from '../selectArticle';
|
||||
import TextClick from '../textClick';
|
||||
export default function Render(props) {
|
||||
const { data, methods } = props;
|
||||
const { config, menuIndex, selectedBtn, selectedSubBtn, currentIndex, changeIsPreview, getOpen, menuType, applicationId, menuId } = data;
|
||||
const { setConfig, confirmName, confirmSubName, editMenuName, deleteMenuContent, getMaterialImgAndVoice, getMaterialVideo, decideMenuContentLabel, getArticle, createMenu, deleteConditionalMenu } = methods;
|
||||
const [msgType, setMsgType] = useState('sendMsg');
|
||||
const [errorInfo, setErrorInfo] = useState('');
|
||||
const [onlyOne, setOnlyOne] = useState(true);
|
||||
const [menuName, setMenuName] = useState('');
|
||||
const [open, setOpen] = useState(false);
|
||||
const [type, setType] = useState('');
|
||||
const [menuContent, setMenuContent] = useState(null);
|
||||
const [decidedMenuContent, setDecidedMenuContent] = useState(null);
|
||||
const [url, setUrl] = useState('');
|
||||
const getUrl = (url) => {
|
||||
setUrl(url);
|
||||
};
|
||||
const getMenuContent = (menuContent) => {
|
||||
setMenuContent(menuContent);
|
||||
if (msgType === 'miniprogram') {
|
||||
if (selectedBtn > 0) {
|
||||
setConfig(selectedBtn - 1, { type: 'miniprogram', url: menuContent.url, pagepath: menuContent.pagepath, appid: menuContent.appid });
|
||||
}
|
||||
else {
|
||||
setConfig(selectedSubBtn - 1, { type: 'miniprogram', url: menuContent.url, pagepath: menuContent.pagepath, appid: menuContent.appid }, currentIndex);
|
||||
}
|
||||
}
|
||||
};
|
||||
const changeOpen = (open) => {
|
||||
setOpen(open);
|
||||
getOpen(open);
|
||||
};
|
||||
const getDecidedMenuContent = async (menuContent) => {
|
||||
setDecidedMenuContent(menuContent);
|
||||
if (selectedBtn > 0) {
|
||||
setConfig(selectedBtn - 1, { type: 'click', key: await generateNewIdAsync(), subType: 'text', content: menuContent });
|
||||
}
|
||||
else {
|
||||
setConfig(selectedSubBtn - 1, { type: 'click', key: await generateNewIdAsync(), subType: 'text', content: menuContent }, currentIndex);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
console.log(config);
|
||||
if (config && config.button && config.button[0] && onlyOne) {
|
||||
setMenuName(config.button[0].name);
|
||||
setOnlyOne(false);
|
||||
}
|
||||
}, [config]);
|
||||
useEffect(() => {
|
||||
const fetchData = async (id, type) => {
|
||||
if (type === 'news') {
|
||||
setDecidedMenuContent({ content: { news_item: await getArticle(id) } });
|
||||
}
|
||||
if (type === 'video') {
|
||||
setDecidedMenuContent(await getMaterialVideo(id));
|
||||
}
|
||||
if (type === 'image' || type === 'voice') {
|
||||
setDecidedMenuContent({ url: await getMaterialImgAndVoice(type, id), media_id: id });
|
||||
}
|
||||
};
|
||||
if (selectedBtn !== 0) {
|
||||
const menuConfig = config.button[selectedBtn - 1];
|
||||
setMenuName(menuConfig?.name);
|
||||
if (menuConfig?.type === 'media_id') {
|
||||
setUrl('');
|
||||
setMsgType('sendMsg');
|
||||
setType(menuConfig.subType);
|
||||
if (menuConfig.subType === 'video') {
|
||||
fetchData(menuConfig.media_id, 'video');
|
||||
}
|
||||
else {
|
||||
fetchData(menuConfig.media_id, menuConfig.subType);
|
||||
}
|
||||
}
|
||||
else if (menuConfig?.type === 'click') {
|
||||
setUrl('');
|
||||
setMsgType('sendMsg');
|
||||
setType('text');
|
||||
setDecidedMenuContent(menuConfig.content);
|
||||
}
|
||||
else if (menuConfig?.type === 'article_id') {
|
||||
setUrl('');
|
||||
setMsgType('sendMsg');
|
||||
setType('news');
|
||||
fetchData(menuConfig.article_id, 'news');
|
||||
}
|
||||
else if (menuConfig?.type === 'miniprogram') {
|
||||
setUrl('');
|
||||
setMsgType('miniprogram');
|
||||
setMenuContent({
|
||||
appid: menuConfig.appid,
|
||||
url: menuConfig.url,
|
||||
pagepath: menuConfig.pagepath
|
||||
});
|
||||
}
|
||||
else if (menuConfig?.type === 'view') {
|
||||
setMsgType('view');
|
||||
setUrl(menuConfig.url);
|
||||
}
|
||||
else {
|
||||
setUrl('');
|
||||
setType('');
|
||||
setMsgType('sendMsg');
|
||||
setDecidedMenuContent(null);
|
||||
setMenuContent(null);
|
||||
}
|
||||
}
|
||||
}, [selectedBtn]);
|
||||
useEffect(() => {
|
||||
const fetchData = async (id, type) => {
|
||||
if (type === 'news') {
|
||||
setDecidedMenuContent({ content: { news_item: await getArticle(id) } });
|
||||
}
|
||||
if (type === 'video') {
|
||||
setDecidedMenuContent(await getMaterialVideo(id));
|
||||
}
|
||||
if (type === 'image' || type === 'voice') {
|
||||
setDecidedMenuContent({ url: await getMaterialImgAndVoice(type, id), media_id: id });
|
||||
}
|
||||
};
|
||||
if (selectedSubBtn !== 0) {
|
||||
const subMenuConfig = config.button[currentIndex]?.sub_button[selectedSubBtn - 1];
|
||||
setMenuName(subMenuConfig?.name);
|
||||
if (subMenuConfig?.type === 'media_id') {
|
||||
setUrl('');
|
||||
setMsgType('sendMsg');
|
||||
setType(subMenuConfig.subType);
|
||||
if (subMenuConfig.subType === 'video') {
|
||||
fetchData(subMenuConfig.media_id, 'video');
|
||||
}
|
||||
else {
|
||||
fetchData(subMenuConfig.media_id, subMenuConfig.subType);
|
||||
}
|
||||
}
|
||||
else if (subMenuConfig?.type === 'click') {
|
||||
setUrl('');
|
||||
setMsgType('sendMsg');
|
||||
setType('text');
|
||||
setDecidedMenuContent(subMenuConfig.content);
|
||||
}
|
||||
else if (subMenuConfig?.type === 'article_id') {
|
||||
setUrl('');
|
||||
setMsgType('sendMsg');
|
||||
setType('news');
|
||||
fetchData(subMenuConfig?.article_id, 'news');
|
||||
}
|
||||
else if (subMenuConfig?.type === 'miniprogram') {
|
||||
setUrl('');
|
||||
setMsgType('miniprogram');
|
||||
setMenuContent({
|
||||
appid: subMenuConfig.appid,
|
||||
url: subMenuConfig.url,
|
||||
pagepath: subMenuConfig.pagepath
|
||||
});
|
||||
}
|
||||
else if (subMenuConfig?.type === 'view') {
|
||||
setMsgType('view');
|
||||
setUrl(subMenuConfig.url);
|
||||
}
|
||||
else {
|
||||
setType('');
|
||||
setUrl('');
|
||||
setMsgType('sendMsg');
|
||||
setDecidedMenuContent(null);
|
||||
setMenuContent(null);
|
||||
}
|
||||
}
|
||||
}, [selectedSubBtn]);
|
||||
useEffect(() => {
|
||||
if (url && url.length > 0) {
|
||||
if (selectedBtn > 0) {
|
||||
setConfig(selectedBtn - 1, { type: 'view', url });
|
||||
}
|
||||
else {
|
||||
setConfig(selectedSubBtn - 1, { type: 'view', url }, currentIndex);
|
||||
}
|
||||
}
|
||||
}, [url]);
|
||||
return (_jsx("div", { className: Style.container, children: config && config.button && config.button.length > 0 && (selectedBtn !== 0 || selectedSubBtn !== 0) ? (_jsxs("div", { className: Style.upsertMenu, children: [_jsxs("div", { className: Style.content, children: [_jsx("div", { className: Style.title, children: selectedSubBtn !== 0 ? '子菜单信息' : '菜单信息' }), _jsx("div", { style: { marginBottom: 32 }, children: _jsx(Form.Item, { label: _jsx("div", { className: Style.label, children: "\u540D\u79F0" }), colon: false, help: _jsxs("div", { children: [_jsx("div", { children: `仅支持中英文和数字,字数不超过${selectedSubBtn !== 0 ? 8 : 4}个汉字或${selectedSubBtn !== 0 ? 16 : 8}个字母。` }), errorInfo && _jsx("div", { style: { color: '#fa5151' }, children: errorInfo })] }), children: _jsx(Input, { style: { width: 340 }, onChange: (val) => {
|
||||
setMenuName(val.target.value);
|
||||
if (selectedSubBtn !== 0) {
|
||||
setErrorInfo(confirmSubName(val.target.value));
|
||||
if (!confirmSubName(val.target.value)) {
|
||||
editMenuName(selectedSubBtn - 1, val.target.value, currentIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setErrorInfo(confirmName(val.target.value));
|
||||
if (!confirmName(val.target.value)) {
|
||||
editMenuName(selectedBtn - 1, val.target.value);
|
||||
}
|
||||
}
|
||||
}, status: errorInfo ? 'error' : '', value: menuName }) }) }), config.button[currentIndex]?.sub_button?.length === 0 && selectedSubBtn === 0
|
||||
|| selectedSubBtn > 0 ? (_jsxs(_Fragment, { children: [_jsx(Form.Item, { colon: false, label: _jsx("div", { className: Style.label, children: "\u6D88\u606F\u7C7B\u578B" }), children: _jsxs(Radio.Group, { value: msgType, onChange: (val) => setMsgType(val.target.value), children: [_jsx(Radio, { value: 'sendMsg', children: "\u53D1\u9001\u6D88\u606F" }), _jsx(Radio, { value: 'view', children: "\u8DF3\u8F6C\u9875\u9762" }), _jsx(Radio, { value: 'miniprogram', children: "\u8DF3\u8F6C\u5C0F\u7A0B\u5E8F" })] }) }), msgType === 'sendMsg' ? (_jsxs(_Fragment, { children: [_jsxs(Form.Item, { colon: false, label: _jsx("div", { className: Style.label, children: decideMenuContentLabel(decidedMenuContent, type) }), children: [!decidedMenuContent && type !== 'text' ? _jsxs("div", { className: Style.menuContent, children: [_jsx("div", { className: Style.item, onClick: () => {
|
||||
setOpen(true);
|
||||
getOpen(true);
|
||||
setType('news');
|
||||
}, children: "\u56FE\u6587\u4FE1\u606F" }), _jsx("div", { className: Style.item, onClick: () => {
|
||||
setType('text');
|
||||
}, children: "\u6587\u5B57" }), _jsx("div", { className: Style.item, onClick: () => {
|
||||
setOpen(true);
|
||||
getOpen(true);
|
||||
setType('image');
|
||||
}, children: "\u56FE\u7247" }), _jsx("div", { className: Style.item, onClick: () => {
|
||||
setOpen(true);
|
||||
getOpen(true);
|
||||
setType('voice');
|
||||
}, children: "\u97F3\u9891" }), _jsx("div", { className: Style.item, onClick: () => {
|
||||
setOpen(true);
|
||||
getOpen(true);
|
||||
setType('video');
|
||||
}, children: "\u89C6\u9891" })] })
|
||||
: type === 'image' ?
|
||||
_jsxs("div", { className: Style.coverImage, children: [_jsx("img", { className: Style.img, src: decidedMenuContent.url }), _jsxs("div", { className: Style.buttonGroup, children: [_jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
const modal = confirm({
|
||||
title: '确定删除该图片吗?',
|
||||
content: '删除后不可恢复',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: async (e) => {
|
||||
modal.destroy();
|
||||
setDecidedMenuContent(null);
|
||||
if (selectedBtn > 0) {
|
||||
deleteMenuContent(selectedBtn - 1);
|
||||
}
|
||||
else {
|
||||
deleteMenuContent(selectedSubBtn - 1, currentIndex);
|
||||
}
|
||||
;
|
||||
},
|
||||
});
|
||||
}, children: _jsx(DeleteOutlined, {}) }), _jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
setOpen(true);
|
||||
getOpen(true);
|
||||
}, children: _jsx(SwapOutlined, {}) })] })] })
|
||||
: type === 'voice' ?
|
||||
_jsxs("div", { className: Style.fileCover, children: [_jsxs("a", { href: decidedMenuContent.url, download: true, style: { color: '#1677FF', cursor: 'pointer' }, children: [_jsx(DownloadOutlined, {}), decidedMenuContent.media_id] }), _jsxs("div", { className: Style.buttonGroup, children: [_jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
const modal = confirm({
|
||||
title: '确定删除该音频吗?',
|
||||
content: '删除后不可恢复',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: async (e) => {
|
||||
modal.destroy();
|
||||
setDecidedMenuContent(null);
|
||||
if (selectedBtn > 0) {
|
||||
deleteMenuContent(selectedBtn - 1);
|
||||
}
|
||||
else {
|
||||
deleteMenuContent(selectedSubBtn - 1, currentIndex);
|
||||
}
|
||||
;
|
||||
},
|
||||
});
|
||||
}, children: _jsx(DeleteOutlined, {}) }), _jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
setOpen(true);
|
||||
getOpen(true);
|
||||
}, children: _jsx(SwapOutlined, {}) })] })] })
|
||||
: type === 'video' ?
|
||||
_jsxs("div", { className: Style.fileCover, children: [_jsxs("a", { href: decidedMenuContent.url, download: true, style: { color: '#1677FF', cursor: 'pointer' }, children: [_jsx(DownloadOutlined, {}), decidedMenuContent.media_id] }), _jsxs("div", { className: Style.buttonGroup, children: [_jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
const modal = confirm({
|
||||
title: '确定删除该视频吗?',
|
||||
content: '删除后不可恢复',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: async (e) => {
|
||||
modal.destroy();
|
||||
setDecidedMenuContent(null);
|
||||
if (selectedBtn > 0) {
|
||||
deleteMenuContent(selectedBtn - 1);
|
||||
}
|
||||
else {
|
||||
deleteMenuContent(selectedSubBtn - 1, currentIndex);
|
||||
}
|
||||
;
|
||||
},
|
||||
});
|
||||
}, children: _jsx(DeleteOutlined, {}) }), _jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
setOpen(true);
|
||||
getOpen(true);
|
||||
}, children: _jsx(SwapOutlined, {}) })] })] })
|
||||
: type === 'news' ?
|
||||
_jsxs("div", { className: Style.news, children: [_jsx(ShowNews, { news: decidedMenuContent?.content?.news_item, oakAutoUnmount: false }), _jsxs("div", { className: Style.buttonGroup, style: { height: '100%' }, children: [_jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
const modal = confirm({
|
||||
title: '确定删除该图文信息吗?',
|
||||
content: '删除后不可恢复',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: async (e) => {
|
||||
modal.destroy();
|
||||
setDecidedMenuContent(null);
|
||||
if (selectedBtn > 0) {
|
||||
deleteMenuContent(selectedBtn - 1);
|
||||
}
|
||||
else {
|
||||
deleteMenuContent(selectedSubBtn - 1, currentIndex);
|
||||
}
|
||||
;
|
||||
},
|
||||
});
|
||||
}, children: _jsx(DeleteOutlined, {}) }), _jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
setOpen(true);
|
||||
getOpen(true);
|
||||
}, children: _jsx(SwapOutlined, {}) })] })] })
|
||||
: null, type === 'text' &&
|
||||
_jsxs("div", { className: Style.editor, children: [_jsx(TextClick, { oakAutoUnmount: true, value: decidedMenuContent, getDecidedMenuContent: getDecidedMenuContent }), _jsx("div", { className: Style.buttonGroup, style: { height: 36, position: 'absolute', right: -50 }, children: _jsx("div", { className: Style.buttonItem, onClick: () => {
|
||||
const modal = confirm({
|
||||
title: '确定删除该文字吗?',
|
||||
content: '删除后不可恢复',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: async (e) => {
|
||||
modal.destroy();
|
||||
setType('news');
|
||||
setDecidedMenuContent(null);
|
||||
if (selectedBtn > 0) {
|
||||
deleteMenuContent(selectedBtn - 1);
|
||||
}
|
||||
else {
|
||||
deleteMenuContent(selectedSubBtn - 1, currentIndex);
|
||||
}
|
||||
},
|
||||
});
|
||||
}, children: _jsx(DeleteOutlined, {}) }) })] })] }), _jsx(Modal, { open: open, footer: _jsxs(Space, { children: [_jsx(Button, { type: 'primary', disabled: !menuContent, onClick: () => {
|
||||
setOpen(false);
|
||||
getOpen(false);
|
||||
setDecidedMenuContent(menuContent);
|
||||
if (selectedBtn > 0) {
|
||||
if (type !== 'news') {
|
||||
if (type === 'image') {
|
||||
setConfig(selectedBtn - 1, { type: 'media_id', media_id: menuContent.media_id, subType: 'image' });
|
||||
}
|
||||
if (type === 'voice') {
|
||||
setConfig(selectedBtn - 1, { type: 'media_id', media_id: menuContent.media_id, subType: 'voice' });
|
||||
}
|
||||
if (type === 'video') {
|
||||
setConfig(selectedBtn - 1, { type: 'media_id', media_id: menuContent.media_id, subType: 'video' });
|
||||
}
|
||||
}
|
||||
else {
|
||||
setConfig(selectedBtn - 1, { type: 'article_id', article_id: menuContent.article_id });
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (type !== 'news') {
|
||||
if (type === 'image') {
|
||||
setConfig(selectedSubBtn - 1, { type: 'media_id', media_id: menuContent.media_id, subType: 'image' }, currentIndex);
|
||||
}
|
||||
if (type === 'voice') {
|
||||
setConfig(selectedSubBtn - 1, { type: 'media_id', media_id: menuContent.media_id, subType: 'voice' }, currentIndex);
|
||||
}
|
||||
if (type === 'video') {
|
||||
setConfig(selectedSubBtn - 1, { type: 'media_id', media_id: menuContent.media_id, subType: 'video' }, currentIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setConfig(selectedSubBtn - 1, { type: 'article_id', article_id: menuContent.article_id }, currentIndex);
|
||||
}
|
||||
}
|
||||
}, children: "\u786E\u5B9A" }), _jsx(Button, { type: 'default', onClick: () => {
|
||||
setOpen(false);
|
||||
getOpen(false);
|
||||
setMenuContent(null);
|
||||
}, children: "\u53D6\u6D88" })] }), onCancel: () => {
|
||||
setOpen(false);
|
||||
getOpen(false);
|
||||
setMenuContent(null);
|
||||
}, destroyOnClose: true, width: 960, children: _jsx(WechatMaterialLibrary, { oakAutoUnmount: true, type: type, getMenuContent: getMenuContent, applicationId: applicationId }) })] })) : msgType === 'view' ? (_jsxs(Form.Item, { colon: false, label: _jsx("div", { className: Style.label, children: "\u7F51\u9875\u94FE\u63A5" }), children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column' }, children: [_jsx(Input, { placeholder: '\u516C\u4F17\u53F7\u94FE\u63A5', style: { width: 340 }, value: url, onChange: (val) => setUrl(val.target.value) }), _jsx("a", { style: { padding: '10px 0' }, onClick: () => { setOpen(true); getOpen(true); }, children: "\u9009\u62E9\u56FE\u6587\u94FE\u63A5" })] }), _jsx(Modal, { open: open, footer: null, title: '选择图文链接', onCancel: () => { setOpen(false); getOpen(false); }, width: 600, children: _jsx(SelectArticle, { oakAutoUnmount: true, changeOpen: changeOpen, getUrl: getUrl, applicationId: applicationId }) })] })) : (_jsxs(Form.Item, { colon: false, label: _jsx("div", { className: Style.label, children: "\u5C0F\u7A0B\u5E8F" }), children: [_jsx(Button, { onClick: () => {
|
||||
setOpen(true);
|
||||
getOpen(true);
|
||||
}, children: "\u9009\u62E9\u5C0F\u7A0B\u5E8F" }), menuContent && menuContent.appid && _jsx("div", { children: menuContent.appid }), _jsx(Modal, { title: '添加小程序', open: open, footer: null, onCancel: () => { setOpen(false); getOpen(false); }, children: _jsx(SelectMiniprogram, { oakAutoUnmount: true, getMenuContent: getMenuContent, changeOpen: changeOpen }) })] }))] })) : (null)] }), _jsx("div", { className: Style.actionBar, children: _jsxs(Space, { children: [_jsxs(Button, { onClick: () => changeIsPreview(true), children: [_jsx(EyeOutlined, {}), "\u9884\u89C8"] }), _jsxs(Button, { type: 'primary', onClick: async () => {
|
||||
createMenu();
|
||||
}, children: [_jsx(CheckOutlined, {}), "\u53D1\u5E03"] }), menuType === 'conditional' && config && menuId && _jsxs(Button, { type: 'primary', danger: true, onClick: () => {
|
||||
const modal = confirm({
|
||||
title: '确定删除该个性化菜单吗?',
|
||||
content: '删除后不可恢复',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
onOk: async (e) => {
|
||||
await deleteConditionalMenu();
|
||||
modal.destroy();
|
||||
},
|
||||
});
|
||||
}, children: [_jsx(DeleteOutlined, {}), "\u5220\u9664"] })] }) })] })) : (_jsxs("div", { className: Style.empty, children: [_jsx("div", { className: Style.content, children: "\u4F60\u672A\u6DFB\u52A0\u81EA\u5B9A\u4E49\u83DC\u5355\uFF0C\u70B9\u51FB\u5DE6\u4FA7\u6DFB\u52A0\u83DC\u5355\u4E3A\u516C\u4F17\u53F7\u521B\u5EFA\u83DC\u5355\u680F\u3002" }), _jsx("div", { className: Style.actionBar, children: _jsxs(Space, { children: [_jsxs(Button, { onClick: () => changeIsPreview(true), children: [_jsx(EyeOutlined, {}), "\u9884\u89C8"] }), _jsxs(Button, { type: 'primary', onClick: async () => {
|
||||
createMenu();
|
||||
}, children: [_jsx(CheckOutlined, {}), "\u53D1\u5E03"] })] }) })] })) }));
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
button: any[];
|
||||
news: any[];
|
||||
applicationId: string;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
export default OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
button: [],
|
||||
news: [],
|
||||
applicationId: '',
|
||||
},
|
||||
data: {},
|
||||
methods: {
|
||||
async getMaterialImgAndVoice(type, media_id) {
|
||||
const { applicationId } = this.props;
|
||||
const imgFile = await this.features.wechatMenu.getMaterial({ applicationId: applicationId, type, media_id });
|
||||
return new Promise((resolve) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(imgFile);
|
||||
reader.onload = function (e) {
|
||||
resolve(e.target?.result);
|
||||
};
|
||||
});
|
||||
},
|
||||
async getArticle(article_id) {
|
||||
const { applicationId } = this.props;
|
||||
const result = await this.features.wechatMenu.getArticle({ applicationId: applicationId, article_id });
|
||||
if (result && result.news_item) {
|
||||
const modifiedResult = await Promise.all(result.news_item.map(async (ele) => {
|
||||
const coverUrl = await this.getMaterialImgAndVoice('image', ele.thumb_media_id);
|
||||
return {
|
||||
...ele,
|
||||
coverUrl
|
||||
};
|
||||
}));
|
||||
return modifiedResult;
|
||||
}
|
||||
},
|
||||
async getMaterialVideo(media_id) {
|
||||
const { applicationId } = this.props;
|
||||
const result = await this.features.wechatMenu.getMaterial({ applicationId: applicationId, type: 'video', media_id });
|
||||
if (result && result.down_url) {
|
||||
return { url: result.down_url, media_id };
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
.container {
|
||||
.phone {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 374px;
|
||||
background: #e0e0e0;
|
||||
border-radius: 8px;
|
||||
|
||||
.topBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
margin: 8px 16px 12px 16px;
|
||||
align-items: center;
|
||||
|
||||
.time {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.actionBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 394px;
|
||||
height: 450px;
|
||||
overflow-y: auto;
|
||||
padding: 10px 0;
|
||||
.img {
|
||||
max-width: 80%;
|
||||
margin-top: 10px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.news {
|
||||
max-width: 80%;
|
||||
margin-top: 10px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
.msg {
|
||||
max-width: 80%;
|
||||
width: max-content;
|
||||
min-height: 30px;
|
||||
margin-left: 20px;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
margin-top: 10px;
|
||||
padding: 4px 10px;
|
||||
position: relative;
|
||||
border-left: 1px solid #fff;
|
||||
.editor {
|
||||
:global {
|
||||
p {
|
||||
margin: 0 !important;
|
||||
}
|
||||
div {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.msg::before {
|
||||
content: ''; /* 伪元素的内容为空 */
|
||||
position: absolute;
|
||||
top: 50%; /* 将箭头垂直居中 */
|
||||
left: -10px; /* 控制箭头的位置 */
|
||||
border: 5px solid transparent; /* 创建一个透明的矩形 */
|
||||
border-right-color: #fff; /* 设置矩形的右侧颜色 */
|
||||
transform: translateY(-50%); /* 调整垂直居中位置 */
|
||||
}
|
||||
}
|
||||
|
||||
.bottomBar {
|
||||
height: 38px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
background: #f0f0f0;
|
||||
.keyBoard {
|
||||
width: 60px;
|
||||
height: 100%;
|
||||
}
|
||||
.buttonList {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
border-left: 1px solid #d0d0d0;
|
||||
padding: 7px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.button:hover {
|
||||
background-color: #d0d0d0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { EntityDict } from "../../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import { WechatPublicInstance } from 'oak-external-sdk';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, {
|
||||
button: any[];
|
||||
wechatInstance: WechatPublicInstance;
|
||||
}, {
|
||||
getMaterialImgAndVoice: (type: 'image' | 'voice', media_id: string) => Promise<string>;
|
||||
getArticle: (article_id: string) => Promise<any[]>;
|
||||
getMaterialVideo: (media_id: string) => {
|
||||
url: string;
|
||||
media_id: string;
|
||||
};
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import { Dropdown } from 'antd';
|
||||
import { WifiOutlined, LeftOutlined, UserOutlined, MenuOutlined } from '@ant-design/icons';
|
||||
import Style from './web.module.less';
|
||||
import { Editor } from '@wangeditor/editor-for-react';
|
||||
import ShowNews from '../showNews';
|
||||
export default function Render(props) {
|
||||
const { button } = props.data;
|
||||
const { getMaterialImgAndVoice, getArticle, getMaterialVideo } = props.methods;
|
||||
const [sendMsg, setSendMsg] = useState([]);
|
||||
const editorConfig = {
|
||||
readOnly: true,
|
||||
autoFocus: true,
|
||||
scroll: false,
|
||||
};
|
||||
const onClick = ({ key }) => {
|
||||
const index = Math.floor(Number(key) / 10);
|
||||
const index2 = Number(key) % 10;
|
||||
menuAction(button[index].sub_button[index2]);
|
||||
};
|
||||
const menuAction = async (menu) => {
|
||||
if (menu.type === 'view' && menu.url) {
|
||||
window.open(menu.url);
|
||||
return;
|
||||
}
|
||||
if (menu.type === 'miniprogram' && menu.url) {
|
||||
setSendMsg([...sendMsg, { type: 'miniprogram', content: '不支持查看小程序,请前往微信公众号平台查看' }]);
|
||||
return;
|
||||
}
|
||||
if (menu.subType === 'text' && menu.content) {
|
||||
setSendMsg([...sendMsg, { type: 'text', content: menu.content }]);
|
||||
return;
|
||||
}
|
||||
if (menu.subType === 'image' && menu.media_id) {
|
||||
setSendMsg([...sendMsg, { type: 'image', content: await getMaterialImgAndVoice('image', menu.media_id) }]);
|
||||
return;
|
||||
}
|
||||
if (menu.type === 'article_id' && menu.article_id) {
|
||||
setSendMsg([...sendMsg, { type: 'article_id', content: await getArticle(menu.article_id) }]);
|
||||
return;
|
||||
}
|
||||
if (menu.subType === 'voice' && menu.media_id) {
|
||||
setSendMsg([...sendMsg, { type: 'voice', content: { url: await getMaterialImgAndVoice('voice', menu.media_id), media_id: menu.media_id } }]);
|
||||
return;
|
||||
}
|
||||
if (menu.subType === 'video' && menu.media_id) {
|
||||
setSendMsg([...sendMsg, { type: 'video', content: { url: await getMaterialVideo(menu.media_id).url, media_id: menu.media_id } }]);
|
||||
return;
|
||||
}
|
||||
};
|
||||
return (_jsx("div", { className: Style.container, children: _jsxs("div", { className: Style.phone, children: [_jsxs("div", { className: Style.topBar, children: [_jsx("div", { className: Style.time, children: "1:21" }), _jsx("div", { className: Style.icons, children: _jsx(WifiOutlined, { style: { fontSize: 14 } }) })] }), _jsxs("div", { className: Style.actionBar, children: [_jsx(LeftOutlined, { style: { fontSize: 20 } }), _jsx(UserOutlined, { style: { fontSize: 20 } })] }), _jsx("div", { className: Style.page, children: (sendMsg && sendMsg.length > 0) &&
|
||||
sendMsg.map((ele) => {
|
||||
if (ele.type === 'text') {
|
||||
return _jsx("div", { className: Style.msg, children: _jsx(Editor, { defaultConfig: editorConfig, value: ele.content, mode: "default", className: Style.editor }) });
|
||||
}
|
||||
else if (ele.type === 'image') {
|
||||
return _jsx("img", { src: ele.content, className: Style.img });
|
||||
}
|
||||
else if (ele.type === 'article_id') {
|
||||
return _jsx("div", { className: Style.news, children: _jsx(ShowNews, { news: ele.content }) });
|
||||
}
|
||||
else if (ele.type === 'voice') {
|
||||
return _jsx("div", { className: Style.msg, children: _jsx("a", { style: { color: '#1677ff' }, href: ele.content.url, download: true, children: ele.content.media_id }) });
|
||||
}
|
||||
else if (ele.type === 'video') {
|
||||
return _jsx("div", { className: Style.msg, children: _jsx("a", { style: { color: '#1677ff' }, href: ele.content.url, download: true, children: ele.content.media_id }) });
|
||||
}
|
||||
else if (ele.type === 'miniprogram') {
|
||||
return _jsx("div", { className: Style.msg, children: ele.content });
|
||||
}
|
||||
}) }), _jsxs("div", { className: Style.bottomBar, children: [_jsx("div", { className: Style.keyBoard }), _jsx("div", { className: Style.buttonList, children: button?.map((ele, index) => {
|
||||
if (ele.sub_button && ele.sub_button.length > 0) {
|
||||
const items = ele.sub_button.map((sub, index2) => {
|
||||
return {
|
||||
label: sub.name,
|
||||
key: `${index * 10 + index2}`,
|
||||
};
|
||||
});
|
||||
return _jsx(Dropdown, { arrow: false, menu: { items, onClick }, placement: 'top', children: _jsxs("div", { className: Style.button, children: [_jsx(MenuOutlined, { style: { fontSize: 12, color: '#d0d0d0' } }), _jsx("div", { className: Style.buttonName, style: { marginLeft: 5 }, children: ele.name })] }) });
|
||||
}
|
||||
else {
|
||||
return _jsx("div", { className: Style.button, onClick: () => {
|
||||
menuAction(ele);
|
||||
}, children: _jsx("div", { className: Style.buttonName, children: ele.name }) });
|
||||
}
|
||||
}) })] })] }) }));
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
getUrl: (url: string) => void;
|
||||
changeOpen: (open: boolean) => void;
|
||||
applicationId: string;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
export default OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
getUrl: (url) => undefined,
|
||||
changeOpen: (open) => undefined,
|
||||
applicationId: '',
|
||||
},
|
||||
lifetimes: {
|
||||
async ready() {
|
||||
const { applicationId } = this.props;
|
||||
if (applicationId) {
|
||||
this.getArticleList(1);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getArticleList(page) {
|
||||
const { applicationId } = this.props;
|
||||
const offset = (page - 1) * 10;
|
||||
const result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId, offset, count: 10, noContent: 0 });
|
||||
const modifiedResult = await Promise.all(result.item.map(async (ele) => {
|
||||
const news_item = await Promise.all(ele.content.news_item.map(async (ele2) => {
|
||||
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
|
||||
return {
|
||||
...ele2,
|
||||
coverUrl
|
||||
};
|
||||
}));
|
||||
return {
|
||||
...ele,
|
||||
content: {
|
||||
...ele.content,
|
||||
news_item
|
||||
}
|
||||
};
|
||||
}));
|
||||
this.setState({
|
||||
materials: modifiedResult,
|
||||
total: result.total_count,
|
||||
});
|
||||
},
|
||||
async getMaterialImg(media_id) {
|
||||
const { applicationId } = this.props;
|
||||
const imgFile = await this.features.wechatMenu.getMaterial({ applicationId: applicationId, type: 'image', media_id });
|
||||
return new Promise((resolve) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(imgFile);
|
||||
reader.onload = function (e) {
|
||||
resolve(e.target?.result);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.upload {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin: 20px 0 0 0;
|
||||
.help {
|
||||
color: #B1B2B3;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.list {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
:global {
|
||||
.ant-select-selector {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
.select {
|
||||
|
||||
.selectItem {
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
line-height: 30px;
|
||||
}
|
||||
.selectItem:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { EntityDict } from "../../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, true, {
|
||||
type: string;
|
||||
materials: any[];
|
||||
total: number;
|
||||
getUrl: (url: string) => void;
|
||||
changeOpen: (open: boolean) => void;
|
||||
}, {
|
||||
getArticleList: (page: number) => void;
|
||||
upload: (media: FormData, description?: FormData) => boolean;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState, useRef } from 'react';
|
||||
import { Button, Table, Space, Input, Popover, Select } from 'antd';
|
||||
const { TextArea } = Input;
|
||||
import Style from './web.module.less';
|
||||
import dayjs from 'dayjs';
|
||||
import ShowNews from '../showNews';
|
||||
export default function Render(props) {
|
||||
const { changeOpen, materials, total, getUrl } = props.data;
|
||||
const { getArticleList, setMessage, upload } = props.methods;
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [url, setUrl] = useState('');
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
const selectRef = useRef(null);
|
||||
const columns = [
|
||||
{
|
||||
dataIndex: 'serial-number',
|
||||
title: '序号',
|
||||
render: (value, record, index) => {
|
||||
return index + 1;
|
||||
},
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
dataIndex: 'url',
|
||||
title: '图文链接',
|
||||
render: (value, record, index) => {
|
||||
if (record.content.news_item.length > 1) {
|
||||
const urlList = record.content.news_item.map((ele) => {
|
||||
return ele.url;
|
||||
});
|
||||
return (_jsx("div", { children: _jsx(Select, { ref: selectRef, style: { width: 160 }, bordered: false, value: urlList.includes(url) ? url : '请选择一篇文章', dropdownRender: () => _jsx("div", { className: Style.select, children: record.content.news_item.map((ele, index) => (_jsx(Popover, { content: _jsx("div", { style: { padding: 12 }, children: _jsx(ShowNews, { oakAutoUnmount: true, news: record.content.news_item.filter((ele, index2) => index === index2) }) }), placement: 'right', children: _jsx("div", { className: Style.selectItem, onClick: () => {
|
||||
selectRef.current.blur();
|
||||
setUrl(ele.url);
|
||||
setSelectedRowKeys([record.article_id]);
|
||||
}, children: ele.url }) }))) }) }) }));
|
||||
}
|
||||
else {
|
||||
return (_jsx("div", { children: _jsx("div", { children: record.content.news_item[0].url }) }));
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'update_time',
|
||||
title: '更新时间',
|
||||
render: (value, record, index) => {
|
||||
return _jsx(_Fragment, { children: dayjs(value).format('YYYY-MM-DD HH:mm') });
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'op',
|
||||
title: '操作',
|
||||
render: (value, record, index) => {
|
||||
return _jsx(Popover, { content: _jsx("div", { style: { padding: 12 }, children: _jsx(ShowNews, { oakAutoUnmount: true, news: record.content.news_item }) }), children: _jsx("div", { style: { cursor: 'pointer', color: '#1677ff' }, children: "\u9884\u89C8" }) });
|
||||
}
|
||||
}
|
||||
];
|
||||
return (_jsxs("div", { className: Style.container, children: [_jsx("div", { className: Style.list, children: _jsx(Table, { dataSource: materials, columns: columns, rowKey: "article_id", pagination: {
|
||||
total: total,
|
||||
pageSize: 10,
|
||||
current: currentPage,
|
||||
onChange: (page, pageSize) => {
|
||||
setCurrentPage(page);
|
||||
getArticleList(page);
|
||||
},
|
||||
}, rowSelection: {
|
||||
type: 'radio',
|
||||
selectedRowKeys: selectedRowKeys,
|
||||
onSelect: (record) => {
|
||||
if (record.content.news_item.length > 1) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
setUrl(record.content.news_item[0].url);
|
||||
}
|
||||
},
|
||||
onChange: (selectedRowKeys) => {
|
||||
setSelectedRowKeys(selectedRowKeys);
|
||||
}
|
||||
} }) }), _jsxs(Space, { style: { display: 'flex', justifyContent: 'center' }, children: [_jsx(Button, { disabled: !url, type: 'primary', onClick: () => {
|
||||
getUrl(url);
|
||||
setUrl('');
|
||||
changeOpen(false);
|
||||
}, children: "\u786E\u5B9A" }), _jsx(Button, { onClick: () => {
|
||||
setUrl('');
|
||||
changeOpen(false);
|
||||
}, children: "\u53D6\u6D88" })] })] }));
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
getMenuContent: (menuContent: any) => void;
|
||||
changeOpen: (open: boolean) => void;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
export default OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
getMenuContent: (menuContent) => undefined,
|
||||
changeOpen: (open) => undefined,
|
||||
},
|
||||
lifetimes: {},
|
||||
methods: {}
|
||||
});
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.container {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import { EntityDict } from "../../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, true, {
|
||||
getMenuContent: (menuContent: any) => void;
|
||||
changeOpen: (open: boolean) => void;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import { Button, Space, Form, Input } from 'antd';
|
||||
import Style from './web.module.less';
|
||||
export default function Render(props) {
|
||||
const { getMenuContent, changeOpen } = props.data;
|
||||
const { setMessage } = props.methods;
|
||||
const [appid, setAppid] = useState('');
|
||||
const [url, setUrl] = useState('');
|
||||
const [pagepath, setPagepath] = useState('');
|
||||
return (_jsxs("div", { className: Style.container, children: [_jsx(Form.Item, { required: true, label: 'appid', labelAlign: 'right', labelCol: { span: 6 }, children: _jsx(Input, { placeholder: '\u5C0F\u7A0B\u5E8F\u7684appid', onChange: (val) => {
|
||||
setAppid(val.target.value);
|
||||
}, value: appid }) }), _jsx(Form.Item, { required: true, label: 'url', labelAlign: 'right', labelCol: { span: 6 }, children: _jsx(Input, { placeholder: '\u5C0F\u7A0B\u5E8F\u7684\u7F51\u9875\u94FE\u63A5', onChange: (val) => {
|
||||
setUrl(val.target.value);
|
||||
}, value: url }) }), _jsx(Form.Item, { required: true, label: 'pagepath', labelAlign: 'right', labelCol: { span: 6 }, children: _jsx(Input, { placeholder: '\u5C0F\u7A0B\u5E8F\u7684\u9875\u9762\u8DEF\u5F84', onChange: (val) => {
|
||||
setPagepath(val.target.value);
|
||||
}, value: pagepath }) }), _jsxs(Space, { style: { display: 'flex', justifyContent: 'center' }, children: [_jsx(Button, { type: 'primary', onClick: () => {
|
||||
if (!appid) {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: '请输入小程序appid'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!url) {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: '请输入小程序网页链接'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!pagepath) {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: '请输入小程序页面路径'
|
||||
});
|
||||
return;
|
||||
}
|
||||
getMenuContent({ appid, url, pagepath });
|
||||
setAppid('');
|
||||
setPagepath('');
|
||||
setUrl('');
|
||||
changeOpen(false);
|
||||
}, children: "\u786E\u5B9A" }), _jsx(Button, { onClick: () => {
|
||||
changeOpen(false);
|
||||
}, children: "\u53D6\u6D88" })] })] }));
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
news: any[];
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
export default OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
news: [],
|
||||
},
|
||||
data: {},
|
||||
methods: {}
|
||||
});
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
|
||||
.container {
|
||||
width: 310px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border: 1px solid #dbdbdb;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
.multiNews {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.cover {
|
||||
width: 308px;
|
||||
height: 130px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
position: relative;
|
||||
.img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.articleTitle {
|
||||
// color: #fff;
|
||||
padding: 0 12px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
}
|
||||
}
|
||||
.newsItem {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 12px;
|
||||
align-items: center;
|
||||
.articleTitle {
|
||||
width: 220px;
|
||||
font-size: 14px;
|
||||
color: #353535;
|
||||
line-height: 48px;
|
||||
border-bottom: 1px solid #dbdbdb;
|
||||
font-weight: 500;
|
||||
}
|
||||
.imgCover {
|
||||
object-fit: cover;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.newsItem:last-child {
|
||||
.articleTitle {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.singleNews {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.cover {
|
||||
width: 308px;
|
||||
height: 130px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
.img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.articleTitle {
|
||||
padding: 12px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: #353535;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { EntityDict } from "../../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, {
|
||||
news: any[];
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import Style from './web.module.less';
|
||||
export default function Render(props) {
|
||||
const { news } = props.data;
|
||||
return (_jsx("div", { className: Style.container, children: news && news.length > 1 ?
|
||||
_jsx("div", { className: Style.multiNews, children: news.map((ele, index) => {
|
||||
if (index === 0) {
|
||||
return (_jsxs("div", { className: Style.cover, children: [_jsx("img", { className: Style.img, src: ele.coverUrl }), _jsx("div", { className: Style.articleTitle, children: ele.title })] }));
|
||||
}
|
||||
else {
|
||||
return (_jsxs("div", { className: Style.newsItem, children: [_jsx("div", { className: Style.articleTitle, children: ele.title }), _jsx("div", { className: Style.imgCover, children: _jsx("img", { className: Style.img, src: ele.coverUrl }) })] }));
|
||||
}
|
||||
}) })
|
||||
:
|
||||
_jsxs("div", { className: Style.singleNews, children: [_jsx("div", { className: Style.cover, children: _jsx("img", { className: Style.img, src: news?.[0]?.coverUrl }) }), _jsx("div", { className: Style.articleTitle, children: news?.[0]?.title })] }) }));
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "wechatPublicTag", true, {
|
||||
news: any[];
|
||||
applicationId: string;
|
||||
getTag: (data: {
|
||||
id: string;
|
||||
name: string;
|
||||
}) => void;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
export default OakComponent({
|
||||
isList: true,
|
||||
entity: 'wechatPublicTag',
|
||||
projection: {
|
||||
id: 1,
|
||||
applicationId: 1,
|
||||
text: 1,
|
||||
wechatId: 1,
|
||||
},
|
||||
formData({ data: rows }) {
|
||||
return {
|
||||
rows,
|
||||
};
|
||||
},
|
||||
pagination: {
|
||||
pageSize: 20,
|
||||
currentPage: 1,
|
||||
more: false,
|
||||
},
|
||||
lifetimes: {},
|
||||
filters: [
|
||||
{
|
||||
filter() {
|
||||
const { applicationId } = this.props;
|
||||
return {
|
||||
applicationId
|
||||
};
|
||||
},
|
||||
}
|
||||
],
|
||||
properties: {
|
||||
news: [],
|
||||
applicationId: '',
|
||||
getTag: (data) => undefined,
|
||||
},
|
||||
data: {},
|
||||
methods: {}
|
||||
});
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { EntityDict } from "../../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
export default function Render(props: WebComponentProps<EntityDict, 'wechatPublicTag', true, {
|
||||
rows: EntityDict['wechatPublicTag']['Schema'][];
|
||||
getTag: (data: {
|
||||
id: string;
|
||||
name: string;
|
||||
}) => void;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import { jsx as _jsx } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import { Table } from 'antd';
|
||||
import Style from './web.module.less';
|
||||
export default function Render(props) {
|
||||
const { rows, oakLoading, getTag } = props.data;
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
||||
return (_jsx("div", { className: Style.container, children: _jsx(Table, { loading: oakLoading, dataSource: rows || [], rowKey: "id", columns: [
|
||||
{
|
||||
dataIndex: 'text',
|
||||
title: '标签名',
|
||||
},
|
||||
], rowSelection: {
|
||||
type: 'radio',
|
||||
onSelect: (record) => {
|
||||
getTag({ id: `${record.wechatId}`, name: record.text });
|
||||
},
|
||||
selectedRowKeys: selectedRowKeys,
|
||||
onChange: (selectedRowKeys) => {
|
||||
setSelectedRowKeys(selectedRowKeys);
|
||||
}
|
||||
}, onRow: (record) => {
|
||||
return {
|
||||
onClick: () => {
|
||||
setSelectedRowKeys([record.id]);
|
||||
getTag({ id: `${record.wechatId}`, name: record.text });
|
||||
}
|
||||
};
|
||||
}, pagination: false }) }));
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
value: string;
|
||||
getDecidedMenuContent: (menuContent: any) => void;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
export default OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
value: '',
|
||||
getDecidedMenuContent: (menuContent) => undefined,
|
||||
},
|
||||
data: {
|
||||
editor: null,
|
||||
},
|
||||
lifetimes: {
|
||||
detached() {
|
||||
const { editor } = this.state;
|
||||
if (editor == null)
|
||||
return;
|
||||
editor.destroy();
|
||||
this.setEditor(null);
|
||||
},
|
||||
},
|
||||
listeners: {
|
||||
'editor,value'(prev, next) {
|
||||
if (prev.editor !== next.editor ||
|
||||
prev.value !== next.value) {
|
||||
if (next.editor && next.value) {
|
||||
next.editor.setHtml(next.value);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setEditor(editor) {
|
||||
this.setState({
|
||||
editor,
|
||||
});
|
||||
},
|
||||
async setHtml(html) {
|
||||
this.setState({
|
||||
html,
|
||||
});
|
||||
if (html && html !== '<p><br></p>') {
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.container {
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { EntityDict } from "../../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import "@wangeditor/editor/dist/css/style.css";
|
||||
import { IDomEditor } from '@wangeditor/editor';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, {
|
||||
value: string;
|
||||
editor: IDomEditor;
|
||||
getDecidedMenuContent: (menuContent: any) => void;
|
||||
}, {
|
||||
setEditor: (editor: IDomEditor | null) => void;
|
||||
setHtml: (html: string) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import Style from './web.module.less';
|
||||
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
|
||||
import { Editor, Toolbar } from "@wangeditor/editor-for-react";
|
||||
const toolbarConfig = {
|
||||
excludeKeys: [
|
||||
"blockquote",
|
||||
"fullScreen",
|
||||
"headerSelect",
|
||||
"|",
|
||||
"bold",
|
||||
"group-more-style",
|
||||
"bgColor",
|
||||
"bulletedList",
|
||||
"numberedList",
|
||||
"todo",
|
||||
"group-image",
|
||||
"group-video",
|
||||
"insertTable",
|
||||
"codeBlock",
|
||||
],
|
||||
}; // TS 语法
|
||||
export default function Render(props) {
|
||||
const { value, editor, getDecidedMenuContent } = props.data;
|
||||
const { setEditor, setHtml } = props.methods;
|
||||
return (_jsxs("div", { className: Style.container, children: [_jsx(Toolbar, { editor: editor, defaultConfig: toolbarConfig, mode: "default", style: {
|
||||
borderBottom: '1px solid #ccc',
|
||||
} }), _jsx(Editor, { defaultConfig: {
|
||||
placeholder: '请输入内容...',
|
||||
}, value: value, onCreated: setEditor, onChange: (editorDom) => {
|
||||
const html = editorDom.getHtml();
|
||||
if (html && html !== '<p><br></p>') {
|
||||
getDecidedMenuContent(html);
|
||||
}
|
||||
}, mode: "default", style: {
|
||||
minHeight: 200,
|
||||
maxHeight: 400,
|
||||
overflowY: 'auto',
|
||||
} })] }));
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
.container {
|
||||
width: 100%;
|
||||
background: var(--oak-bg-color-container);
|
||||
padding: 10px;
|
||||
.warn {
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs {
|
||||
background: #F5F5F5;
|
||||
padding: 10px;
|
||||
|
||||
.conditionalMenu {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.tagList {
|
||||
width: 20%;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.tagHelp {
|
||||
background: var(--oak-bg-color-container);
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../../oak-app-domain';
|
||||
export default function Render(props: WebComponentProps<EntityDict, 'wechatMenu', true, {
|
||||
is_menu_open: boolean;
|
||||
applicationId: string;
|
||||
menuId: string;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element | null;
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState } from 'react';
|
||||
import WechatMenu from './menu';
|
||||
import ConditionalMenu from './conditionalMenu';
|
||||
import Style from './web.module.less';
|
||||
import { Tabs } from 'antd';
|
||||
import TagList from './tagList';
|
||||
export default function Render(props) {
|
||||
const { menuId, oakFullpath, is_menu_open, applicationId } = props.data;
|
||||
const {} = props.methods;
|
||||
const [menuType, setMenuType] = useState('common');
|
||||
const [tag, setTag] = useState({});
|
||||
const getTag = (tag) => {
|
||||
setTag(tag);
|
||||
};
|
||||
const items = [
|
||||
{
|
||||
key: '1',
|
||||
label: '通用菜单',
|
||||
children: _jsx(WechatMenu, { menuId: menuId ? menuId : undefined, oakPath: '$wechatMenu', applicationId: applicationId, oakAutoUnmount: true, menuType: menuType }),
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: '个性化菜单',
|
||||
children: _jsxs("div", { className: Style.conditionalMenu, children: [_jsx("div", { className: Style.tagList, children: _jsx(TagList, { oakAutoUnmount: true, oakPath: '$wechatPublicTag', applicationId: applicationId, getTag: getTag }) }), tag.id ? (_jsx(ConditionalMenu, { oakPath: '$conditionalMenu', applicationId: applicationId, oakAutoUnmount: true, tagId: tag.id, menuType: menuType })) : (_jsx("div", { className: Style.tagHelp, children: "\u8BF7\u9009\u62E9\u4E00\u4E2A\u6807\u7B7E" }))] }),
|
||||
},
|
||||
];
|
||||
if (oakFullpath) {
|
||||
return (_jsx("div", { children: is_menu_open ? (_jsx("div", { className: Style.tabs, children: _jsx(Tabs, { defaultActiveKey: '1', items: items, onChange: (key) => {
|
||||
if (key === '1') {
|
||||
setMenuType('common');
|
||||
}
|
||||
else {
|
||||
setMenuType('conditional');
|
||||
}
|
||||
} }) })) : (_jsx("div", { className: Style.container, children: _jsx("div", { className: Style.warn, children: "\u5C1A\u672A\u5F00\u542F\u83DC\u5355\uFF0C\u8BF7\u5148\u524D\u5F80\u5FAE\u4FE1\u516C\u4F17\u5E73\u53F0\u5F00\u542F\u3002" }) })) }));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { Int } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { Schema as Application } from './Application';
|
||||
import { Schema as WechatPublicTag } from './WechatPublicTag';
|
||||
type Config = {
|
||||
button: any[];
|
||||
matchrule?: {
|
||||
tag_id?: string;
|
||||
};
|
||||
};
|
||||
export interface Schema extends EntityShape {
|
||||
menuId?: Int<4>;
|
||||
menuConfig: Config;
|
||||
application: Application;
|
||||
publishState: 'wait' | 'success' | 'fail';
|
||||
wechatPublicTag?: WechatPublicTag;
|
||||
}
|
||||
export {};
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
;
|
||||
const entityDesc = {
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '微信菜单',
|
||||
attr: {
|
||||
menuId: '菜单Id',
|
||||
menuConfig: '菜单配置',
|
||||
application: '应用',
|
||||
publishState: '发布状态',
|
||||
wechatPublicTag: '标签',
|
||||
},
|
||||
v: {
|
||||
publishState: {
|
||||
wait: '等待发布',
|
||||
success: '发布成功',
|
||||
fail: '发布失败',
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
export {};
|
||||
|
|
@ -5,6 +5,7 @@ import { ExtraFile2 } from './extraFile2';
|
|||
import { Application } from './application';
|
||||
import { Config } from './config';
|
||||
import { WeiXinJsSdk } from './weiXinJsSdk';
|
||||
import { WechatMenu } from './wechatMenu';
|
||||
import { BasicFeatures } from 'oak-frontend-base';
|
||||
import AspectDict from '../aspects/AspectDict';
|
||||
import { AppType } from '../oak-app-domain/Application/Schema';
|
||||
|
|
@ -21,4 +22,5 @@ export type GeneralFeatures<ED extends EntityDict, Cxt extends BackendRuntimeCon
|
|||
config: Config<ED, Cxt, FrontCxt, AD>;
|
||||
weiXinJsSdk: WeiXinJsSdk<ED, Cxt, FrontCxt, AD>;
|
||||
theme: Theme<ED, Cxt, FrontCxt, AD>;
|
||||
wechatMenu: WechatMenu<ED, Cxt, FrontCxt, AD>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@ import { ExtraFile2 } from './extraFile2';
|
|||
import { Application } from './application';
|
||||
import { Config } from './config';
|
||||
import { WeiXinJsSdk } from './weiXinJsSdk';
|
||||
import { WechatMenu } from './wechatMenu';
|
||||
import Theme from './theme';
|
||||
export function initialize(basicFeatures, type, domain) {
|
||||
const application = new Application(type, domain, basicFeatures.cache, basicFeatures.localStorage);
|
||||
const token = new Token(basicFeatures.cache, basicFeatures.localStorage, basicFeatures.environment);
|
||||
const wechatMenu = new WechatMenu(basicFeatures.cache, basicFeatures.localStorage);
|
||||
// 临时代码,合并后再删
|
||||
const extraFile = new ExtraFile(basicFeatures.cache, application, basicFeatures.locales);
|
||||
const extraFile2 = new ExtraFile2(basicFeatures.cache, application, basicFeatures.locales);
|
||||
|
|
@ -22,5 +24,6 @@ export function initialize(basicFeatures, type, domain) {
|
|||
config,
|
||||
weiXinJsSdk,
|
||||
theme,
|
||||
wechatMenu
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
import { Feature } from 'oak-frontend-base';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import AspectDict from '../aspects/AspectDict';
|
||||
import { BackendRuntimeContext } from '../context/BackendRuntimeContext';
|
||||
import { FrontendRuntimeContext } from '../context/FrontendRuntimeContext';
|
||||
import { Cache } from 'oak-frontend-base/es/features/cache';
|
||||
import { LocalStorage } from 'oak-frontend-base/es/features/localStorage';
|
||||
export declare class WechatMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>, FrontCxt extends FrontendRuntimeContext<ED, Cxt, AD>, AD extends AspectDict<ED, Cxt> & CommonAspectDict<ED, Cxt>> extends Feature {
|
||||
private cache;
|
||||
private storage;
|
||||
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, storage: LocalStorage);
|
||||
getCurrentMenu(params: {
|
||||
applicationId: string;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["getCurrentMenu"]>>;
|
||||
getMenu(params: {
|
||||
applicationId: string;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["getMenu"]>>;
|
||||
createMenu(params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["createMenu"]>>;
|
||||
createConditionalMenu(params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["createConditionalMenu"]>>;
|
||||
deleteConditionalMenu(params: {
|
||||
applicationId: string;
|
||||
menuid: number;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["deleteConditionalMenu"]>>;
|
||||
batchGetArticle(params: {
|
||||
applicationId: string;
|
||||
offset?: number;
|
||||
count: number;
|
||||
noContent?: 0 | 1;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["batchGetArticle"]>>;
|
||||
getArticle(params: {
|
||||
applicationId: string;
|
||||
article_id: string;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["getArticle"]>>;
|
||||
createMaterial(params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'voice' | 'video' | 'thumb';
|
||||
media: FormData;
|
||||
description?: FormData;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["createMaterial"]>>;
|
||||
batchGetMaterialList(params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
offset?: number;
|
||||
count: number;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["batchGetMaterialList"]>>;
|
||||
getMaterial(params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
media_id: string;
|
||||
}): Promise<ReturnType<(AD & CommonAspectDict<ED, Cxt>)["getMaterial"]>>;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import { Feature } from 'oak-frontend-base';
|
||||
export class WechatMenu extends Feature {
|
||||
cache;
|
||||
storage;
|
||||
constructor(cache, storage) {
|
||||
super();
|
||||
this.cache = cache;
|
||||
this.storage = storage;
|
||||
}
|
||||
async getCurrentMenu(params) {
|
||||
const callBack = await this.cache.exec('getCurrentMenu', params);
|
||||
return callBack.result;
|
||||
}
|
||||
async getMenu(params) {
|
||||
const callBack = await this.cache.exec('getMenu', params);
|
||||
return callBack.result;
|
||||
}
|
||||
async createMenu(params) {
|
||||
const callBack = await this.cache.exec('createMenu', params);
|
||||
return callBack.result;
|
||||
}
|
||||
async createConditionalMenu(params) {
|
||||
const callBack = await this.cache.exec('createConditionalMenu', params);
|
||||
return callBack.result;
|
||||
}
|
||||
async deleteConditionalMenu(params) {
|
||||
const callBack = await this.cache.exec('deleteConditionalMenu', params);
|
||||
return callBack.result;
|
||||
}
|
||||
async batchGetArticle(params) {
|
||||
const callBack = await this.cache.exec('batchGetArticle', params);
|
||||
return callBack.result;
|
||||
}
|
||||
async getArticle(params) {
|
||||
const callBack = await this.cache.exec('getArticle', params);
|
||||
return callBack.result;
|
||||
}
|
||||
async createMaterial(params) {
|
||||
const callBack = await this.cache.exec('createMaterial', params);
|
||||
return callBack.result;
|
||||
}
|
||||
async batchGetMaterialList(params) {
|
||||
const callBack = await this.cache.exec('batchGetMaterialList', params);
|
||||
return callBack.result;
|
||||
}
|
||||
async getMaterial(params) {
|
||||
const callBack = await this.cache.exec('getMaterial', params);
|
||||
return callBack.result;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import * as MessageTypeTemplateId from "../MessageTypeTemplateId/Schema";
|
|||
import * as Notification from "../Notification/Schema";
|
||||
import * as SessionMessage from "../SessionMessage/Schema";
|
||||
import * as Token from "../Token/Schema";
|
||||
import * as WechatMenu from "../WechatMenu/Schema";
|
||||
import * as WechatPublicTag from "../WechatPublicTag/Schema";
|
||||
import * as WechatQrCode from "../WechatQrCode/Schema";
|
||||
import * as WechatUser from "../WechatUser/Schema";
|
||||
|
|
@ -88,6 +89,8 @@ export type Schema = EntityShape & {
|
|||
sessionMessage$application$$aggr?: AggregationResult<SessionMessage.Schema>;
|
||||
token$application?: Array<Token.Schema>;
|
||||
token$application$$aggr?: AggregationResult<Token.Schema>;
|
||||
wechatMenu$application?: Array<WechatMenu.Schema>;
|
||||
wechatMenu$application$$aggr?: AggregationResult<WechatMenu.Schema>;
|
||||
wechatPublicTag$application?: Array<WechatPublicTag.Schema>;
|
||||
wechatPublicTag$application$$aggr?: AggregationResult<WechatPublicTag.Schema>;
|
||||
wechatQrCode$application?: Array<WechatQrCode.Schema>;
|
||||
|
|
@ -115,6 +118,7 @@ type AttrFilter = {
|
|||
notification$application: Notification.Filter & SubQueryPredicateMetadata;
|
||||
sessionMessage$application: SessionMessage.Filter & SubQueryPredicateMetadata;
|
||||
token$application: Token.Filter & SubQueryPredicateMetadata;
|
||||
wechatMenu$application: WechatMenu.Filter & SubQueryPredicateMetadata;
|
||||
wechatPublicTag$application: WechatPublicTag.Filter & SubQueryPredicateMetadata;
|
||||
wechatQrCode$application: WechatQrCode.Filter & SubQueryPredicateMetadata;
|
||||
wechatUser$application: WechatUser.Filter & SubQueryPredicateMetadata;
|
||||
|
|
@ -159,6 +163,12 @@ export type Projection = {
|
|||
token$application$$aggr?: Token.Aggregation & {
|
||||
$entity: "token";
|
||||
};
|
||||
wechatMenu$application?: WechatMenu.Selection & {
|
||||
$entity: "wechatMenu";
|
||||
};
|
||||
wechatMenu$application$$aggr?: WechatMenu.Aggregation & {
|
||||
$entity: "wechatMenu";
|
||||
};
|
||||
wechatPublicTag$application?: WechatPublicTag.Selection & {
|
||||
$entity: "wechatPublicTag";
|
||||
};
|
||||
|
|
@ -234,6 +244,7 @@ export type CreateOperationData = FormCreateData<Omit<OpSchema, "systemId">> & (
|
|||
notification$application?: OakOperation<Notification.UpdateOperation["action"], Omit<Notification.UpdateOperationData, "application" | "applicationId">, Omit<Notification.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<Notification.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<Notification.CreateOperationData, "application" | "applicationId">> | OakOperation<Notification.UpdateOperation["action"], Omit<Notification.UpdateOperationData, "application" | "applicationId">, Omit<Notification.Filter, "application" | "applicationId">>>;
|
||||
sessionMessage$application?: OakOperation<SessionMessage.UpdateOperation["action"], Omit<SessionMessage.UpdateOperationData, "application" | "applicationId">, Omit<SessionMessage.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<SessionMessage.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<SessionMessage.CreateOperationData, "application" | "applicationId">> | OakOperation<SessionMessage.UpdateOperation["action"], Omit<SessionMessage.UpdateOperationData, "application" | "applicationId">, Omit<SessionMessage.Filter, "application" | "applicationId">>>;
|
||||
token$application?: OakOperation<Token.UpdateOperation["action"], Omit<Token.UpdateOperationData, "application" | "applicationId">, Omit<Token.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<Token.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<Token.CreateOperationData, "application" | "applicationId">> | OakOperation<Token.UpdateOperation["action"], Omit<Token.UpdateOperationData, "application" | "applicationId">, Omit<Token.Filter, "application" | "applicationId">>>;
|
||||
wechatMenu$application?: OakOperation<WechatMenu.UpdateOperation["action"], Omit<WechatMenu.UpdateOperationData, "application" | "applicationId">, Omit<WechatMenu.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<WechatMenu.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<WechatMenu.CreateOperationData, "application" | "applicationId">> | OakOperation<WechatMenu.UpdateOperation["action"], Omit<WechatMenu.UpdateOperationData, "application" | "applicationId">, Omit<WechatMenu.Filter, "application" | "applicationId">>>;
|
||||
wechatPublicTag$application?: OakOperation<WechatPublicTag.UpdateOperation["action"], Omit<WechatPublicTag.UpdateOperationData, "application" | "applicationId">, Omit<WechatPublicTag.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<WechatPublicTag.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<WechatPublicTag.CreateOperationData, "application" | "applicationId">> | OakOperation<WechatPublicTag.UpdateOperation["action"], Omit<WechatPublicTag.UpdateOperationData, "application" | "applicationId">, Omit<WechatPublicTag.Filter, "application" | "applicationId">>>;
|
||||
wechatQrCode$application?: OakOperation<WechatQrCode.UpdateOperation["action"], Omit<WechatQrCode.UpdateOperationData, "application" | "applicationId">, Omit<WechatQrCode.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<WechatQrCode.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<WechatQrCode.CreateOperationData, "application" | "applicationId">> | OakOperation<WechatQrCode.UpdateOperation["action"], Omit<WechatQrCode.UpdateOperationData, "application" | "applicationId">, Omit<WechatQrCode.Filter, "application" | "applicationId">>>;
|
||||
wechatUser$application?: OakOperation<WechatUser.UpdateOperation["action"], Omit<WechatUser.UpdateOperationData, "application" | "applicationId">, Omit<WechatUser.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<WechatUser.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<WechatUser.CreateOperationData, "application" | "applicationId">> | OakOperation<WechatUser.UpdateOperation["action"], Omit<WechatUser.UpdateOperationData, "application" | "applicationId">, Omit<WechatUser.Filter, "application" | "applicationId">>>;
|
||||
|
|
@ -260,6 +271,7 @@ export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "systemId">> & (
|
|||
notification$application?: OakOperation<Notification.UpdateOperation["action"], Omit<Notification.UpdateOperationData, "application" | "applicationId">, Omit<Notification.Filter, "application" | "applicationId">> | OakOperation<Notification.RemoveOperation["action"], Omit<Notification.RemoveOperationData, "application" | "applicationId">, Omit<Notification.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<Notification.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<Notification.CreateOperationData, "application" | "applicationId">> | OakOperation<Notification.UpdateOperation["action"], Omit<Notification.UpdateOperationData, "application" | "applicationId">, Omit<Notification.Filter, "application" | "applicationId">> | OakOperation<Notification.RemoveOperation["action"], Omit<Notification.RemoveOperationData, "application" | "applicationId">, Omit<Notification.Filter, "application" | "applicationId">>>;
|
||||
sessionMessage$application?: OakOperation<SessionMessage.UpdateOperation["action"], Omit<SessionMessage.UpdateOperationData, "application" | "applicationId">, Omit<SessionMessage.Filter, "application" | "applicationId">> | OakOperation<SessionMessage.RemoveOperation["action"], Omit<SessionMessage.RemoveOperationData, "application" | "applicationId">, Omit<SessionMessage.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<SessionMessage.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<SessionMessage.CreateOperationData, "application" | "applicationId">> | OakOperation<SessionMessage.UpdateOperation["action"], Omit<SessionMessage.UpdateOperationData, "application" | "applicationId">, Omit<SessionMessage.Filter, "application" | "applicationId">> | OakOperation<SessionMessage.RemoveOperation["action"], Omit<SessionMessage.RemoveOperationData, "application" | "applicationId">, Omit<SessionMessage.Filter, "application" | "applicationId">>>;
|
||||
token$application?: OakOperation<Token.UpdateOperation["action"], Omit<Token.UpdateOperationData, "application" | "applicationId">, Omit<Token.Filter, "application" | "applicationId">> | OakOperation<Token.RemoveOperation["action"], Omit<Token.RemoveOperationData, "application" | "applicationId">, Omit<Token.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<Token.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<Token.CreateOperationData, "application" | "applicationId">> | OakOperation<Token.UpdateOperation["action"], Omit<Token.UpdateOperationData, "application" | "applicationId">, Omit<Token.Filter, "application" | "applicationId">> | OakOperation<Token.RemoveOperation["action"], Omit<Token.RemoveOperationData, "application" | "applicationId">, Omit<Token.Filter, "application" | "applicationId">>>;
|
||||
wechatMenu$application?: OakOperation<WechatMenu.UpdateOperation["action"], Omit<WechatMenu.UpdateOperationData, "application" | "applicationId">, Omit<WechatMenu.Filter, "application" | "applicationId">> | OakOperation<WechatMenu.RemoveOperation["action"], Omit<WechatMenu.RemoveOperationData, "application" | "applicationId">, Omit<WechatMenu.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<WechatMenu.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<WechatMenu.CreateOperationData, "application" | "applicationId">> | OakOperation<WechatMenu.UpdateOperation["action"], Omit<WechatMenu.UpdateOperationData, "application" | "applicationId">, Omit<WechatMenu.Filter, "application" | "applicationId">> | OakOperation<WechatMenu.RemoveOperation["action"], Omit<WechatMenu.RemoveOperationData, "application" | "applicationId">, Omit<WechatMenu.Filter, "application" | "applicationId">>>;
|
||||
wechatPublicTag$application?: OakOperation<WechatPublicTag.UpdateOperation["action"], Omit<WechatPublicTag.UpdateOperationData, "application" | "applicationId">, Omit<WechatPublicTag.Filter, "application" | "applicationId">> | OakOperation<WechatPublicTag.RemoveOperation["action"], Omit<WechatPublicTag.RemoveOperationData, "application" | "applicationId">, Omit<WechatPublicTag.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<WechatPublicTag.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<WechatPublicTag.CreateOperationData, "application" | "applicationId">> | OakOperation<WechatPublicTag.UpdateOperation["action"], Omit<WechatPublicTag.UpdateOperationData, "application" | "applicationId">, Omit<WechatPublicTag.Filter, "application" | "applicationId">> | OakOperation<WechatPublicTag.RemoveOperation["action"], Omit<WechatPublicTag.RemoveOperationData, "application" | "applicationId">, Omit<WechatPublicTag.Filter, "application" | "applicationId">>>;
|
||||
wechatQrCode$application?: OakOperation<WechatQrCode.UpdateOperation["action"], Omit<WechatQrCode.UpdateOperationData, "application" | "applicationId">, Omit<WechatQrCode.Filter, "application" | "applicationId">> | OakOperation<WechatQrCode.RemoveOperation["action"], Omit<WechatQrCode.RemoveOperationData, "application" | "applicationId">, Omit<WechatQrCode.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<WechatQrCode.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<WechatQrCode.CreateOperationData, "application" | "applicationId">> | OakOperation<WechatQrCode.UpdateOperation["action"], Omit<WechatQrCode.UpdateOperationData, "application" | "applicationId">, Omit<WechatQrCode.Filter, "application" | "applicationId">> | OakOperation<WechatQrCode.RemoveOperation["action"], Omit<WechatQrCode.RemoveOperationData, "application" | "applicationId">, Omit<WechatQrCode.Filter, "application" | "applicationId">>>;
|
||||
wechatUser$application?: OakOperation<WechatUser.UpdateOperation["action"], Omit<WechatUser.UpdateOperationData, "application" | "applicationId">, Omit<WechatUser.Filter, "application" | "applicationId">> | OakOperation<WechatUser.RemoveOperation["action"], Omit<WechatUser.RemoveOperationData, "application" | "applicationId">, Omit<WechatUser.Filter, "application" | "applicationId">> | OakOperation<"create", Omit<WechatUser.CreateOperationData, "application" | "applicationId">[]> | Array<OakOperation<"create", Omit<WechatUser.CreateOperationData, "application" | "applicationId">> | OakOperation<WechatUser.UpdateOperation["action"], Omit<WechatUser.UpdateOperationData, "application" | "applicationId">, Omit<WechatUser.Filter, "application" | "applicationId">> | OakOperation<WechatUser.RemoveOperation["action"], Omit<WechatUser.RemoveOperationData, "application" | "applicationId">, Omit<WechatUser.Filter, "application" | "applicationId">>>;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import { EntityDef as Token } from "./Token/Schema";
|
|||
import { EntityDef as UserSystem } from "./UserSystem/Schema";
|
||||
import { EntityDef as UserWechatPublicTag } from "./UserWechatPublicTag/Schema";
|
||||
import { EntityDef as WechatLogin } from "./WechatLogin/Schema";
|
||||
import { EntityDef as WechatMenu } from "./WechatMenu/Schema";
|
||||
import { EntityDef as WechatPublicTag } from "./WechatPublicTag/Schema";
|
||||
import { EntityDef as WechatQrCode } from "./WechatQrCode/Schema";
|
||||
import { EntityDef as WechatUser } from "./WechatUser/Schema";
|
||||
|
|
@ -84,6 +85,7 @@ export type EntityDict = {
|
|||
userSystem: UserSystem;
|
||||
userWechatPublicTag: UserWechatPublicTag;
|
||||
wechatLogin: WechatLogin;
|
||||
wechatMenu: WechatMenu;
|
||||
wechatPublicTag: WechatPublicTag;
|
||||
wechatQrCode: WechatQrCode;
|
||||
wechatUser: WechatUser;
|
||||
|
|
|
|||
|
|
@ -11,18 +11,19 @@ import * as UserEntityGrant from "../UserEntityGrant/Schema";
|
|||
import * as UserSystem from "../UserSystem/Schema";
|
||||
import * as UserWechatPublicTag from "../UserWechatPublicTag/Schema";
|
||||
import * as WechatLogin from "../WechatLogin/Schema";
|
||||
import * as WechatMenu from "../WechatMenu/Schema";
|
||||
import * as WechatPublicTag from "../WechatPublicTag/Schema";
|
||||
import * as WechatQrCode from "../WechatQrCode/Schema";
|
||||
import * as WechatUser from "../WechatUser/Schema";
|
||||
export type OpSchema = EntityShape & {
|
||||
modiId: ForeignKey<"modi">;
|
||||
entity: "user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string;
|
||||
entity: "user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatMenu" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string;
|
||||
entityId: String<64>;
|
||||
};
|
||||
export type OpAttr = keyof OpSchema;
|
||||
export type Schema = EntityShape & {
|
||||
modiId: ForeignKey<"modi">;
|
||||
entity: "user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string;
|
||||
entity: "user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatMenu" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string;
|
||||
entityId: String<64>;
|
||||
modi: Modi.Schema;
|
||||
user?: User.Schema;
|
||||
|
|
@ -30,6 +31,7 @@ export type Schema = EntityShape & {
|
|||
userSystem?: UserSystem.Schema;
|
||||
userWechatPublicTag?: UserWechatPublicTag.Schema;
|
||||
wechatLogin?: WechatLogin.Schema;
|
||||
wechatMenu?: WechatMenu.Schema;
|
||||
wechatPublicTag?: WechatPublicTag.Schema;
|
||||
wechatQrCode?: WechatQrCode.Schema;
|
||||
wechatUser?: WechatUser.Schema;
|
||||
|
|
@ -43,13 +45,14 @@ type AttrFilter = {
|
|||
$$updateAt$$: Q_DateValue;
|
||||
modiId: Q_StringValue;
|
||||
modi: Modi.Filter;
|
||||
entity: Q_EnumValue<"user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string>;
|
||||
entity: Q_EnumValue<"user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatMenu" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string>;
|
||||
entityId: Q_StringValue;
|
||||
user: User.Filter;
|
||||
userEntityGrant: UserEntityGrant.Filter;
|
||||
userSystem: UserSystem.Filter;
|
||||
userWechatPublicTag: UserWechatPublicTag.Filter;
|
||||
wechatLogin: WechatLogin.Filter;
|
||||
wechatMenu: WechatMenu.Filter;
|
||||
wechatPublicTag: WechatPublicTag.Filter;
|
||||
wechatQrCode: WechatQrCode.Filter;
|
||||
wechatUser: WechatUser.Filter;
|
||||
|
|
@ -71,6 +74,7 @@ export type Projection = {
|
|||
userSystem?: UserSystem.Projection;
|
||||
userWechatPublicTag?: UserWechatPublicTag.Projection;
|
||||
wechatLogin?: WechatLogin.Projection;
|
||||
wechatMenu?: WechatMenu.Projection;
|
||||
wechatPublicTag?: WechatPublicTag.Projection;
|
||||
wechatQrCode?: WechatQrCode.Projection;
|
||||
wechatUser?: WechatUser.Projection;
|
||||
|
|
@ -96,6 +100,9 @@ type UserWechatPublicTagIdProjection = OneOf<{
|
|||
type WechatLoginIdProjection = OneOf<{
|
||||
entityId: number;
|
||||
}>;
|
||||
type WechatMenuIdProjection = OneOf<{
|
||||
entityId: number;
|
||||
}>;
|
||||
type WechatPublicTagIdProjection = OneOf<{
|
||||
entityId: number;
|
||||
}>;
|
||||
|
|
@ -131,6 +138,8 @@ export type SortAttr = {
|
|||
userWechatPublicTag: UserWechatPublicTag.SortAttr;
|
||||
} | {
|
||||
wechatLogin: WechatLogin.SortAttr;
|
||||
} | {
|
||||
wechatMenu: WechatMenu.SortAttr;
|
||||
} | {
|
||||
wechatPublicTag: WechatPublicTag.SortAttr;
|
||||
} | {
|
||||
|
|
@ -211,6 +220,17 @@ export type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "enti
|
|||
} | {
|
||||
entity: "wechatLogin";
|
||||
entityId: ForeignKey<"WechatLogin">;
|
||||
} | {
|
||||
entity?: never;
|
||||
entityId?: never;
|
||||
wechatMenu: WechatMenu.CreateSingleOperation;
|
||||
} | {
|
||||
entity: "wechatMenu";
|
||||
entityId: ForeignKey<"WechatMenu">;
|
||||
wechatMenu: WechatMenu.UpdateOperation;
|
||||
} | {
|
||||
entity: "wechatMenu";
|
||||
entityId: ForeignKey<"WechatMenu">;
|
||||
} | {
|
||||
entity?: never;
|
||||
entityId?: never;
|
||||
|
|
@ -284,6 +304,10 @@ export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "enti
|
|||
wechatLogin?: WechatLogin.CreateSingleOperation | WechatLogin.UpdateOperation | WechatLogin.RemoveOperation;
|
||||
entityId?: never;
|
||||
entity?: never;
|
||||
} | {
|
||||
wechatMenu?: WechatMenu.CreateSingleOperation | WechatMenu.UpdateOperation | WechatMenu.RemoveOperation;
|
||||
entityId?: never;
|
||||
entity?: never;
|
||||
} | {
|
||||
wechatPublicTag?: WechatPublicTag.CreateSingleOperation | WechatPublicTag.UpdateOperation | WechatPublicTag.RemoveOperation;
|
||||
entityId?: never;
|
||||
|
|
@ -297,8 +321,8 @@ export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "enti
|
|||
entityId?: never;
|
||||
entity?: never;
|
||||
} | {
|
||||
entity?: ("user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string) | null;
|
||||
entityId?: ForeignKey<"User" | "UserEntityGrant" | "UserSystem" | "UserWechatPublicTag" | "WechatLogin" | "WechatPublicTag" | "WechatQrCode" | "WechatUser"> | null;
|
||||
entity?: ("user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatMenu" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string) | null;
|
||||
entityId?: ForeignKey<"User" | "UserEntityGrant" | "UserSystem" | "UserWechatPublicTag" | "WechatLogin" | "WechatMenu" | "WechatPublicTag" | "WechatQrCode" | "WechatUser"> | null;
|
||||
}) & {
|
||||
[k: string]: any;
|
||||
};
|
||||
|
|
@ -315,6 +339,8 @@ export type RemoveOperationData = {} & (({
|
|||
userWechatPublicTag?: UserWechatPublicTag.UpdateOperation | UserWechatPublicTag.RemoveOperation;
|
||||
} | {
|
||||
wechatLogin?: WechatLogin.UpdateOperation | WechatLogin.RemoveOperation;
|
||||
} | {
|
||||
wechatMenu?: WechatMenu.UpdateOperation | WechatMenu.RemoveOperation;
|
||||
} | {
|
||||
wechatPublicTag?: WechatPublicTag.UpdateOperation | WechatPublicTag.RemoveOperation;
|
||||
} | {
|
||||
|
|
@ -332,6 +358,7 @@ export type UserEntityGrantIdSubQuery = Selection<UserEntityGrantIdProjection>;
|
|||
export type UserSystemIdSubQuery = Selection<UserSystemIdProjection>;
|
||||
export type UserWechatPublicTagIdSubQuery = Selection<UserWechatPublicTagIdProjection>;
|
||||
export type WechatLoginIdSubQuery = Selection<WechatLoginIdProjection>;
|
||||
export type WechatMenuIdSubQuery = Selection<WechatMenuIdProjection>;
|
||||
export type WechatPublicTagIdSubQuery = Selection<WechatPublicTagIdProjection>;
|
||||
export type WechatQrCodeIdSubQuery = Selection<WechatQrCodeIdProjection>;
|
||||
export type WechatUserIdSubQuery = Selection<WechatUserIdProjection>;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const desc = {
|
|||
params: {
|
||||
length: 32
|
||||
},
|
||||
ref: ["user", "userEntityGrant", "userSystem", "userWechatPublicTag", "wechatLogin", "wechatPublicTag", "wechatQrCode", "wechatUser"]
|
||||
ref: ["user", "userEntityGrant", "userSystem", "userWechatPublicTag", "wechatLogin", "wechatMenu", "wechatPublicTag", "wechatQrCode", "wechatUser"]
|
||||
},
|
||||
entityId: {
|
||||
notNull: true,
|
||||
|
|
|
|||
|
|
@ -11,18 +11,19 @@ import * as UserEntityGrant from "../UserEntityGrant/Schema";
|
|||
import * as UserSystem from "../UserSystem/Schema";
|
||||
import * as UserWechatPublicTag from "../UserWechatPublicTag/Schema";
|
||||
import * as WechatLogin from "../WechatLogin/Schema";
|
||||
import * as WechatMenu from "../WechatMenu/Schema";
|
||||
import * as WechatPublicTag from "../WechatPublicTag/Schema";
|
||||
import * as WechatQrCode from "../WechatQrCode/Schema";
|
||||
import * as WechatUser from "../WechatUser/Schema";
|
||||
export type OpSchema = EntityShape & {
|
||||
operId: ForeignKey<"oper">;
|
||||
entity: "user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string;
|
||||
entity: "user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatMenu" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string;
|
||||
entityId: String<64>;
|
||||
};
|
||||
export type OpAttr = keyof OpSchema;
|
||||
export type Schema = EntityShape & {
|
||||
operId: ForeignKey<"oper">;
|
||||
entity: "user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string;
|
||||
entity: "user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatMenu" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string;
|
||||
entityId: String<64>;
|
||||
oper: Oper.Schema;
|
||||
user?: User.Schema;
|
||||
|
|
@ -30,6 +31,7 @@ export type Schema = EntityShape & {
|
|||
userSystem?: UserSystem.Schema;
|
||||
userWechatPublicTag?: UserWechatPublicTag.Schema;
|
||||
wechatLogin?: WechatLogin.Schema;
|
||||
wechatMenu?: WechatMenu.Schema;
|
||||
wechatPublicTag?: WechatPublicTag.Schema;
|
||||
wechatQrCode?: WechatQrCode.Schema;
|
||||
wechatUser?: WechatUser.Schema;
|
||||
|
|
@ -43,13 +45,14 @@ type AttrFilter = {
|
|||
$$updateAt$$: Q_DateValue;
|
||||
operId: Q_StringValue;
|
||||
oper: Oper.Filter;
|
||||
entity: Q_EnumValue<"user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string>;
|
||||
entity: Q_EnumValue<"user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatMenu" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string>;
|
||||
entityId: Q_StringValue;
|
||||
user: User.Filter;
|
||||
userEntityGrant: UserEntityGrant.Filter;
|
||||
userSystem: UserSystem.Filter;
|
||||
userWechatPublicTag: UserWechatPublicTag.Filter;
|
||||
wechatLogin: WechatLogin.Filter;
|
||||
wechatMenu: WechatMenu.Filter;
|
||||
wechatPublicTag: WechatPublicTag.Filter;
|
||||
wechatQrCode: WechatQrCode.Filter;
|
||||
wechatUser: WechatUser.Filter;
|
||||
|
|
@ -71,6 +74,7 @@ export type Projection = {
|
|||
userSystem?: UserSystem.Projection;
|
||||
userWechatPublicTag?: UserWechatPublicTag.Projection;
|
||||
wechatLogin?: WechatLogin.Projection;
|
||||
wechatMenu?: WechatMenu.Projection;
|
||||
wechatPublicTag?: WechatPublicTag.Projection;
|
||||
wechatQrCode?: WechatQrCode.Projection;
|
||||
wechatUser?: WechatUser.Projection;
|
||||
|
|
@ -96,6 +100,9 @@ type UserWechatPublicTagIdProjection = OneOf<{
|
|||
type WechatLoginIdProjection = OneOf<{
|
||||
entityId: number;
|
||||
}>;
|
||||
type WechatMenuIdProjection = OneOf<{
|
||||
entityId: number;
|
||||
}>;
|
||||
type WechatPublicTagIdProjection = OneOf<{
|
||||
entityId: number;
|
||||
}>;
|
||||
|
|
@ -131,6 +138,8 @@ export type SortAttr = {
|
|||
userWechatPublicTag: UserWechatPublicTag.SortAttr;
|
||||
} | {
|
||||
wechatLogin: WechatLogin.SortAttr;
|
||||
} | {
|
||||
wechatMenu: WechatMenu.SortAttr;
|
||||
} | {
|
||||
wechatPublicTag: WechatPublicTag.SortAttr;
|
||||
} | {
|
||||
|
|
@ -208,6 +217,17 @@ export type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "enti
|
|||
} | {
|
||||
entity: "wechatLogin";
|
||||
entityId: ForeignKey<"WechatLogin">;
|
||||
} | {
|
||||
entity?: never;
|
||||
entityId?: never;
|
||||
wechatMenu: WechatMenu.CreateSingleOperation;
|
||||
} | {
|
||||
entity: "wechatMenu";
|
||||
entityId: ForeignKey<"WechatMenu">;
|
||||
wechatMenu: WechatMenu.UpdateOperation;
|
||||
} | {
|
||||
entity: "wechatMenu";
|
||||
entityId: ForeignKey<"WechatMenu">;
|
||||
} | {
|
||||
entity?: never;
|
||||
entityId?: never;
|
||||
|
|
@ -275,6 +295,10 @@ export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "enti
|
|||
wechatLogin?: WechatLogin.CreateSingleOperation | WechatLogin.UpdateOperation | WechatLogin.RemoveOperation;
|
||||
entityId?: never;
|
||||
entity?: never;
|
||||
} | {
|
||||
wechatMenu?: WechatMenu.CreateSingleOperation | WechatMenu.UpdateOperation | WechatMenu.RemoveOperation;
|
||||
entityId?: never;
|
||||
entity?: never;
|
||||
} | {
|
||||
wechatPublicTag?: WechatPublicTag.CreateSingleOperation | WechatPublicTag.UpdateOperation | WechatPublicTag.RemoveOperation;
|
||||
entityId?: never;
|
||||
|
|
@ -288,8 +312,8 @@ export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "enti
|
|||
entityId?: never;
|
||||
entity?: never;
|
||||
} | {
|
||||
entity?: ("user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string) | null;
|
||||
entityId?: ForeignKey<"User" | "UserEntityGrant" | "UserSystem" | "UserWechatPublicTag" | "WechatLogin" | "WechatPublicTag" | "WechatQrCode" | "WechatUser"> | null;
|
||||
entity?: ("user" | "userEntityGrant" | "userSystem" | "userWechatPublicTag" | "wechatLogin" | "wechatMenu" | "wechatPublicTag" | "wechatQrCode" | "wechatUser" | string) | null;
|
||||
entityId?: ForeignKey<"User" | "UserEntityGrant" | "UserSystem" | "UserWechatPublicTag" | "WechatLogin" | "WechatMenu" | "WechatPublicTag" | "WechatQrCode" | "WechatUser"> | null;
|
||||
}) & {
|
||||
[k: string]: any;
|
||||
};
|
||||
|
|
@ -304,6 +328,8 @@ export type RemoveOperationData = {} & ({
|
|||
userWechatPublicTag?: UserWechatPublicTag.UpdateOperation | UserWechatPublicTag.RemoveOperation;
|
||||
} | {
|
||||
wechatLogin?: WechatLogin.UpdateOperation | WechatLogin.RemoveOperation;
|
||||
} | {
|
||||
wechatMenu?: WechatMenu.UpdateOperation | WechatMenu.RemoveOperation;
|
||||
} | {
|
||||
wechatPublicTag?: WechatPublicTag.UpdateOperation | WechatPublicTag.RemoveOperation;
|
||||
} | {
|
||||
|
|
@ -321,6 +347,7 @@ export type UserEntityGrantIdSubQuery = Selection<UserEntityGrantIdProjection>;
|
|||
export type UserSystemIdSubQuery = Selection<UserSystemIdProjection>;
|
||||
export type UserWechatPublicTagIdSubQuery = Selection<UserWechatPublicTagIdProjection>;
|
||||
export type WechatLoginIdSubQuery = Selection<WechatLoginIdProjection>;
|
||||
export type WechatMenuIdSubQuery = Selection<WechatMenuIdProjection>;
|
||||
export type WechatPublicTagIdSubQuery = Selection<WechatPublicTagIdProjection>;
|
||||
export type WechatQrCodeIdSubQuery = Selection<WechatQrCodeIdProjection>;
|
||||
export type WechatUserIdSubQuery = Selection<WechatUserIdProjection>;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const desc = {
|
|||
params: {
|
||||
length: 32
|
||||
},
|
||||
ref: ["user", "userEntityGrant", "userSystem", "userWechatPublicTag", "wechatLogin", "wechatPublicTag", "wechatQrCode", "wechatUser"]
|
||||
ref: ["user", "userEntityGrant", "userSystem", "userWechatPublicTag", "wechatLogin", "wechatMenu", "wechatPublicTag", "wechatQrCode", "wechatUser"]
|
||||
},
|
||||
entityId: {
|
||||
notNull: true,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import { desc as tokenDesc } from "./Token/Storage";
|
|||
import { desc as userSystemDesc } from "./UserSystem/Storage";
|
||||
import { desc as userWechatPublicTagDesc } from "./UserWechatPublicTag/Storage";
|
||||
import { desc as wechatLoginDesc } from "./WechatLogin/Storage";
|
||||
import { desc as wechatMenuDesc } from "./WechatMenu/Storage";
|
||||
import { desc as wechatPublicTagDesc } from "./WechatPublicTag/Storage";
|
||||
import { desc as wechatQrCodeDesc } from "./WechatQrCode/Storage";
|
||||
import { desc as wechatUserDesc } from "./WechatUser/Storage";
|
||||
|
|
@ -84,6 +85,7 @@ export const storageSchema = {
|
|||
userSystem: userSystemDesc,
|
||||
userWechatPublicTag: userWechatPublicTagDesc,
|
||||
wechatLogin: wechatLoginDesc,
|
||||
wechatMenu: wechatMenuDesc,
|
||||
wechatPublicTag: wechatPublicTagDesc,
|
||||
wechatQrCode: wechatQrCodeDesc,
|
||||
wechatUser: wechatUserDesc
|
||||
|
|
|
|||
|
|
@ -0,0 +1,202 @@
|
|||
import { ForeignKey, JsonProjection } from "oak-domain/lib/types/DataType";
|
||||
import { Q_DateValue, Q_NumberValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey, JsonFilter, SubQueryPredicateMetadata } from "oak-domain/lib/types/Demand";
|
||||
import { OneOf } from "oak-domain/lib/types/Polyfill";
|
||||
import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, Selection as OakSelection, MakeAction as OakMakeAction, AggregationResult } from "oak-domain/lib/types/Entity";
|
||||
import { GenericAction } from "oak-domain/lib/actions/action";
|
||||
import { Int } from "oak-domain/lib/types/DataType";
|
||||
import { EntityShape } from "oak-domain/lib/types/Entity";
|
||||
import * as Application from "../Application/Schema";
|
||||
import * as WechatPublicTag from "../WechatPublicTag/Schema";
|
||||
import * as ModiEntity from "../ModiEntity/Schema";
|
||||
import * as OperEntity from "../OperEntity/Schema";
|
||||
type Config = {
|
||||
button: any[];
|
||||
matchrule?: {
|
||||
tag_id?: string;
|
||||
};
|
||||
};
|
||||
export type OpSchema = EntityShape & {
|
||||
menuId?: Int<4> | null;
|
||||
menuConfig: Config;
|
||||
applicationId: ForeignKey<"application">;
|
||||
publishState: 'wait' | 'success' | 'fail';
|
||||
wechatPublicTagId?: ForeignKey<"wechatPublicTag"> | null;
|
||||
};
|
||||
export type OpAttr = keyof OpSchema;
|
||||
export type Schema = EntityShape & {
|
||||
menuId?: Int<4> | null;
|
||||
menuConfig: Config;
|
||||
applicationId: ForeignKey<"application">;
|
||||
publishState: 'wait' | 'success' | 'fail';
|
||||
wechatPublicTagId?: ForeignKey<"wechatPublicTag"> | null;
|
||||
application: Application.Schema;
|
||||
wechatPublicTag?: WechatPublicTag.Schema | null;
|
||||
modiEntity$entity?: Array<ModiEntity.Schema>;
|
||||
modiEntity$entity$$aggr?: AggregationResult<ModiEntity.Schema>;
|
||||
operEntity$entity?: Array<OperEntity.Schema>;
|
||||
operEntity$entity$$aggr?: AggregationResult<OperEntity.Schema>;
|
||||
} & {
|
||||
[A in ExpressionKey]?: any;
|
||||
};
|
||||
type AttrFilter = {
|
||||
id: Q_StringValue;
|
||||
$$createAt$$: Q_DateValue;
|
||||
$$seq$$: Q_StringValue;
|
||||
$$updateAt$$: Q_DateValue;
|
||||
menuId: Q_NumberValue;
|
||||
menuConfig: JsonFilter<Config>;
|
||||
applicationId: Q_StringValue;
|
||||
application: Application.Filter;
|
||||
publishState: Q_EnumValue<'wait' | 'success' | 'fail'>;
|
||||
wechatPublicTagId: Q_StringValue;
|
||||
wechatPublicTag: WechatPublicTag.Filter;
|
||||
modiEntity$entity: ModiEntity.Filter & SubQueryPredicateMetadata;
|
||||
operEntity$entity: OperEntity.Filter & SubQueryPredicateMetadata;
|
||||
};
|
||||
export type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>;
|
||||
export type Projection = {
|
||||
"#id"?: NodeId;
|
||||
[k: string]: any;
|
||||
id?: number;
|
||||
$$createAt$$?: number;
|
||||
$$updateAt$$?: number;
|
||||
$$seq$$?: number;
|
||||
menuId?: number;
|
||||
menuConfig?: number | JsonProjection<Config>;
|
||||
applicationId?: number;
|
||||
application?: Application.Projection;
|
||||
publishState?: number;
|
||||
wechatPublicTagId?: number;
|
||||
wechatPublicTag?: WechatPublicTag.Projection;
|
||||
modiEntity$entity?: ModiEntity.Selection & {
|
||||
$entity: "modiEntity";
|
||||
};
|
||||
modiEntity$entity$$aggr?: ModiEntity.Aggregation & {
|
||||
$entity: "modiEntity";
|
||||
};
|
||||
operEntity$entity?: OperEntity.Selection & {
|
||||
$entity: "operEntity";
|
||||
};
|
||||
operEntity$entity$$aggr?: OperEntity.Aggregation & {
|
||||
$entity: "operEntity";
|
||||
};
|
||||
} & Partial<ExprOp<OpAttr | string>>;
|
||||
type WechatMenuIdProjection = OneOf<{
|
||||
id: number;
|
||||
}>;
|
||||
type ApplicationIdProjection = OneOf<{
|
||||
applicationId: number;
|
||||
}>;
|
||||
type WechatPublicTagIdProjection = OneOf<{
|
||||
wechatPublicTagId: number;
|
||||
}>;
|
||||
export type SortAttr = {
|
||||
id: number;
|
||||
} | {
|
||||
$$createAt$$: number;
|
||||
} | {
|
||||
$$seq$$: number;
|
||||
} | {
|
||||
$$updateAt$$: number;
|
||||
} | {
|
||||
menuId: number;
|
||||
} | {
|
||||
menuConfig: number;
|
||||
} | {
|
||||
applicationId: number;
|
||||
} | {
|
||||
application: Application.SortAttr;
|
||||
} | {
|
||||
publishState: number;
|
||||
} | {
|
||||
wechatPublicTagId: number;
|
||||
} | {
|
||||
wechatPublicTag: WechatPublicTag.SortAttr;
|
||||
} | {
|
||||
[k: string]: any;
|
||||
} | OneOf<ExprOp<OpAttr | string>>;
|
||||
export type SortNode = {
|
||||
$attr: SortAttr;
|
||||
$direction?: "asc" | "desc";
|
||||
};
|
||||
export type Sorter = SortNode[];
|
||||
export type SelectOperation<P extends Object = Projection> = OakSelection<"select", P, Filter, Sorter>;
|
||||
export type Selection<P extends Object = Projection> = SelectOperation<P>;
|
||||
export type Aggregation = DeduceAggregation<Projection, Filter, Sorter>;
|
||||
export type CreateOperationData = FormCreateData<Omit<OpSchema, "applicationId" | "wechatPublicTagId">> & (({
|
||||
applicationId?: never;
|
||||
application: Application.CreateSingleOperation;
|
||||
} | {
|
||||
applicationId: ForeignKey<"application">;
|
||||
application?: Application.UpdateOperation;
|
||||
} | {
|
||||
applicationId: ForeignKey<"application">;
|
||||
}) & ({
|
||||
wechatPublicTagId?: never;
|
||||
wechatPublicTag?: WechatPublicTag.CreateSingleOperation;
|
||||
} | {
|
||||
wechatPublicTagId: ForeignKey<"wechatPublicTag">;
|
||||
wechatPublicTag?: WechatPublicTag.UpdateOperation;
|
||||
} | {
|
||||
wechatPublicTagId?: ForeignKey<"wechatPublicTag">;
|
||||
})) & {
|
||||
modiEntity$entity?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">>>;
|
||||
operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>;
|
||||
};
|
||||
export type CreateSingleOperation = OakOperation<"create", CreateOperationData>;
|
||||
export type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>;
|
||||
export type CreateOperation = CreateSingleOperation | CreateMultipleOperation;
|
||||
export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "applicationId" | "wechatPublicTagId">> & (({
|
||||
application: Application.CreateSingleOperation;
|
||||
applicationId?: never;
|
||||
} | {
|
||||
application: Application.UpdateOperation;
|
||||
applicationId?: never;
|
||||
} | {
|
||||
application: Application.RemoveOperation;
|
||||
applicationId?: never;
|
||||
} | {
|
||||
application?: never;
|
||||
applicationId?: ForeignKey<"application"> | null;
|
||||
}) & ({
|
||||
wechatPublicTag: WechatPublicTag.CreateSingleOperation;
|
||||
wechatPublicTagId?: never;
|
||||
} | {
|
||||
wechatPublicTag: WechatPublicTag.UpdateOperation;
|
||||
wechatPublicTagId?: never;
|
||||
} | {
|
||||
wechatPublicTag: WechatPublicTag.RemoveOperation;
|
||||
wechatPublicTagId?: never;
|
||||
} | {
|
||||
wechatPublicTag?: never;
|
||||
wechatPublicTagId?: ForeignKey<"wechatPublicTag"> | null;
|
||||
})) & {
|
||||
[k: string]: any;
|
||||
modiEntity$entity?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">>>;
|
||||
operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>;
|
||||
};
|
||||
export type UpdateOperation = OakOperation<"update" | string, UpdateOperationData, Filter, Sorter>;
|
||||
export type RemoveOperationData = {} & (({
|
||||
application?: Application.UpdateOperation | Application.RemoveOperation;
|
||||
}) & ({
|
||||
wechatPublicTag?: WechatPublicTag.UpdateOperation | WechatPublicTag.RemoveOperation;
|
||||
}));
|
||||
export type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>;
|
||||
export type Operation = CreateOperation | UpdateOperation | RemoveOperation;
|
||||
export type ApplicationIdSubQuery = Selection<ApplicationIdProjection>;
|
||||
export type WechatPublicTagIdSubQuery = Selection<WechatPublicTagIdProjection>;
|
||||
export type WechatMenuIdSubQuery = Selection<WechatMenuIdProjection>;
|
||||
export type EntityDef = {
|
||||
Schema: Schema;
|
||||
OpSchema: OpSchema;
|
||||
Action: OakMakeAction<GenericAction> | string;
|
||||
Selection: Selection;
|
||||
Aggregation: Aggregation;
|
||||
Operation: Operation;
|
||||
Create: CreateOperation;
|
||||
Update: UpdateOperation;
|
||||
Remove: RemoveOperation;
|
||||
CreateSingle: CreateSingleOperation;
|
||||
CreateMulti: CreateMultipleOperation;
|
||||
};
|
||||
export {};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export {};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { StorageDesc } from "oak-domain/lib/types/Storage";
|
||||
import { OpSchema } from "./Schema";
|
||||
export declare const desc: StorageDesc<OpSchema>;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import { genericActions as actions } from "oak-domain/lib/actions/action";
|
||||
export const desc = {
|
||||
attributes: {
|
||||
menuId: {
|
||||
type: "int",
|
||||
params: {
|
||||
width: 4,
|
||||
signed: true
|
||||
}
|
||||
},
|
||||
menuConfig: {
|
||||
notNull: true,
|
||||
type: "object"
|
||||
},
|
||||
applicationId: {
|
||||
notNull: true,
|
||||
type: "ref",
|
||||
ref: "application"
|
||||
},
|
||||
publishState: {
|
||||
notNull: true,
|
||||
type: "enum",
|
||||
enumeration: ["wait", "success", "fail"]
|
||||
},
|
||||
wechatPublicTagId: {
|
||||
type: "ref",
|
||||
ref: "wechatPublicTag"
|
||||
}
|
||||
},
|
||||
actionType: "crud",
|
||||
actions
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
{ "name": "微信菜单", "attr": { "menuId": "菜单Id", "menuConfig": "菜单配置", "application": "应用", "publishState": "发布状态", "wechatPublicTag": "标签" }, "v": { "publishState": { "wait": "等待发布", "success": "发布成功", "fail": "发布失败" } } }
|
||||
|
|
@ -7,6 +7,7 @@ import { String, Datetime, Boolean, Uint } from "oak-domain/lib/types/DataType";
|
|||
import { EntityShape } from "oak-domain/lib/types/Entity";
|
||||
import * as Application from "../Application/Schema";
|
||||
import * as UserWechatPublicTag from "../UserWechatPublicTag/Schema";
|
||||
import * as WechatMenu from "../WechatMenu/Schema";
|
||||
import * as ModiEntity from "../ModiEntity/Schema";
|
||||
import * as OperEntity from "../OperEntity/Schema";
|
||||
export type OpSchema = EntityShape & {
|
||||
|
|
@ -26,6 +27,8 @@ export type Schema = EntityShape & {
|
|||
application: Application.Schema;
|
||||
userWechatPublicTag$wechatPublicTag?: Array<UserWechatPublicTag.Schema>;
|
||||
userWechatPublicTag$wechatPublicTag$$aggr?: AggregationResult<UserWechatPublicTag.Schema>;
|
||||
wechatMenu$wechatPublicTag?: Array<WechatMenu.Schema>;
|
||||
wechatMenu$wechatPublicTag$$aggr?: AggregationResult<WechatMenu.Schema>;
|
||||
modiEntity$entity?: Array<ModiEntity.Schema>;
|
||||
modiEntity$entity$$aggr?: AggregationResult<ModiEntity.Schema>;
|
||||
operEntity$entity?: Array<OperEntity.Schema>;
|
||||
|
|
@ -45,6 +48,7 @@ type AttrFilter = {
|
|||
sync: Q_BooleanValue;
|
||||
syncAt: Q_DateValue;
|
||||
userWechatPublicTag$wechatPublicTag: UserWechatPublicTag.Filter & SubQueryPredicateMetadata;
|
||||
wechatMenu$wechatPublicTag: WechatMenu.Filter & SubQueryPredicateMetadata;
|
||||
modiEntity$entity: ModiEntity.Filter & SubQueryPredicateMetadata;
|
||||
operEntity$entity: OperEntity.Filter & SubQueryPredicateMetadata;
|
||||
};
|
||||
|
|
@ -68,6 +72,12 @@ export type Projection = {
|
|||
userWechatPublicTag$wechatPublicTag$$aggr?: UserWechatPublicTag.Aggregation & {
|
||||
$entity: "userWechatPublicTag";
|
||||
};
|
||||
wechatMenu$wechatPublicTag?: WechatMenu.Selection & {
|
||||
$entity: "wechatMenu";
|
||||
};
|
||||
wechatMenu$wechatPublicTag$$aggr?: WechatMenu.Aggregation & {
|
||||
$entity: "wechatMenu";
|
||||
};
|
||||
modiEntity$entity?: ModiEntity.Selection & {
|
||||
$entity: "modiEntity";
|
||||
};
|
||||
|
|
@ -128,6 +138,7 @@ export type CreateOperationData = FormCreateData<Omit<OpSchema, "applicationId">
|
|||
applicationId: ForeignKey<"application">;
|
||||
})) & {
|
||||
userWechatPublicTag$wechatPublicTag?: OakOperation<UserWechatPublicTag.UpdateOperation["action"], Omit<UserWechatPublicTag.UpdateOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<UserWechatPublicTag.Filter, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<"create", Omit<UserWechatPublicTag.CreateOperationData, "wechatPublicTag" | "wechatPublicTagId">[]> | Array<OakOperation<"create", Omit<UserWechatPublicTag.CreateOperationData, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<UserWechatPublicTag.UpdateOperation["action"], Omit<UserWechatPublicTag.UpdateOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<UserWechatPublicTag.Filter, "wechatPublicTag" | "wechatPublicTagId">>>;
|
||||
wechatMenu$wechatPublicTag?: OakOperation<WechatMenu.UpdateOperation["action"], Omit<WechatMenu.UpdateOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<WechatMenu.Filter, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<"create", Omit<WechatMenu.CreateOperationData, "wechatPublicTag" | "wechatPublicTagId">[]> | Array<OakOperation<"create", Omit<WechatMenu.CreateOperationData, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<WechatMenu.UpdateOperation["action"], Omit<WechatMenu.UpdateOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<WechatMenu.Filter, "wechatPublicTag" | "wechatPublicTagId">>>;
|
||||
modiEntity$entity?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">>>;
|
||||
operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>;
|
||||
};
|
||||
|
|
@ -149,6 +160,7 @@ export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "applicationId">
|
|||
})) & {
|
||||
[k: string]: any;
|
||||
userWechatPublicTag$wechatPublicTag?: OakOperation<UserWechatPublicTag.UpdateOperation["action"], Omit<UserWechatPublicTag.UpdateOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<UserWechatPublicTag.Filter, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<UserWechatPublicTag.RemoveOperation["action"], Omit<UserWechatPublicTag.RemoveOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<UserWechatPublicTag.Filter, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<"create", Omit<UserWechatPublicTag.CreateOperationData, "wechatPublicTag" | "wechatPublicTagId">[]> | Array<OakOperation<"create", Omit<UserWechatPublicTag.CreateOperationData, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<UserWechatPublicTag.UpdateOperation["action"], Omit<UserWechatPublicTag.UpdateOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<UserWechatPublicTag.Filter, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<UserWechatPublicTag.RemoveOperation["action"], Omit<UserWechatPublicTag.RemoveOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<UserWechatPublicTag.Filter, "wechatPublicTag" | "wechatPublicTagId">>>;
|
||||
wechatMenu$wechatPublicTag?: OakOperation<WechatMenu.UpdateOperation["action"], Omit<WechatMenu.UpdateOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<WechatMenu.Filter, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<WechatMenu.RemoveOperation["action"], Omit<WechatMenu.RemoveOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<WechatMenu.Filter, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<"create", Omit<WechatMenu.CreateOperationData, "wechatPublicTag" | "wechatPublicTagId">[]> | Array<OakOperation<"create", Omit<WechatMenu.CreateOperationData, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<WechatMenu.UpdateOperation["action"], Omit<WechatMenu.UpdateOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<WechatMenu.Filter, "wechatPublicTag" | "wechatPublicTagId">> | OakOperation<WechatMenu.RemoveOperation["action"], Omit<WechatMenu.RemoveOperationData, "wechatPublicTag" | "wechatPublicTagId">, Omit<WechatMenu.Filter, "wechatPublicTag" | "wechatPublicTagId">>>;
|
||||
modiEntity$entity?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">>>;
|
||||
operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import * as Token from "./Token/Schema";
|
|||
import * as UserSystem from "./UserSystem/Schema";
|
||||
import * as UserWechatPublicTag from "./UserWechatPublicTag/Schema";
|
||||
import * as WechatLogin from "./WechatLogin/Schema";
|
||||
import * as WechatMenu from "./WechatMenu/Schema";
|
||||
import * as WechatPublicTag from "./WechatPublicTag/Schema";
|
||||
import * as WechatQrCode from "./WechatQrCode/Schema";
|
||||
import * as WechatUser from "./WechatUser/Schema";
|
||||
|
|
@ -167,6 +168,8 @@ export type ApplicationIdSubQuery = {
|
|||
entity: "sessionMessage";
|
||||
}) | (Token.ApplicationIdSubQuery & {
|
||||
entity: "token";
|
||||
}) | (WechatMenu.ApplicationIdSubQuery & {
|
||||
entity: "wechatMenu";
|
||||
}) | (WechatPublicTag.ApplicationIdSubQuery & {
|
||||
entity: "wechatPublicTag";
|
||||
}) | (WechatQrCode.ApplicationIdSubQuery & {
|
||||
|
|
@ -385,9 +388,20 @@ export type WechatLoginIdSubQuery = {
|
|||
entity: "wechatLogin";
|
||||
}) | any;
|
||||
};
|
||||
export type WechatMenuIdSubQuery = {
|
||||
[K in "$in" | "$nin"]?: (ModiEntity.WechatMenuIdSubQuery & {
|
||||
entity: "modiEntity";
|
||||
}) | (OperEntity.WechatMenuIdSubQuery & {
|
||||
entity: "operEntity";
|
||||
}) | (WechatMenu.WechatMenuIdSubQuery & {
|
||||
entity: "wechatMenu";
|
||||
}) | any;
|
||||
};
|
||||
export type WechatPublicTagIdSubQuery = {
|
||||
[K in "$in" | "$nin"]?: (UserWechatPublicTag.WechatPublicTagIdSubQuery & {
|
||||
entity: "userWechatPublicTag";
|
||||
}) | (WechatMenu.WechatPublicTagIdSubQuery & {
|
||||
entity: "wechatMenu";
|
||||
}) | (ModiEntity.WechatPublicTagIdSubQuery & {
|
||||
entity: "modiEntity";
|
||||
}) | (OperEntity.WechatPublicTagIdSubQuery & {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Tabs, Card, Descriptions, Typography, Button } from 'antd';
|
|||
import PageHeader from '../../../components/common/pageHeader';
|
||||
import Style from './web.module.less';
|
||||
import MessageTypeTemplateIdList from '../../../components/messageTypeTemplateId/list';
|
||||
import WechatMenu from '../../../components/wechatMenu';
|
||||
export default function Render(props) {
|
||||
const { oakId, tabValue, config, name, description, type, system } = props.data;
|
||||
const { t, navigateBack, onTabClick, goWechatPublicTagList } = props.methods;
|
||||
|
|
@ -25,5 +26,12 @@ export default function Render(props) {
|
|||
children: (_jsx(MessageTypeTemplateIdList, { oakAutoUnmount: true, applicationId: oakId, oakPath: `$application-detail-mttId-${oakId}` })),
|
||||
});
|
||||
}
|
||||
if (['wechatPublic'].includes(type)) {
|
||||
items.push({
|
||||
label: '菜单管理',
|
||||
key: 'menu',
|
||||
children: (_jsx(WechatMenu, { oakAutoUnmount: true, applicationId: oakId, oakPath: `$application-detail-menu-${oakId}` }))
|
||||
});
|
||||
}
|
||||
return (_jsx(PageHeader, { showBack: true, title: "\u5E94\u7528\u6982\u89C8", children: _jsx("div", { className: Style.container, children: _jsx(Card, { title: name, bordered: false, extra: Actions, children: _jsx(Tabs, { items: items }) }) }) }));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,5 +105,50 @@ export type GeneralAspectDict<ED extends EntityDict, Cxt extends BackendRuntimeC
|
|||
result: string;
|
||||
times?: number;
|
||||
}>;
|
||||
getCurrentMenu: (params: {
|
||||
applicationId: string;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
getMenu: (params: {
|
||||
applicationId: string;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
createMenu: (params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
createConditionalMenu: (params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
deleteConditionalMenu: (params: {
|
||||
applicationId: string;
|
||||
menuid: number;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
batchGetArticle: (params: {
|
||||
applicationId: string;
|
||||
offset?: number;
|
||||
count: number;
|
||||
noContent?: 0 | 1;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
getArticle: (params: {
|
||||
applicationId: string;
|
||||
article_id: string;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
createMaterial: (params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'voice' | 'video' | 'thumb';
|
||||
media: FormData;
|
||||
description?: FormData;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
batchGetMaterialList: (params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
offset?: number;
|
||||
count: number;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
getMaterial: (params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
media_id: string;
|
||||
}, context: Cxt) => Promise<any>;
|
||||
};
|
||||
export default GeneralAspectDict;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { createWechatLogin } from './wechatLogin';
|
|||
import { unbindingWechat } from './wechatUser';
|
||||
import { getMpUnlimitWxaCode } from './wechatQrCode';
|
||||
import { confirmUserEntityGrant } from './userEntityGrant';
|
||||
import { getCurrentMenu, getMenu, createMenu, createConditionalMenu, deleteConditionalMenu, batchGetArticle, getArticle, createMaterial, batchGetMaterialList, getMaterial } from './wechatMenu';
|
||||
declare const aspectDict: {
|
||||
mergeUser: typeof mergeUser;
|
||||
switchTo: typeof switchTo;
|
||||
|
|
@ -31,5 +32,15 @@ declare const aspectDict: {
|
|||
updateUserPassword: typeof updateUserPassword;
|
||||
getMpUnlimitWxaCode: typeof getMpUnlimitWxaCode;
|
||||
confirmUserEntityGrant: typeof confirmUserEntityGrant;
|
||||
getCurrentMenu: typeof getCurrentMenu;
|
||||
getMenu: typeof getMenu;
|
||||
createMenu: typeof createMenu;
|
||||
createConditionalMenu: typeof createConditionalMenu;
|
||||
deleteConditionalMenu: typeof deleteConditionalMenu;
|
||||
batchGetArticle: typeof batchGetArticle;
|
||||
getArticle: typeof getArticle;
|
||||
createMaterial: typeof createMaterial;
|
||||
batchGetMaterialList: typeof batchGetMaterialList;
|
||||
getMaterial: typeof getMaterial;
|
||||
};
|
||||
export default aspectDict;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const wechatLogin_1 = require("./wechatLogin");
|
|||
const wechatUser_1 = require("./wechatUser");
|
||||
const wechatQrCode_1 = require("./wechatQrCode");
|
||||
const userEntityGrant_1 = require("./userEntityGrant");
|
||||
const wechatMenu_1 = require("./wechatMenu");
|
||||
const aspectDict = {
|
||||
mergeUser: user_1.mergeUser,
|
||||
switchTo: token_1.switchTo,
|
||||
|
|
@ -33,5 +34,15 @@ const aspectDict = {
|
|||
updateUserPassword: user_1.updateUserPassword,
|
||||
getMpUnlimitWxaCode: wechatQrCode_1.getMpUnlimitWxaCode,
|
||||
confirmUserEntityGrant: userEntityGrant_1.confirmUserEntityGrant,
|
||||
getCurrentMenu: wechatMenu_1.getCurrentMenu,
|
||||
getMenu: wechatMenu_1.getMenu,
|
||||
createMenu: wechatMenu_1.createMenu,
|
||||
createConditionalMenu: wechatMenu_1.createConditionalMenu,
|
||||
deleteConditionalMenu: wechatMenu_1.deleteConditionalMenu,
|
||||
batchGetArticle: wechatMenu_1.batchGetArticle,
|
||||
getArticle: wechatMenu_1.getArticle,
|
||||
createMaterial: wechatMenu_1.createMaterial,
|
||||
batchGetMaterialList: wechatMenu_1.batchGetMaterialList,
|
||||
getMaterial: wechatMenu_1.getMaterial,
|
||||
};
|
||||
exports.default = aspectDict;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { BackendRuntimeContext } from '../context/BackendRuntimeContext';
|
||||
export declare function getCurrentMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function getMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function createMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function createConditionalMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
menuConfig: any;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function deleteConditionalMenu<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
menuid: number;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function batchGetArticle<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
offset?: number;
|
||||
count: number;
|
||||
noContent?: 0 | 1;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function getArticle<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
article_id: string;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function createMaterial<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'voice' | 'video' | 'thumb';
|
||||
media: FormData;
|
||||
description?: FormData;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function batchGetMaterialList<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
offset?: number;
|
||||
count: number;
|
||||
}, context: Cxt): Promise<any>;
|
||||
export declare function getMaterial<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
|
||||
applicationId: string;
|
||||
type: 'image' | 'video' | 'voice' | 'news';
|
||||
media_id: string;
|
||||
}, context: Cxt): Promise<any>;
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getMaterial = exports.batchGetMaterialList = exports.createMaterial = exports.getArticle = exports.batchGetArticle = exports.deleteConditionalMenu = exports.createConditionalMenu = exports.createMenu = exports.getMenu = exports.getCurrentMenu = void 0;
|
||||
const oak_external_sdk_1 = require("oak-external-sdk");
|
||||
async function getWechatPublicConfig(applicationId, context) {
|
||||
const [application] = await context.select('application', {
|
||||
data: {
|
||||
id: 1,
|
||||
config: 1,
|
||||
type: 1,
|
||||
},
|
||||
filter: {
|
||||
id: applicationId,
|
||||
type: 'wechatPublic'
|
||||
},
|
||||
}, {
|
||||
dontCollect: true
|
||||
});
|
||||
return application;
|
||||
}
|
||||
async function getCurrentMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.getCurrentMenu();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.getCurrentMenu = getCurrentMenu;
|
||||
async function getMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.getMenu();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.getMenu = getMenu;
|
||||
async function createMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.createMenu(params.menuConfig);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.createMenu = createMenu;
|
||||
async function createConditionalMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.createConditionalMenu(params.menuConfig);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.createConditionalMenu = createConditionalMenu;
|
||||
async function deleteConditionalMenu(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.deleteConditionalMenu(params.menuid);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.deleteConditionalMenu = deleteConditionalMenu;
|
||||
async function batchGetArticle(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.batchGetArticle(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.batchGetArticle = batchGetArticle;
|
||||
async function getArticle(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.getArticle(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.getArticle = getArticle;
|
||||
async function createMaterial(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.createMaterial(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.createMaterial = createMaterial;
|
||||
async function batchGetMaterialList(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.batchGetMaterialList(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.batchGetMaterialList = batchGetMaterialList;
|
||||
async function getMaterial(params, context) {
|
||||
const application = await getWechatPublicConfig(params.applicationId, context);
|
||||
if (application) {
|
||||
const { type, config, systemId } = application;
|
||||
let appId, appSecret;
|
||||
const config2 = config;
|
||||
appId = config2.appId;
|
||||
appSecret = config2.appSecret;
|
||||
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, type, appSecret);
|
||||
const result = await wechatInstance.getMaterial(params);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.getMaterial = getMaterial;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../oak-app-domain").EntityDict, keyof import("../../oak-app-domain").EntityDict, false, {
|
||||
type: "image" | "video" | "news" | "voice";
|
||||
getMenuContent: (menuContent: any) => void;
|
||||
applicationId: string;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
type: '',
|
||||
getMenuContent: (menuContent) => undefined,
|
||||
applicationId: '',
|
||||
},
|
||||
lifetimes: {
|
||||
async ready() {
|
||||
const { type, applicationId } = this.props;
|
||||
let result;
|
||||
if (type === 'news') {
|
||||
result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId, offset: 0, count: 10, noContent: 0 });
|
||||
const modifiedResult = await Promise.all(result.item.map(async (ele) => {
|
||||
const news_item = await Promise.all(ele.content.news_item.map(async (ele2) => {
|
||||
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
|
||||
return {
|
||||
...ele2,
|
||||
coverUrl
|
||||
};
|
||||
}));
|
||||
return {
|
||||
...ele,
|
||||
content: {
|
||||
...ele.content,
|
||||
news_item
|
||||
}
|
||||
};
|
||||
}));
|
||||
this.setState({
|
||||
materials: modifiedResult,
|
||||
total: result.total_count,
|
||||
});
|
||||
}
|
||||
else {
|
||||
result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId, type: type, offset: 0, count: 10 });
|
||||
this.setState({
|
||||
materials: result.item,
|
||||
total: result.total_count,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getMaterialList(page) {
|
||||
const { applicationId } = this.props;
|
||||
const { type } = this.props;
|
||||
const offset = (page - 1) * 10;
|
||||
const result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId, type: type, offset, count: 10 });
|
||||
this.setState({
|
||||
materials: result.item,
|
||||
total: result.total_count,
|
||||
});
|
||||
},
|
||||
async getArticleList(page) {
|
||||
const { applicationId } = this.props;
|
||||
const offset = (page - 1) * 10;
|
||||
const result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId, offset, count: 10, noContent: 0 });
|
||||
const modifiedResult = await Promise.all(result.item.map(async (ele) => {
|
||||
const news_item = await Promise.all(ele.content.news_item.map(async (ele2) => {
|
||||
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
|
||||
return {
|
||||
...ele2,
|
||||
coverUrl
|
||||
};
|
||||
}));
|
||||
return {
|
||||
...ele,
|
||||
content: {
|
||||
...ele.content,
|
||||
news_item
|
||||
}
|
||||
};
|
||||
}));
|
||||
this.setState({
|
||||
materials: modifiedResult,
|
||||
total: result.total_count,
|
||||
});
|
||||
},
|
||||
async upload(media, description) {
|
||||
const { applicationId } = this.props;
|
||||
const { type } = this.props;
|
||||
console.log(media);
|
||||
const result = await this.features.wechatMenu.createMaterial({ applicationId: applicationId, type: type, media, description });
|
||||
if (result && result.media_id) {
|
||||
this.setMessage({
|
||||
type: 'success',
|
||||
content: '上传成功',
|
||||
});
|
||||
this.getMaterialList(1);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
async getMaterialImg(media_id) {
|
||||
const { applicationId } = this.props;
|
||||
const imgFile = await this.features.wechatMenu.getMaterial({ applicationId: applicationId, type: 'image', media_id });
|
||||
return new Promise((resolve) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(imgFile);
|
||||
reader.onload = function (e) {
|
||||
resolve(e.target?.result);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.upload {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
margin: 20px 0 0 0;
|
||||
.help {
|
||||
color: #B1B2B3;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.list {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { EntityDict } from "../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, true, {
|
||||
type: string;
|
||||
materials: any[];
|
||||
total: number;
|
||||
getMenuContent: (menuContent: any) => void;
|
||||
}, {
|
||||
getMaterialList: (page: number) => void;
|
||||
getArticleList: (page: number) => void;
|
||||
upload: (media: FormData, description?: FormData) => boolean;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const antd_1 = require("antd");
|
||||
const { TextArea } = antd_1.Input;
|
||||
const icons_1 = require("@ant-design/icons");
|
||||
const web_module_less_1 = tslib_1.__importDefault(require("./web.module.less"));
|
||||
const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
||||
const showNews_1 = tslib_1.__importDefault(require("../wechatMenu/showNews"));
|
||||
function Render(props) {
|
||||
const { type, materials, total, getMenuContent } = props.data;
|
||||
const { getMaterialList, setMessage, upload, getArticleList } = props.methods;
|
||||
const [currentPage, setCurrentPage] = (0, react_1.useState)(1);
|
||||
const [upsertOpen, setUpsertOpen] = (0, react_1.useState)(false);
|
||||
const [title, setTitle] = (0, react_1.useState)('');
|
||||
const [introduction, setIntroduction] = (0, react_1.useState)('');
|
||||
const [fileList, setFileList] = (0, react_1.useState)([]);
|
||||
const [video, setVideo] = (0, react_1.useState)(new FormData);
|
||||
const checkFileType = (filename) => {
|
||||
const fileExtension = filename?.split('.')?.pop()?.toLowerCase();
|
||||
let allowedExtensions = [];
|
||||
if (type === 'image') {
|
||||
allowedExtensions = ['bmp', 'png', 'jpeg', 'jpg', 'gif'];
|
||||
}
|
||||
else if (type === 'voice') {
|
||||
allowedExtensions = ['mp3', 'wma', 'wav', 'amr'];
|
||||
}
|
||||
else {
|
||||
allowedExtensions = ['mp4'];
|
||||
}
|
||||
if (allowedExtensions.includes(fileExtension)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
setMessage({
|
||||
content: '文件类型错误',
|
||||
type: 'error'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const uploadFile = async (file) => {
|
||||
if (checkFileType(file.name)) {
|
||||
const formData = new FormData();
|
||||
formData.append('media', file);
|
||||
console.log(file);
|
||||
upload(formData);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
};
|
||||
const fileChange = (info) => {
|
||||
setFileList(info.fileList);
|
||||
};
|
||||
const uploadVideo = async (file) => {
|
||||
if (checkFileType(file.name)) {
|
||||
const formData = new FormData();
|
||||
formData.append('media', file);
|
||||
setVideo(formData);
|
||||
const updataFileList = fileList.map((ele) => {
|
||||
return {
|
||||
...ele,
|
||||
status: 'done'
|
||||
};
|
||||
});
|
||||
fileChange({ fileList: updataFileList });
|
||||
}
|
||||
else {
|
||||
const updataFileList = fileList.map((ele) => {
|
||||
return {
|
||||
...ele,
|
||||
status: 'error'
|
||||
};
|
||||
});
|
||||
fileChange({ fileList: updataFileList });
|
||||
}
|
||||
};
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (!open) {
|
||||
setTitle('');
|
||||
setIntroduction('');
|
||||
setFileList([]);
|
||||
}
|
||||
}, [open]);
|
||||
const columns = [
|
||||
{
|
||||
dataIndex: 'serial-number',
|
||||
title: '序号',
|
||||
render: (value, record, index) => {
|
||||
return index + 1;
|
||||
},
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: '名称',
|
||||
},
|
||||
{
|
||||
dataIndex: 'update_time',
|
||||
title: '更新时间',
|
||||
render: (value, record, index) => {
|
||||
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, dayjs_1.default)(value).format('YYYY-MM-DD HH:mm') });
|
||||
}
|
||||
},
|
||||
];
|
||||
const newsColumns = [
|
||||
{
|
||||
dataIndex: 'serial-number',
|
||||
title: '序号',
|
||||
render: (value, record, index) => {
|
||||
return index + 1;
|
||||
},
|
||||
width: 100
|
||||
},
|
||||
{
|
||||
dataIndex: 'coverImg',
|
||||
title: '封面图',
|
||||
render: (value, record, index) => {
|
||||
return ((0, jsx_runtime_1.jsx)("div", { children: record.content.news_item.map((ele) => ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)("img", { style: { width: 100 }, src: ele.coverUrl }) }))) }));
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'title',
|
||||
title: '图文消息标题',
|
||||
render: (value, record, index) => {
|
||||
return ((0, jsx_runtime_1.jsx)("div", { children: record.content.news_item.map((ele) => ((0, jsx_runtime_1.jsx)("div", { children: ele.title }))) }));
|
||||
}
|
||||
},
|
||||
{
|
||||
// dataIndex: 'author',
|
||||
title: '作者',
|
||||
render: (value, record, index) => {
|
||||
return ((0, jsx_runtime_1.jsx)("div", { children: record.content.news_item.map((ele) => ((0, jsx_runtime_1.jsx)("div", { children: ele.author }))) }));
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'digest',
|
||||
title: '图文信息摘要',
|
||||
render: (value, record, index) => {
|
||||
return ((0, jsx_runtime_1.jsx)("div", { children: record.content.news_item.map((ele) => ((0, jsx_runtime_1.jsx)("div", { children: ele.digest }))) }));
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'update_time',
|
||||
title: '更新时间',
|
||||
render: (value, record, index) => {
|
||||
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, dayjs_1.default)(value).format('YYYY-MM-DD HH:mm') });
|
||||
}
|
||||
},
|
||||
{
|
||||
dataIndex: 'op',
|
||||
title: '操作',
|
||||
render: (value, record, index) => {
|
||||
return (0, jsx_runtime_1.jsx)(antd_1.Popover, { content: (0, jsx_runtime_1.jsx)("div", { style: { padding: 12 }, children: (0, jsx_runtime_1.jsx)(showNews_1.default, { oakAutoUnmount: true, news: record.content.news_item }) }), children: (0, jsx_runtime_1.jsx)("div", { style: { cursor: 'pointer', color: '#1677ff' }, children: "\u9884\u89C8" }) });
|
||||
}
|
||||
}
|
||||
];
|
||||
if (type === 'image') {
|
||||
columns.splice(1, 0, {
|
||||
dataIndex: 'url',
|
||||
title: '图片',
|
||||
render: (value, record, index) => {
|
||||
return (0, jsx_runtime_1.jsx)("img", { style: { width: 120, height: 70 }, src: value });
|
||||
},
|
||||
});
|
||||
}
|
||||
else if (type === 'voice') {
|
||||
columns.splice(1, 0, {
|
||||
dataIndex: 'url',
|
||||
title: '音频',
|
||||
render: (value, record, index) => {
|
||||
return (0, jsx_runtime_1.jsxs)("a", { href: value, download: true, style: { color: '#1677FF', cursor: 'pointer' }, children: [(0, jsx_runtime_1.jsx)(icons_1.DownloadOutlined, {}), record.media_id] });
|
||||
},
|
||||
});
|
||||
}
|
||||
else if (type === 'video') {
|
||||
columns.splice(1, 0, {
|
||||
dataIndex: 'url',
|
||||
title: '视频',
|
||||
render: (value, record, index) => {
|
||||
return (0, jsx_runtime_1.jsxs)("a", { href: value, download: true, style: { color: '#1677FF', cursor: 'pointer' }, children: [(0, jsx_runtime_1.jsx)(icons_1.DownloadOutlined, {}), record.media_id] });
|
||||
},
|
||||
});
|
||||
}
|
||||
else {
|
||||
}
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.container, children: [(0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.title, children: type === 'news' ? '选择图文' : type === 'image' ? '选择图片' : type === 'voice' ? '插入音频' : '选择视频' }), type !== 'news' && (0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.upload, children: [(0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.help, children: type === 'image' ? '大小不超过10M' : type === 'voice' ? '由于版本兼容的原因,你暂时只可以选择60秒内的音频发送' : null }), type === 'video' ? ((0, jsx_runtime_1.jsx)(antd_1.Button, { onClick: () => {
|
||||
setUpsertOpen(true);
|
||||
}, children: "\u4E0A\u4F20\u89C6\u9891" })) : ((0, jsx_runtime_1.jsx)(antd_1.Upload, { maxCount: 1, showUploadList: false, customRequest: ({ file }) => {
|
||||
uploadFile(file);
|
||||
}, children: (0, jsx_runtime_1.jsxs)(antd_1.Button, { children: ["\u4E0A\u4F20", type === 'image' ? '图片' : '音频'] }) })), (0, jsx_runtime_1.jsx)(antd_1.Modal, { open: upsertOpen, onCancel: () => setUpsertOpen(false), title: '上传视频', footer: (0, jsx_runtime_1.jsxs)(antd_1.Space, { children: [(0, jsx_runtime_1.jsx)(antd_1.Button, { type: 'primary', onClick: () => {
|
||||
if (title.length === 0) {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: '标题不能为空'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (introduction.length === 0) {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: '视频介绍不能为空'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (fileList.length === 0 || fileList[0].status === 'error') {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: '请上传视频文件'
|
||||
});
|
||||
return;
|
||||
}
|
||||
const formData = new FormData;
|
||||
const descriptionData = {
|
||||
title,
|
||||
introduction,
|
||||
};
|
||||
formData.append('description', JSON.stringify(descriptionData));
|
||||
if (upload(video, formData)) {
|
||||
setUpsertOpen(false);
|
||||
}
|
||||
}, children: "\u4E0A\u4F20" }), (0, jsx_runtime_1.jsx)(antd_1.Button, { onClick: () => setUpsertOpen(false), children: "\u53D6\u6D88" })] }), children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(antd_1.Form.Item, { label: (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.label, children: "\u6807\u9898" }), required: true, labelAlign: 'right', labelCol: { span: 4 }, children: (0, jsx_runtime_1.jsx)(antd_1.Input, { showCount: true, maxLength: 20, value: title, onChange: (val) => setTitle(val.target.value) }) }), (0, jsx_runtime_1.jsx)(antd_1.Form.Item, { label: (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.label, children: "\u89C6\u9891\u4ECB\u7ECD" }), required: true, children: (0, jsx_runtime_1.jsx)(TextArea, { showCount: true, maxLength: 300, value: introduction, autoSize: { minRows: 5 }, onChange: (val) => setIntroduction(val.target.value) }) }), (0, jsx_runtime_1.jsx)(antd_1.Form.Item, { label: (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.label, children: "\u4E0A\u4F20\u89C6\u9891" }), required: true, children: (0, jsx_runtime_1.jsx)(antd_1.Upload, { customRequest: ({ file }) => uploadVideo(file), maxCount: 1, onChange: fileChange, fileList: fileList, children: (0, jsx_runtime_1.jsxs)(antd_1.Button, { children: [(0, jsx_runtime_1.jsx)(icons_1.DownloadOutlined, {}), fileList.length > 0 ? '重新' : '', "\u4E0A\u4F20"] }) }) })] }) })] }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.list, children: (0, jsx_runtime_1.jsx)(antd_1.Table, { rowKey: type === 'news' ? 'article_id' : 'media_id', dataSource: materials, columns: type === 'news' ? newsColumns : columns, pagination: {
|
||||
total: total,
|
||||
pageSize: 10,
|
||||
current: currentPage,
|
||||
onChange: (page, pageSize) => {
|
||||
setCurrentPage(page);
|
||||
if (type === 'news') {
|
||||
getArticleList(page);
|
||||
}
|
||||
else {
|
||||
getMaterialList(page);
|
||||
}
|
||||
},
|
||||
}, rowSelection: {
|
||||
type: 'radio',
|
||||
onSelect: (record) => {
|
||||
if (type === 'news') {
|
||||
getMenuContent(record);
|
||||
}
|
||||
else {
|
||||
getMenuContent(record);
|
||||
}
|
||||
},
|
||||
} }) })] }));
|
||||
}
|
||||
exports.default = Render;
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
id: string;
|
||||
config: any;
|
||||
menuIndex: number;
|
||||
changeConfig: (config: any) => void;
|
||||
menuType: string;
|
||||
getSelectedBtn: (selectedBtn: number) => void;
|
||||
getSelectedSubBtn: (selectedSubBtn: number) => void;
|
||||
getCurrentIndex: (currentIndex: number) => void;
|
||||
errorIndex: number[];
|
||||
isPreview: boolean;
|
||||
open: boolean;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = OakComponent({
|
||||
isList: false,
|
||||
properties: {
|
||||
id: '',
|
||||
config: null,
|
||||
menuIndex: 0,
|
||||
changeConfig: (config) => undefined,
|
||||
menuType: '',
|
||||
getSelectedBtn: (selectedBtn) => undefined,
|
||||
getSelectedSubBtn: (selectedSubBtn) => undefined,
|
||||
getCurrentIndex: (currentIndex) => undefined,
|
||||
errorIndex: [],
|
||||
isPreview: false,
|
||||
open: false,
|
||||
},
|
||||
data: {},
|
||||
methods: {
|
||||
deleteMenuItem(index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
config.button.splice(index, 1);
|
||||
changeConfig(config);
|
||||
this.setMessage({
|
||||
content: '操作成功',
|
||||
type: 'success'
|
||||
});
|
||||
},
|
||||
toRight(index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
config.button = [
|
||||
...config.button.slice(0, index - 1),
|
||||
config.button[index],
|
||||
config.button[index - 1],
|
||||
...config.button.slice(index + 1)
|
||||
];
|
||||
changeConfig(config);
|
||||
},
|
||||
toLeft(index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
config.button = [
|
||||
...config.button.slice(0, index - 2),
|
||||
config.button[index - 1],
|
||||
config.button[index - 2],
|
||||
...config.button.slice(index)
|
||||
];
|
||||
changeConfig(config);
|
||||
},
|
||||
toUp(currentIndex, index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
let menu = config.button[currentIndex];
|
||||
const subMenu = [
|
||||
...menu.sub_button.slice(0, index - 2),
|
||||
menu.sub_button[index - 1],
|
||||
menu.sub_button[index - 2],
|
||||
...menu.sub_button.slice(index)
|
||||
];
|
||||
config.button[currentIndex].sub_button = subMenu;
|
||||
changeConfig(config);
|
||||
},
|
||||
toDown(currentIndex, index) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
let menu = config.button[currentIndex];
|
||||
const subMenu = [
|
||||
...menu.sub_button.slice(0, index - 1),
|
||||
menu.sub_button[index],
|
||||
menu.sub_button[index - 1],
|
||||
...menu.sub_button.slice(index + 1)
|
||||
];
|
||||
config.button[currentIndex].sub_button = subMenu;
|
||||
changeConfig(config);
|
||||
},
|
||||
deleteSubMenuItem(index, currentIndex) {
|
||||
const { config, changeConfig, menuIndex, menuType } = this.props;
|
||||
config.button[currentIndex].sub_button.splice(index, 1);
|
||||
changeConfig(config);
|
||||
this.setMessage({
|
||||
content: '操作成功',
|
||||
type: 'success'
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
.container {
|
||||
width: 100%;
|
||||
.phone {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
background: #fcfcfc;
|
||||
border-radius: 8px;
|
||||
|
||||
.topBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
margin: 8px 16px 10px 16px;
|
||||
align-items: center;
|
||||
|
||||
.time {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.actionBar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.page {
|
||||
height: 412px;
|
||||
}
|
||||
|
||||
.bottomBar {
|
||||
height: 68px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background: #fcfcfc;
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-top: 1px solid #EDEEEF;
|
||||
|
||||
.keyBoard {
|
||||
width: 60px;
|
||||
|
||||
}
|
||||
|
||||
.menu {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
cursor: pointer;
|
||||
|
||||
.buttonGroup {
|
||||
top: 73px;
|
||||
position: absolute;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 48px;
|
||||
min-width: 48px;
|
||||
border-radius: 24px;
|
||||
background: #fcfcfc;
|
||||
font-size: 24px;
|
||||
padding: 5px;
|
||||
box-shadow: 0 1px 6px #e4e8eb;
|
||||
|
||||
.buttonItem {
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
.buttonItem:hover {
|
||||
background: #EDEEEF;
|
||||
}
|
||||
}
|
||||
|
||||
.menuItem {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 68px;
|
||||
width: 80px;
|
||||
position: relative;
|
||||
|
||||
.menuName {
|
||||
width: 100%;
|
||||
height: 33px;
|
||||
border-left: 1px solid #EDEEEF;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.button2 {
|
||||
margin: 17px 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-left: 1px solid #EDEEEF;
|
||||
color: #4C4D4E;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border: 1px dashed #1677FF;
|
||||
font-size: 14px;
|
||||
color: #1677FF;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.ant-popover-inner {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
.subMenuContent {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
.subButtonGroup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 48px;
|
||||
min-height: 48px;
|
||||
border-radius: 24px;
|
||||
background: #fcfcfc;
|
||||
font-size: 24px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
left: 90px;
|
||||
box-shadow: 0 1px 6px #e4e8eb;
|
||||
|
||||
.buttonItem {
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
.buttonItem:hover {
|
||||
background: #EDEEEF;
|
||||
}
|
||||
}
|
||||
}
|
||||
.subMenuItem {
|
||||
width: 86px;
|
||||
height: 49px;
|
||||
text-align: center;
|
||||
padding: 12px 2px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-bottom: 1px solid #EDEEEF;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { WechatPublicInstance } from 'oak-external-sdk';
|
||||
import { EntityDict } from "../../../oak-app-domain";
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
export default function Render(props: WebComponentProps<EntityDict, keyof EntityDict, false, {
|
||||
config: any;
|
||||
menuIndex: number;
|
||||
file: File;
|
||||
wechatInstance: WechatPublicInstance;
|
||||
errorIndex: number[];
|
||||
menuType: string;
|
||||
changeConfig: (config: any) => void;
|
||||
getSelectedBtn: (selectedBtn: number) => void;
|
||||
getSelectedSubBtn: (selectedSubBtn: number) => void;
|
||||
getCurrentIndex: (currentIndex: number) => void;
|
||||
isPreview: boolean;
|
||||
open: boolean;
|
||||
}, {
|
||||
setConfig: (index: number, content: any, currentIndex?: number) => void;
|
||||
deleteMenuItem: (index: number) => void;
|
||||
deleteSubMenuItem: (index: number, currentIndex: number) => void;
|
||||
toRight: (index: number) => void;
|
||||
toLeft: (index: number) => void;
|
||||
toUp: (currentIndex: number, index: number) => void;
|
||||
toDown: (currentIndex: number, index: number) => void;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue