1
0
mirror of synced 2025-11-06 04:20:53 +08:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Copilot
1d08953fce Merge 968a4a453f into db85c0ab8a 2025-10-06 18:05:00 +00:00
copilot-swe-agent[bot]
968a4a453f Add convenience methods for Tips control with clickable links
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
2025-09-24 15:31:59 +00:00
copilot-swe-agent[bot]
028074cf5b Detailed analysis of Tips control link support
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
2025-09-24 15:25:27 +00:00
copilot-swe-agent[bot]
087c85c738 Initial plan 2025-09-24 15:13:22 +00:00
3 changed files with 287 additions and 0 deletions

View File

@@ -6,6 +6,8 @@ import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -126,6 +128,74 @@ public class ContentValue implements Serializable {
@SerializedName("tips_content")
private List<TipsContent> tipsContent;
/**
* Creates a simple Tips control with mixed plain text and clickable links.
*
* @param lang the language code (e.g., "zh_CN")
* @param textAndLinks array of objects where strings become plain text and Link objects become clickable links
* @return NewTips instance with the specified content
*/
public static NewTips of(String lang, Object... textAndLinks) {
NewTips tips = new NewTips();
TipsContent content = new TipsContent();
TipsContent.Text text = new TipsContent.Text();
List<TipsContent.SubText> subTexts = new ArrayList<>();
for (Object item : textAndLinks) {
TipsContent.SubText subText = new TipsContent.SubText();
TipsContent.SubText.Content subContent = new TipsContent.SubText.Content();
if (item instanceof String) {
// Plain text
TipsContent.SubText.Content.PlainText plainText = new TipsContent.SubText.Content.PlainText();
plainText.setContent((String) item);
subContent.setPlainText(plainText);
subText.setType(1);
} else if (item instanceof TipsContent.SubText.Content.Link) {
// Link
subContent.setLink((TipsContent.SubText.Content.Link) item);
subText.setType(2);
}
subText.setContent(subContent);
subTexts.add(subText);
}
text.setSubText(subTexts);
content.setText(text);
content.setLang(lang);
tips.setTipsContent(Arrays.asList(content));
return tips;
}
/**
* Creates a simple Tips control with only plain text.
*
* @param lang the language code (e.g., "zh_CN")
* @param textContent the plain text content
* @return NewTips instance with plain text content
*/
public static NewTips ofText(String lang, String textContent) {
return of(lang, textContent);
}
/**
* Creates a Tips control with a single clickable link.
*
* @param lang the language code (e.g., "zh_CN")
* @param linkTitle the display text for the link
* @param linkUrl the URL to link to
* @return NewTips instance with a single clickable link
*/
public static NewTips ofLink(String lang, String linkTitle, String linkUrl) {
TipsContent.SubText.Content.Link link = new TipsContent.SubText.Content.Link();
link.setTitle(linkTitle);
link.setUrl(linkUrl);
return of(lang, link);
}
/**
* The type tips_content.
*/

View File

@@ -0,0 +1,124 @@
package me.chanjar.weixin.cp.bean.oa.applydata;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.testng.annotations.Test;
import java.util.Arrays;
import static org.testng.Assert.*;
public class ContentValueTipsTest {
@Test
public void testTipsWithLinksManualCreation() {
System.out.println("Testing ContentValue.NewTips structure with Link (manual creation):");
// Create a Tips structure with both plain text and link
ContentValue.NewTips tips = new ContentValue.NewTips();
ContentValue.NewTips.TipsContent tipsContent = new ContentValue.NewTips.TipsContent();
ContentValue.NewTips.TipsContent.Text text = new ContentValue.NewTips.TipsContent.Text();
// Create plain text subtext
ContentValue.NewTips.TipsContent.SubText plainSubText = new ContentValue.NewTips.TipsContent.SubText();
ContentValue.NewTips.TipsContent.SubText.Content plainContent = new ContentValue.NewTips.TipsContent.SubText.Content();
ContentValue.NewTips.TipsContent.SubText.Content.PlainText plainTextContent =
new ContentValue.NewTips.TipsContent.SubText.Content.PlainText();
plainTextContent.setContent("This is plain text. For more info, ");
plainContent.setPlainText(plainTextContent);
plainSubText.setType(1); // Type 1 for plain text
plainSubText.setContent(plainContent);
// Create link subtext
ContentValue.NewTips.TipsContent.SubText linkSubText = new ContentValue.NewTips.TipsContent.SubText();
ContentValue.NewTips.TipsContent.SubText.Content linkContent = new ContentValue.NewTips.TipsContent.SubText.Content();
ContentValue.NewTips.TipsContent.SubText.Content.Link link =
new ContentValue.NewTips.TipsContent.SubText.Content.Link();
link.setTitle("click here");
link.setUrl("https://work.weixin.qq.com");
linkContent.setLink(link);
linkSubText.setType(2); // Type 2 for link
linkSubText.setContent(linkContent);
text.setSubText(Arrays.asList(plainSubText, linkSubText));
tipsContent.setText(text);
tipsContent.setLang("zh_CN");
tips.setTipsContent(Arrays.asList(tipsContent));
// Convert to JSON
String json = WxCpGsonBuilder.create().toJson(tips);
System.out.println("Generated JSON:");
System.out.println(json);
// Try to parse it back
validateTipsStructure(tips, json);
}
@Test
public void testTipsWithConvenienceMethods() {
System.out.println("Testing ContentValue.NewTips with convenience methods:");
// Test 1: Simple plain text
ContentValue.NewTips textOnly = ContentValue.NewTips.ofText("zh_CN", "This is a simple text tip.");
String textJson = WxCpGsonBuilder.create().toJson(textOnly);
System.out.println("Text-only JSON: " + textJson);
validateTipsStructure(textOnly, textJson);
// Test 2: Single link
ContentValue.NewTips linkOnly = ContentValue.NewTips.ofLink("zh_CN", "Visit WeChat Work", "https://work.weixin.qq.com");
String linkJson = WxCpGsonBuilder.create().toJson(linkOnly);
System.out.println("Link-only JSON: " + linkJson);
validateTipsStructure(linkOnly, linkJson);
// Test 3: Mixed content using convenience method
ContentValue.NewTips.TipsContent.SubText.Content.Link link =
new ContentValue.NewTips.TipsContent.SubText.Content.Link();
link.setTitle("click here");
link.setUrl("https://work.weixin.qq.com");
ContentValue.NewTips mixed = ContentValue.NewTips.of("zh_CN",
"For more information, ", link, " or contact support.");
String mixedJson = WxCpGsonBuilder.create().toJson(mixed);
System.out.println("Mixed content JSON: " + mixedJson);
validateTipsStructure(mixed, mixedJson);
System.out.println("All convenience method tests passed!");
}
private void validateTipsStructure(ContentValue.NewTips tips, String json) {
try {
ContentValue.NewTips parsedTips = WxCpGsonBuilder.create().fromJson(json, ContentValue.NewTips.class);
assertNotNull(parsedTips);
assertNotNull(parsedTips.getTipsContent());
assertFalse(parsedTips.getTipsContent().isEmpty());
ContentValue.NewTips.TipsContent.Text parsedText = parsedTips.getTipsContent().get(0).getText();
assertNotNull(parsedText);
assertNotNull(parsedText.getSubText());
assertTrue(parsedText.getSubText().size() > 0);
// Verify structure based on content
for (ContentValue.NewTips.TipsContent.SubText subText : parsedText.getSubText()) {
assertNotNull(subText.getType());
assertNotNull(subText.getContent());
if (subText.getType() == 1) {
// Plain text
assertNotNull(subText.getContent().getPlainText());
assertNotNull(subText.getContent().getPlainText().getContent());
} else if (subText.getType() == 2) {
// Link
assertNotNull(subText.getContent().getLink());
assertNotNull(subText.getContent().getLink().getTitle());
assertNotNull(subText.getContent().getLink().getUrl());
}
}
System.out.println("✓ JSON parsing and validation successful");
} catch (Exception e) {
System.out.println("✗ Error parsing: " + e.getMessage());
e.printStackTrace();
fail("Failed to parse JSON: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,93 @@
package me.chanjar.weixin.cp.bean.oa.applydata;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
/**
* Usage examples for ContentValue.NewTips with clickable link support.
*
* This example demonstrates how to create Tips controls that can render URLs as clickable links,
* addressing the issue where "Tips控件无法将url渲染为可点击的链接".
*
* @author WxJava Community
*/
public class TipsUsageExample {
public static void main(String[] args) {
demonstrateBasicUsage();
demonstrateAdvancedUsage();
}
/**
* Basic usage examples for creating Tips with clickable links.
*/
public static void demonstrateBasicUsage() {
System.out.println("=== Basic Tips Usage Examples ===\n");
// Example 1: Simple plain text tip
ContentValue.NewTips textTip = ContentValue.NewTips.ofText("zh_CN",
"这是一个简单的文本提示。");
System.out.println("1. Plain text tip JSON:");
System.out.println(WxCpGsonBuilder.create().toJson(textTip));
System.out.println();
// Example 2: Simple clickable link tip
ContentValue.NewTips linkTip = ContentValue.NewTips.ofLink("zh_CN",
"访问企业微信官网", "https://work.weixin.qq.com");
System.out.println("2. Single link tip JSON:");
System.out.println(WxCpGsonBuilder.create().toJson(linkTip));
System.out.println();
// Example 3: Mixed content - text with clickable link
ContentValue.NewTips.TipsContent.SubText.Content.Link helpLink =
new ContentValue.NewTips.TipsContent.SubText.Content.Link();
helpLink.setTitle("点击查看详情");
helpLink.setUrl("https://work.weixin.qq.com/help");
ContentValue.NewTips mixedTip = ContentValue.NewTips.of("zh_CN",
"如需了解更多信息,请", helpLink, "");
System.out.println("3. Mixed content tip JSON:");
System.out.println(WxCpGsonBuilder.create().toJson(mixedTip));
System.out.println();
}
/**
* Advanced usage examples showing complex Tips with multiple links and text.
*/
public static void demonstrateAdvancedUsage() {
System.out.println("=== Advanced Tips Usage Examples ===\n");
// Example 4: Complex tip with multiple links
ContentValue.NewTips.TipsContent.SubText.Content.Link docsLink =
new ContentValue.NewTips.TipsContent.SubText.Content.Link();
docsLink.setTitle("开发文档");
docsLink.setUrl("https://developer.work.weixin.qq.com");
ContentValue.NewTips.TipsContent.SubText.Content.Link supportLink =
new ContentValue.NewTips.TipsContent.SubText.Content.Link();
supportLink.setTitle("技术支持");
supportLink.setUrl("https://work.weixin.qq.com/contact");
ContentValue.NewTips complexTip = ContentValue.NewTips.of("zh_CN",
"审批流程说明:\n1. 提交申请后系统将自动处理\n2. 如有疑问请查看",
docsLink,
"或联系",
supportLink);
System.out.println("4. Complex tip with multiple links JSON:");
System.out.println(WxCpGsonBuilder.create().toJson(complexTip));
System.out.println();
// Demonstrate that the structure supports proper type differentiation
System.out.println("=== Type Verification ===");
ContentValue.NewTips parsed = WxCpGsonBuilder.create().fromJson(
WxCpGsonBuilder.create().toJson(complexTip), ContentValue.NewTips.class);
parsed.getTipsContent().get(0).getText().getSubText().forEach(subText -> {
if (subText.getType() == 1) {
System.out.println("Plain text: \"" + subText.getContent().getPlainText().getContent() + "\"");
} else if (subText.getType() == 2) {
System.out.println("Link: \"" + subText.getContent().getLink().getTitle() +
"\" -> " + subText.getContent().getLink().getUrl());
}
});
}
}