Skip to content

Commit 968a4a4

Browse files
Copilotbinarywang
andcommitted
Add convenience methods for Tips control with clickable links
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
1 parent 028074c commit 968a4a4

File tree

4 files changed

+221
-84
lines changed

4 files changed

+221
-84
lines changed

TipsLinkTest.java

Lines changed: 0 additions & 69 deletions
This file was deleted.

weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import java.io.Serializable;
88
import java.math.BigDecimal;
9+
import java.util.ArrayList;
10+
import java.util.Arrays;
911
import java.util.List;
1012

1113
/**
@@ -126,6 +128,74 @@ public static class NewTips implements Serializable {
126128
@SerializedName("tips_content")
127129
private List<TipsContent> tipsContent;
128130

131+
/**
132+
* Creates a simple Tips control with mixed plain text and clickable links.
133+
*
134+
* @param lang the language code (e.g., "zh_CN")
135+
* @param textAndLinks array of objects where strings become plain text and Link objects become clickable links
136+
* @return NewTips instance with the specified content
137+
*/
138+
public static NewTips of(String lang, Object... textAndLinks) {
139+
NewTips tips = new NewTips();
140+
TipsContent content = new TipsContent();
141+
TipsContent.Text text = new TipsContent.Text();
142+
143+
List<TipsContent.SubText> subTexts = new ArrayList<>();
144+
145+
for (Object item : textAndLinks) {
146+
TipsContent.SubText subText = new TipsContent.SubText();
147+
TipsContent.SubText.Content subContent = new TipsContent.SubText.Content();
148+
149+
if (item instanceof String) {
150+
// Plain text
151+
TipsContent.SubText.Content.PlainText plainText = new TipsContent.SubText.Content.PlainText();
152+
plainText.setContent((String) item);
153+
subContent.setPlainText(plainText);
154+
subText.setType(1);
155+
} else if (item instanceof TipsContent.SubText.Content.Link) {
156+
// Link
157+
subContent.setLink((TipsContent.SubText.Content.Link) item);
158+
subText.setType(2);
159+
}
160+
161+
subText.setContent(subContent);
162+
subTexts.add(subText);
163+
}
164+
165+
text.setSubText(subTexts);
166+
content.setText(text);
167+
content.setLang(lang);
168+
tips.setTipsContent(Arrays.asList(content));
169+
170+
return tips;
171+
}
172+
173+
/**
174+
* Creates a simple Tips control with only plain text.
175+
*
176+
* @param lang the language code (e.g., "zh_CN")
177+
* @param textContent the plain text content
178+
* @return NewTips instance with plain text content
179+
*/
180+
public static NewTips ofText(String lang, String textContent) {
181+
return of(lang, textContent);
182+
}
183+
184+
/**
185+
* Creates a Tips control with a single clickable link.
186+
*
187+
* @param lang the language code (e.g., "zh_CN")
188+
* @param linkTitle the display text for the link
189+
* @param linkUrl the URL to link to
190+
* @return NewTips instance with a single clickable link
191+
*/
192+
public static NewTips ofLink(String lang, String linkTitle, String linkUrl) {
193+
TipsContent.SubText.Content.Link link = new TipsContent.SubText.Content.Link();
194+
link.setTitle(linkTitle);
195+
link.setUrl(linkUrl);
196+
return of(lang, link);
197+
}
198+
129199
/**
130200
* The type tips_content.
131201
*/

weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValueTipsTest.java

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
public class ContentValueTipsTest {
1111

1212
@Test
13-
public void testTipsWithLinks() {
14-
System.out.println("Testing ContentValue.NewTips structure with Link:");
13+
public void testTipsWithLinksManualCreation() {
14+
System.out.println("Testing ContentValue.NewTips structure with Link (manual creation):");
1515

1616
// Create a Tips structure with both plain text and link
1717
ContentValue.NewTips tips = new ContentValue.NewTips();
@@ -51,6 +51,41 @@ public void testTipsWithLinks() {
5151
System.out.println(json);
5252

5353
// Try to parse it back
54+
validateTipsStructure(tips, json);
55+
}
56+
57+
@Test
58+
public void testTipsWithConvenienceMethods() {
59+
System.out.println("Testing ContentValue.NewTips with convenience methods:");
60+
61+
// Test 1: Simple plain text
62+
ContentValue.NewTips textOnly = ContentValue.NewTips.ofText("zh_CN", "This is a simple text tip.");
63+
String textJson = WxCpGsonBuilder.create().toJson(textOnly);
64+
System.out.println("Text-only JSON: " + textJson);
65+
validateTipsStructure(textOnly, textJson);
66+
67+
// Test 2: Single link
68+
ContentValue.NewTips linkOnly = ContentValue.NewTips.ofLink("zh_CN", "Visit WeChat Work", "https://work.weixin.qq.com");
69+
String linkJson = WxCpGsonBuilder.create().toJson(linkOnly);
70+
System.out.println("Link-only JSON: " + linkJson);
71+
validateTipsStructure(linkOnly, linkJson);
72+
73+
// Test 3: Mixed content using convenience method
74+
ContentValue.NewTips.TipsContent.SubText.Content.Link link =
75+
new ContentValue.NewTips.TipsContent.SubText.Content.Link();
76+
link.setTitle("click here");
77+
link.setUrl("https://work.weixin.qq.com");
78+
79+
ContentValue.NewTips mixed = ContentValue.NewTips.of("zh_CN",
80+
"For more information, ", link, " or contact support.");
81+
String mixedJson = WxCpGsonBuilder.create().toJson(mixed);
82+
System.out.println("Mixed content JSON: " + mixedJson);
83+
validateTipsStructure(mixed, mixedJson);
84+
85+
System.out.println("All convenience method tests passed!");
86+
}
87+
88+
private void validateTipsStructure(ContentValue.NewTips tips, String json) {
5489
try {
5590
ContentValue.NewTips parsedTips = WxCpGsonBuilder.create().fromJson(json, ContentValue.NewTips.class);
5691
assertNotNull(parsedTips);
@@ -60,20 +95,28 @@ public void testTipsWithLinks() {
6095
ContentValue.NewTips.TipsContent.Text parsedText = parsedTips.getTipsContent().get(0).getText();
6196
assertNotNull(parsedText);
6297
assertNotNull(parsedText.getSubText());
63-
assertEquals(parsedText.getSubText().size(), 2);
64-
65-
// Verify plain text
66-
assertEquals(parsedText.getSubText().get(0).getType().intValue(), 1);
67-
assertEquals(parsedText.getSubText().get(0).getContent().getPlainText().getContent(), "This is plain text. For more info, ");
68-
69-
// Verify link
70-
assertEquals(parsedText.getSubText().get(1).getType().intValue(), 2);
71-
assertEquals(parsedText.getSubText().get(1).getContent().getLink().getTitle(), "click here");
72-
assertEquals(parsedText.getSubText().get(1).getContent().getLink().getUrl(), "https://work.weixin.qq.com");
73-
74-
System.out.println("Test passed successfully!");
98+
assertTrue(parsedText.getSubText().size() > 0);
99+
100+
// Verify structure based on content
101+
for (ContentValue.NewTips.TipsContent.SubText subText : parsedText.getSubText()) {
102+
assertNotNull(subText.getType());
103+
assertNotNull(subText.getContent());
104+
105+
if (subText.getType() == 1) {
106+
// Plain text
107+
assertNotNull(subText.getContent().getPlainText());
108+
assertNotNull(subText.getContent().getPlainText().getContent());
109+
} else if (subText.getType() == 2) {
110+
// Link
111+
assertNotNull(subText.getContent().getLink());
112+
assertNotNull(subText.getContent().getLink().getTitle());
113+
assertNotNull(subText.getContent().getLink().getUrl());
114+
}
115+
}
116+
117+
System.out.println("✓ JSON parsing and validation successful");
75118
} catch (Exception e) {
76-
System.out.println("Error parsing: " + e.getMessage());
119+
System.out.println("Error parsing: " + e.getMessage());
77120
e.printStackTrace();
78121
fail("Failed to parse JSON: " + e.getMessage());
79122
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package me.chanjar.weixin.cp.bean.oa.applydata;
2+
3+
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
4+
5+
/**
6+
* Usage examples for ContentValue.NewTips with clickable link support.
7+
*
8+
* This example demonstrates how to create Tips controls that can render URLs as clickable links,
9+
* addressing the issue where "Tips控件无法将url渲染为可点击的链接".
10+
*
11+
* @author WxJava Community
12+
*/
13+
public class TipsUsageExample {
14+
15+
public static void main(String[] args) {
16+
demonstrateBasicUsage();
17+
demonstrateAdvancedUsage();
18+
}
19+
20+
/**
21+
* Basic usage examples for creating Tips with clickable links.
22+
*/
23+
public static void demonstrateBasicUsage() {
24+
System.out.println("=== Basic Tips Usage Examples ===\n");
25+
26+
// Example 1: Simple plain text tip
27+
ContentValue.NewTips textTip = ContentValue.NewTips.ofText("zh_CN",
28+
"这是一个简单的文本提示。");
29+
System.out.println("1. Plain text tip JSON:");
30+
System.out.println(WxCpGsonBuilder.create().toJson(textTip));
31+
System.out.println();
32+
33+
// Example 2: Simple clickable link tip
34+
ContentValue.NewTips linkTip = ContentValue.NewTips.ofLink("zh_CN",
35+
"访问企业微信官网", "https://work.weixin.qq.com");
36+
System.out.println("2. Single link tip JSON:");
37+
System.out.println(WxCpGsonBuilder.create().toJson(linkTip));
38+
System.out.println();
39+
40+
// Example 3: Mixed content - text with clickable link
41+
ContentValue.NewTips.TipsContent.SubText.Content.Link helpLink =
42+
new ContentValue.NewTips.TipsContent.SubText.Content.Link();
43+
helpLink.setTitle("点击查看详情");
44+
helpLink.setUrl("https://work.weixin.qq.com/help");
45+
46+
ContentValue.NewTips mixedTip = ContentValue.NewTips.of("zh_CN",
47+
"如需了解更多信息,请", helpLink, "。");
48+
System.out.println("3. Mixed content tip JSON:");
49+
System.out.println(WxCpGsonBuilder.create().toJson(mixedTip));
50+
System.out.println();
51+
}
52+
53+
/**
54+
* Advanced usage examples showing complex Tips with multiple links and text.
55+
*/
56+
public static void demonstrateAdvancedUsage() {
57+
System.out.println("=== Advanced Tips Usage Examples ===\n");
58+
59+
// Example 4: Complex tip with multiple links
60+
ContentValue.NewTips.TipsContent.SubText.Content.Link docsLink =
61+
new ContentValue.NewTips.TipsContent.SubText.Content.Link();
62+
docsLink.setTitle("开发文档");
63+
docsLink.setUrl("https://developer.work.weixin.qq.com");
64+
65+
ContentValue.NewTips.TipsContent.SubText.Content.Link supportLink =
66+
new ContentValue.NewTips.TipsContent.SubText.Content.Link();
67+
supportLink.setTitle("技术支持");
68+
supportLink.setUrl("https://work.weixin.qq.com/contact");
69+
70+
ContentValue.NewTips complexTip = ContentValue.NewTips.of("zh_CN",
71+
"审批流程说明:\n1. 提交申请后系统将自动处理\n2. 如有疑问请查看",
72+
docsLink,
73+
"或联系",
74+
supportLink);
75+
System.out.println("4. Complex tip with multiple links JSON:");
76+
System.out.println(WxCpGsonBuilder.create().toJson(complexTip));
77+
System.out.println();
78+
79+
// Demonstrate that the structure supports proper type differentiation
80+
System.out.println("=== Type Verification ===");
81+
ContentValue.NewTips parsed = WxCpGsonBuilder.create().fromJson(
82+
WxCpGsonBuilder.create().toJson(complexTip), ContentValue.NewTips.class);
83+
84+
parsed.getTipsContent().get(0).getText().getSubText().forEach(subText -> {
85+
if (subText.getType() == 1) {
86+
System.out.println("Plain text: \"" + subText.getContent().getPlainText().getContent() + "\"");
87+
} else if (subText.getType() == 2) {
88+
System.out.println("Link: \"" + subText.getContent().getLink().getTitle() +
89+
"\" -> " + subText.getContent().getLink().getUrl());
90+
}
91+
});
92+
}
93+
}

0 commit comments

Comments
 (0)