feat: 完成工具菜单所有功能
- 后端ToolController实现6个工具API - 前端创建6个工具页面 - 修改pages.json注册页面 - 修改api.js添加工具API - 修改tools.vue添加跳转逻辑
This commit is contained in:
1 parent
c85c819008
commit
e021ce5bc9
10 files changed
+2292
-14
No files matched your search
@@ -0,0 +1,402 @@
|
||||
package xuan.controller;
|
||||
|
||||
import com.nlf.calendar.Lunar;
|
||||
import com.nlf.calendar.Solar;
|
||||
import com.nlf.calendar.LunarYear;
|
||||
import com.nlf.calendar.LunarMonth;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import xuan.core.bazi.BaZi;
|
||||
import xuan.core.bazi.settings.BaZiJiChuSetting;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/tools")
|
||||
public class ToolController {
|
||||
|
||||
@PostMapping("/lunar")
|
||||
public Map<String, Object> lunarQuery(@RequestBody Map<String, Object> params) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
String date = params.get("date").toString();
|
||||
int type = params.containsKey("type") ? Integer.parseInt(params.get("type").toString()) : 0;
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
|
||||
if (type == 0) {
|
||||
Solar solar = Solar.fromYmdHms(
|
||||
Integer.parseInt(date.substring(0, 4)),
|
||||
Integer.parseInt(date.substring(5, 7)),
|
||||
Integer.parseInt(date.substring(8, 10)),
|
||||
params.containsKey("hour") ? Integer.parseInt(params.get("hour").toString()) : 0,
|
||||
params.containsKey("minute") ? Integer.parseInt(params.get("minute").toString()) : 0,
|
||||
0
|
||||
);
|
||||
Lunar lunar = solar.getLunar();
|
||||
|
||||
data.put("solar", solar.toString());
|
||||
data.put("lunar", lunar.toString());
|
||||
data.put("lunarYear", lunar.getYearInGanZhi());
|
||||
data.put("lunarMonth", lunar.getMonthInGanZhi());
|
||||
data.put("lunarDay", lunar.getDayInGanZhi());
|
||||
data.put("lunarYearName", lunar.getYearShengXiao() + "年");
|
||||
data.put("lunarMonthName", lunar.getMonthName());
|
||||
data.put("lunarDayName", lunar.getDayName());
|
||||
data.put("festival", lunar.getFestivals());
|
||||
data.put("jieQi", lunar.getJieQi());
|
||||
data.put("week", solar.getWeekInChinese());
|
||||
data.put("constellation", solar.getXingZuo());
|
||||
} else {
|
||||
int year = Integer.parseInt(params.get("lunarYear").toString());
|
||||
int month = Integer.parseInt(params.get("lunarMonth").toString());
|
||||
int day = Integer.parseInt(params.get("lunarDay").toString());
|
||||
boolean isLeap = params.containsKey("isLeap") && Boolean.parseBoolean(params.get("isLeap").toString());
|
||||
|
||||
Lunar lunar = Lunar.fromYmd(year, month, day, isLeap ? 1 : 0);
|
||||
Solar solar = lunar.getSolar();
|
||||
|
||||
data.put("lunar", lunar.toString());
|
||||
data.put("solar", solar.toString());
|
||||
data.put("solarYear", solar.getYear());
|
||||
data.put("solarMonth", solar.getMonth());
|
||||
data.put("solarDay", solar.getDay());
|
||||
}
|
||||
|
||||
result.put("success", true);
|
||||
result.put("data", data);
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("error", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/ganzhi")
|
||||
public Map<String, Object> ganZhiQuery(@RequestBody Map<String, Object> params) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
String date = params.get("date").toString();
|
||||
int hour = params.containsKey("hour") ? Integer.parseInt(params.get("hour").toString()) : 0;
|
||||
|
||||
Solar solar = Solar.fromYmdHms(
|
||||
Integer.parseInt(date.substring(0, 4)),
|
||||
Integer.parseInt(date.substring(5, 7)),
|
||||
Integer.parseInt(date.substring(8, 10)),
|
||||
hour, 0, 0
|
||||
);
|
||||
Lunar lunar = solar.getLunar();
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("yearGanZhi", lunar.getYearInGanZhi());
|
||||
data.put("monthGanZhi", lunar.getMonthInGanZhi());
|
||||
data.put("dayGanZhi", lunar.getDayInGanZhi());
|
||||
data.put("hourGanZhi", lunar.getTimeInGanZhi());
|
||||
data.put("yearGan", lunar.getYearGan());
|
||||
data.put("yearZhi", lunar.getYearZhi());
|
||||
data.put("monthGan", lunar.getMonthGan());
|
||||
data.put("monthZhi", lunar.getMonthZhi());
|
||||
data.put("dayGan", lunar.getDayGan());
|
||||
data.put("dayZhi", lunar.getDayZhi());
|
||||
data.put("hourGan", lunar.getTimeGan());
|
||||
data.put("hourZhi", lunar.getTimeZhi());
|
||||
|
||||
result.put("success", true);
|
||||
result.put("data", data);
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("error", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/shengxiao")
|
||||
public Map<String, Object> shengXiaoQuery(@RequestBody Map<String, Object> params) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
int year = Integer.parseInt(params.get("year").toString());
|
||||
|
||||
Solar solar = Solar.fromYmd(year, 1, 1);
|
||||
Lunar lunar = solar.getLunar();
|
||||
String shengXiao = lunar.getYearShengXiao();
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("year", year);
|
||||
data.put("shengXiao", shengXiao);
|
||||
|
||||
String[] shengXiaoOrder = {"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
|
||||
Map<String, String> shengXiaoInfo = new HashMap<>();
|
||||
shengXiaoInfo.put("鼠", "子鼠,五行属水,聪明机智,适应力强");
|
||||
shengXiaoInfo.put("牛", "丑牛,五行属土,勤劳踏实,责任心强");
|
||||
shengXiaoInfo.put("虎", "寅虎,五行属木,勇敢自信,领导力强");
|
||||
shengXiaoInfo.put("兔", "卯兔,五行属木,温柔善良,心思细腻");
|
||||
shengXiaoInfo.put("龙", "辰龙,五行属土,气宇轩昂,有远大理想");
|
||||
shengXiaoInfo.put("蛇", "巳蛇,五行属火,智慧深沉,洞察力强");
|
||||
shengXiaoInfo.put("马", "午马,五行属火,热情奔放,行动力强");
|
||||
shengXiaoInfo.put("羊", "未羊,五行属土,温文尔雅,富有同情心");
|
||||
shengXiaoInfo.put("猴", "申猴,五行属金,聪明伶俐,多才多艺");
|
||||
shengXiaoInfo.put("鸡", "酉鸡,五行属金,精明能干,善于表达");
|
||||
shengXiaoInfo.put("狗", "戌狗,五行属土,忠诚可靠,正义感强");
|
||||
shengXiaoInfo.put("猪", "亥猪,五行属水,善良宽厚,乐观豁达");
|
||||
|
||||
data.put("info", shengXiaoInfo.getOrDefault(shengXiao, "未知生肖"));
|
||||
|
||||
String ganZhi = lunar.getYearInGanZhi();
|
||||
data.put("ganZhi", ganZhi);
|
||||
|
||||
result.put("success", true);
|
||||
result.put("data", data);
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("error", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/xingzuo")
|
||||
public Map<String, Object> xingZuoQuery(@RequestBody Map<String, Object> params) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
int month = Integer.parseInt(params.get("month").toString());
|
||||
int day = Integer.parseInt(params.get("day").toString());
|
||||
|
||||
Solar solar = Solar.fromYmd(2000, month, day);
|
||||
String xingZuo = solar.getXingZuo();
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("month", month);
|
||||
data.put("day", day);
|
||||
data.put("xingZuo", xingZuo);
|
||||
|
||||
Map<String, Map<String, String>> xingZuoInfo = new HashMap<>();
|
||||
xingZuoInfo.put("白羊座", Map.of(
|
||||
"dateRange", "3月21日-4月19日",
|
||||
"element", "火象星座",
|
||||
"character", "热情、冲动、自信",
|
||||
"desc", "白羊座是黄道十二宫的第一宫,代表着新的开始和生命力。白羊座的人充满活力,勇于冒险,具有领导才能。"
|
||||
));
|
||||
xingZuoInfo.put("金牛座", Map.of(
|
||||
"dateRange", "4月20日-5月20日",
|
||||
"element", "土象星座",
|
||||
"character", "稳重、务实、固执",
|
||||
"desc", "金牛座是黄道十二宫的第二宫,代表着物质和财富。金牛座的人踏实可靠,追求稳定,有很强的耐心。"
|
||||
));
|
||||
xingZuoInfo.put("双子座", Map.of(
|
||||
"dateRange", "5月21日-6月21日",
|
||||
"element", "风象星座",
|
||||
"character", "聪明、善变、好奇",
|
||||
"desc", "双子座是黄道十二宫的第三宫,代表着沟通和交流。双子座的人思维敏捷,善于表达,兴趣广泛。"
|
||||
));
|
||||
xingZuoInfo.put("巨蟹座", Map.of(
|
||||
"dateRange", "6月22日-7月22日",
|
||||
"element", "水象星座",
|
||||
"character", "敏感、顾家、情绪化",
|
||||
"desc", "巨蟹座是黄道十二宫的第四宫,代表着家庭和情感。巨蟹座的人重视家庭,情感丰富,有很强的保护欲。"
|
||||
));
|
||||
xingZuoInfo.put("狮子座", Map.of(
|
||||
"dateRange", "7月23日-8月22日",
|
||||
"element", "火象星座",
|
||||
"character", "自信、慷慨、霸道",
|
||||
"desc", "狮子座是黄道十二宫的第五宫,代表着创造力和自我表达。狮子座的人自信大方,有领导才能,喜欢成为焦点。"
|
||||
));
|
||||
xingZuoInfo.put("处女座", Map.of(
|
||||
"dateRange", "8月23日-9月22日",
|
||||
"element", "土象星座",
|
||||
"character", "细心、完美主义、挑剔",
|
||||
"desc", "处女座是黄道十二宫的第六宫,代表着分析和服务。处女座的人注重细节,追求完美,有很强的分析能力。"
|
||||
));
|
||||
xingZuoInfo.put("天秤座", Map.of(
|
||||
"dateRange", "9月23日-10月23日",
|
||||
"element", "风象星座",
|
||||
"character", "优雅、公正、犹豫",
|
||||
"desc", "天秤座是黄道十二宫的第七宫,代表着平衡和和谐。天秤座的人追求公正,善于社交,有很强的审美能力。"
|
||||
));
|
||||
xingZuoInfo.put("天蝎座", Map.of(
|
||||
"dateRange", "10月24日-11月22日",
|
||||
"element", "水象星座",
|
||||
"character", "神秘、执着、多疑",
|
||||
"desc", "天蝎座是黄道十二宫的第八宫,代表着转化和重生。天蝎座的人意志坚定,洞察力强,有很强的直觉。"
|
||||
));
|
||||
xingZuoInfo.put("射手座", Map.of(
|
||||
"dateRange", "11月23日-12月21日",
|
||||
"element", "火象星座",
|
||||
"character", "乐观、自由、粗心",
|
||||
"desc", "射手座是黄道十二宫的第九宫,代表着探索和哲学。射手座的人热爱自由,乐观开朗,有很强的冒险精神。"
|
||||
));
|
||||
xingZuoInfo.put("摩羯座", Map.of(
|
||||
"dateRange", "12月22日-1月19日",
|
||||
"element", "土象星座",
|
||||
"character", "务实、有责任感、悲观",
|
||||
"desc", "摩羯座是黄道十二宫的第十宫,代表着成就和责任。摩羯座的人有很强的责任感,追求成功,脚踏实地。"
|
||||
));
|
||||
xingZuoInfo.put("水瓶座", Map.of(
|
||||
"dateRange", "1月20日-2月18日",
|
||||
"element", "风象星座",
|
||||
"character", "独立、创新、叛逆",
|
||||
"desc", "水瓶座是黄道十二宫的第十一宫,代表着创新和人道主义。水瓶座的人思想前卫,独立自主,有很强的创造力。"
|
||||
));
|
||||
xingZuoInfo.put("双鱼座", Map.of(
|
||||
"dateRange", "2月19日-3月20日",
|
||||
"element", "水象星座",
|
||||
"character", "浪漫、敏感、优柔寡断",
|
||||
"desc", "双鱼座是黄道十二宫的最后一宫,代表着灵性和直觉。双鱼座的人富有想象力,感情丰富,有很强的同理心。"
|
||||
));
|
||||
|
||||
Map<String, String> info = xingZuoInfo.getOrDefault(xingZuo, Map.of("desc", "未知星座"));
|
||||
data.put("dateRange", info.get("dateRange"));
|
||||
data.put("element", info.get("element"));
|
||||
data.put("character", info.get("character"));
|
||||
data.put("desc", info.get("desc"));
|
||||
|
||||
result.put("success", true);
|
||||
result.put("data", data);
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("error", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/wuxing")
|
||||
public Map<String, Object> wuXingQuery(@RequestBody Map<String, Object> params) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
String date = params.get("date").toString();
|
||||
int hour = params.containsKey("hour") ? Integer.parseInt(params.get("hour").toString()) : 0;
|
||||
|
||||
Solar solar = Solar.fromYmdHms(
|
||||
Integer.parseInt(date.substring(0, 4)),
|
||||
Integer.parseInt(date.substring(5, 7)),
|
||||
Integer.parseInt(date.substring(8, 10)),
|
||||
hour, 0, 0
|
||||
);
|
||||
Lunar lunar = solar.getLunar();
|
||||
|
||||
String yearGan = lunar.getYearGan();
|
||||
String monthGan = lunar.getMonthGan();
|
||||
String dayGan = lunar.getDayGan();
|
||||
String hourGan = lunar.getTimeGan();
|
||||
|
||||
Map<String, String> ganWuXing = new HashMap<>();
|
||||
ganWuXing.put("甲", "木"); ganWuXing.put("乙", "木");
|
||||
ganWuXing.put("丙", "火"); ganWuXing.put("丁", "火");
|
||||
ganWuXing.put("戊", "土"); ganWuXing.put("己", "土");
|
||||
ganWuXing.put("庚", "金"); ganWuXing.put("辛", "金");
|
||||
ganWuXing.put("壬", "水"); ganWuXing.put("癸", "水");
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("yearGan", yearGan);
|
||||
data.put("yearWuXing", ganWuXing.get(yearGan));
|
||||
data.put("monthGan", monthGan);
|
||||
data.put("monthWuXing", ganWuXing.get(monthGan));
|
||||
data.put("dayGan", dayGan);
|
||||
data.put("dayWuXing", ganWuXing.get(dayGan));
|
||||
data.put("hourGan", hourGan);
|
||||
data.put("hourWuXing", ganWuXing.get(hourGan));
|
||||
|
||||
Map<String, Integer> wuXingCount = new HashMap<>();
|
||||
wuXingCount.put("金", 0);
|
||||
wuXingCount.put("木", 0);
|
||||
wuXingCount.put("水", 0);
|
||||
wuXingCount.put("火", 0);
|
||||
wuXingCount.put("土", 0);
|
||||
|
||||
for (String gan : Arrays.asList(yearGan, monthGan, dayGan, hourGan)) {
|
||||
String wx = ganWuXing.get(gan);
|
||||
wuXingCount.put(wx, wuXingCount.get(wx) + 1);
|
||||
}
|
||||
|
||||
String[] zhiList = {lunar.getYearZhi(), lunar.getMonthZhi(), lunar.getDayZhi(), lunar.getTimeZhi()};
|
||||
Map<String, String> zhiWuXing = new HashMap<>();
|
||||
zhiWuXing.put("子", "水"); zhiWuXing.put("丑", "土");
|
||||
zhiWuXing.put("寅", "木"); zhiWuXing.put("卯", "木");
|
||||
zhiWuXing.put("辰", "土"); zhiWuXing.put("巳", "火");
|
||||
zhiWuXing.put("午", "火"); zhiWuXing.put("未", "土");
|
||||
zhiWuXing.put("申", "金"); zhiWuXing.put("酉", "金");
|
||||
zhiWuXing.put("戌", "土"); zhiWuXing.put("亥", "水");
|
||||
|
||||
for (String zhi : zhiList) {
|
||||
String wx = zhiWuXing.get(zhi);
|
||||
wuXingCount.put(wx, wuXingCount.get(wx) + 1);
|
||||
}
|
||||
|
||||
data.put("wuXingCount", wuXingCount);
|
||||
|
||||
List<String> missing = new ArrayList<>();
|
||||
for (Map.Entry<String, Integer> entry : wuXingCount.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
missing.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
data.put("missing", missing);
|
||||
|
||||
Map<String, String> wuXingInfo = new HashMap<>();
|
||||
wuXingInfo.put("金", "金主义,其性刚,其情烈。金盛之人骨肉相称,面方白净,眉高眼深。");
|
||||
wuXingInfo.put("木", "木主仁,其性直,其情和。木盛之人丰姿秀丽,骨骼修长,手足细腻。");
|
||||
wuXingInfo.put("水", "水主智,其性聪,其情善。水盛之人面黑有采,语言清和,为人深思熟虑。");
|
||||
wuXingInfo.put("火", "火主礼,其性急,其情恭。火盛之人头小脚长,上尖下阔,浓眉小耳。");
|
||||
wuXingInfo.put("土", "土主信,其性重,其情厚。土盛之人圆腰廓鼻,眉清目秀,口才声重。");
|
||||
|
||||
data.put("wuXingInfo", wuXingInfo);
|
||||
|
||||
result.put("success", true);
|
||||
result.put("data", data);
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("error", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@PostMapping("/jiri")
|
||||
public Map<String, Object> jiRiQuery(@RequestBody Map<String, Object> params) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
String date = params.get("date").toString();
|
||||
|
||||
Solar solar = Solar.fromYmd(
|
||||
Integer.parseInt(date.substring(0, 4)),
|
||||
Integer.parseInt(date.substring(5, 7)),
|
||||
Integer.parseInt(date.substring(8, 10))
|
||||
);
|
||||
Lunar lunar = solar.getLunar();
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("solar", solar.toString());
|
||||
data.put("lunar", lunar.toString());
|
||||
data.put("ganZhi", lunar.getDayInGanZhi());
|
||||
data.put("xingZuo", solar.getXingZuo());
|
||||
data.put("week", solar.getWeekInChinese());
|
||||
|
||||
List<String> yi = lunar.getDayYi();
|
||||
List<String> ji = lunar.getDayJi();
|
||||
data.put("yi", yi);
|
||||
data.put("ji", ji);
|
||||
|
||||
String[] chong = lunar.getDayChong().split(" ");
|
||||
data.put("chong", chong.length > 0 ? chong[0] : "");
|
||||
data.put("chongGan", lunar.getDayChongGan());
|
||||
data.put("chongZhi", lunar.getDayChongZhi());
|
||||
data.put("sha", lunar.getDaySha());
|
||||
|
||||
String jieQi = lunar.getJieQi();
|
||||
data.put("jieQi", jieQi != null ? jieQi : "无");
|
||||
|
||||
List<String> festivals = lunar.getFestivals();
|
||||
data.put("festivals", festivals);
|
||||
|
||||
List<String> solarFestivals = solar.getFestivals();
|
||||
data.put("solarFestivals", solarFestivals);
|
||||
|
||||
boolean isGoodDay = yi.size() > ji.size();
|
||||
data.put("isGoodDay", isGoodDay);
|
||||
data.put("suggestion", isGoodDay ? "今日宜多行善事,适合办理重要事务" : "今日宜静不宜动,适合修身养性");
|
||||
|
||||
result.put("success", true);
|
||||
result.put("data", data);
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("error", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -160,6 +160,54 @@
|
||||
"navigationBarBackgroundColor": "#8B5CF6",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tool-lunar/tool-lunar",
|
||||
"style": {
|
||||
"navigationBarTitleText": "农历查询",
|
||||
"navigationBarBackgroundColor": "#3B82F6",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tool-ganzhi/tool-ganzhi",
|
||||
"style": {
|
||||
"navigationBarTitleText": "干支查询",
|
||||
"navigationBarBackgroundColor": "#10B981",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tool-shengxiao/tool-shengxiao",
|
||||
"style": {
|
||||
"navigationBarTitleText": "生肖查询",
|
||||
"navigationBarBackgroundColor": "#F59E0B",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tool-xingzuo/tool-xingzuo",
|
||||
"style": {
|
||||
"navigationBarTitleText": "星座查询",
|
||||
"navigationBarBackgroundColor": "#8B5CF6",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tool-wuxing/tool-wuxing",
|
||||
"style": {
|
||||
"navigationBarTitleText": "五行查询",
|
||||
"navigationBarBackgroundColor": "#EF4444",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/tool-jiri/tool-jiri",
|
||||
"style": {
|
||||
"navigationBarTitleText": "吉日查询",
|
||||
"navigationBarBackgroundColor": "#EC4899",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="header-card">
|
||||
<text class="header-title">🕐 干支查询</text>
|
||||
<text class="header-subtitle">年月日时干支</text>
|
||||
</view>
|
||||
|
||||
<view class="form-card">
|
||||
<view class="form-item">
|
||||
<text class="form-label">日期</text>
|
||||
<picker mode="date" :value="date" @change="onDateChange">
|
||||
<view class="picker-value">{{ date }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">时辰</text>
|
||||
<picker mode="selector" :range="hours" :value="hourIndex" @change="onHourChange">
|
||||
<view class="picker-value">{{ hours[hourIndex] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<button class="submit-btn" @click="query" :disabled="loading">
|
||||
<text class="btn-text">{{ loading ? '查询中...' : '开始查询' }}</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<view class="result-card" v-if="result">
|
||||
<view class="result-header">
|
||||
<text class="result-title">查询结果</text>
|
||||
</view>
|
||||
<view class="result-content">
|
||||
<view class="result-item">
|
||||
<text class="item-label">年柱</text>
|
||||
<text class="item-value highlight">{{ result.yearGanZhi }}</text>
|
||||
</view>
|
||||
<view class="result-item">
|
||||
<text class="item-label">月柱</text>
|
||||
<text class="item-value highlight">{{ result.monthGanZhi }}</text>
|
||||
</view>
|
||||
<view class="result-item">
|
||||
<text class="item-label">日柱</text>
|
||||
<text class="item-value highlight">{{ result.dayGanZhi }}</text>
|
||||
</view>
|
||||
<view class="result-item">
|
||||
<text class="item-label">时柱</text>
|
||||
<text class="item-value highlight">{{ result.hourGanZhi }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="detail-card">
|
||||
<text class="detail-title">四柱详解</text>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">年干:</text>
|
||||
<text class="detail-value">{{ result.yearGan }} ({{ result.yearGan }}干)</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">年支:</text>
|
||||
<text class="detail-value">{{ result.yearZhi }} ({{ result.yearZhi }}支)</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">月干:</text>
|
||||
<text class="detail-value">{{ result.monthGan }}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">月支:</text>
|
||||
<text class="detail-value">{{ result.monthZhi }}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">日干:</text>
|
||||
<text class="detail-value">{{ result.dayGan }}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">日支:</text>
|
||||
<text class="detail-value">{{ result.dayZhi }}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">时干:</text>
|
||||
<text class="detail-value">{{ result.hourGan }}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">时支:</text>
|
||||
<text class="detail-value">{{ result.hourZhi }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/utils/api.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
date: '2000-01-01',
|
||||
hourIndex: 0,
|
||||
hours: ['子时(23-1点)', '丑时(1-3点)', '寅时(3-5点)', '卯时(5-7点)', '辰时(7-9点)', '巳时(9-11点)', '午时(11-13点)', '未时(13-15点)', '申时(15-17点)', '酉时(17-19点)', '戌时(19-21点)', '亥时(21-23点)'],
|
||||
hourValues: [23, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21],
|
||||
loading: false,
|
||||
result: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onDateChange(e) {
|
||||
this.date = e.detail.value
|
||||
},
|
||||
onHourChange(e) {
|
||||
this.hourIndex = e.detail.value
|
||||
},
|
||||
async query() {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await api.toolApi.ganzhi({
|
||||
date: this.date,
|
||||
hour: this.hourValues[this.hourIndex]
|
||||
})
|
||||
if (res.success) {
|
||||
this.result = res.data
|
||||
} else {
|
||||
uni.showToast({ title: res.error || '查询失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '查询失败', icon: 'none' })
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: linear-gradient(180deg, #ECFDF5 0%, #D1FAE5 50%, #A7F3D0 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.header-card {
|
||||
background: linear-gradient(135deg, #10B981 0%, #059669 100%);
|
||||
border-radius: 32rpx;
|
||||
padding: 48rpx 32rpx;
|
||||
text-align: center;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 16rpx 48rpx rgba(16, 185, 129, 0.25);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(16, 185, 129, 0.08);
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 28rpx;
|
||||
color: #374151;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.picker-value {
|
||||
padding: 24rpx;
|
||||
background: #F9FAFB;
|
||||
border-radius: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, #10B981 0%, #059669 100%);
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
text-align: center;
|
||||
margin-top: 32rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.result-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(16, 185, 129, 0.08);
|
||||
}
|
||||
|
||||
.result-header {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.result-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.result-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1rpx solid #F3F4F6;
|
||||
}
|
||||
|
||||
.item-label {
|
||||
font-size: 28rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.item-value {
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.item-value.highlight {
|
||||
font-size: 36rpx;
|
||||
color: #059669;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
margin-top: 32rpx;
|
||||
padding-top: 24rpx;
|
||||
border-top: 1rpx solid #E5E7EB;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
display: flex;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
width: 100rpx;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 26rpx;
|
||||
color: #1F2937;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,370 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="header-card">
|
||||
<text class="header-title">📆 吉日查询</text>
|
||||
<text class="header-subtitle">黄道吉日查询</text>
|
||||
</view>
|
||||
|
||||
<view class="form-card">
|
||||
<view class="form-item">
|
||||
<text class="form-label">查询日期</text>
|
||||
<picker mode="date" :value="date" @change="onDateChange">
|
||||
<view class="picker-value">{{ date }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<button class="submit-btn" @click="query" :disabled="loading">
|
||||
<text class="btn-text">{{ loading ? '查询中...' : '开始查询' }}</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<view class="result-card" v-if="result">
|
||||
<view class="result-header">
|
||||
<text class="result-title">{{ result.solar }}</text>
|
||||
<text class="result-subtitle">{{ result.lunar }}</text>
|
||||
</view>
|
||||
|
||||
<view class="day-status" :class="{ good: result.isGoodDay }">
|
||||
<text class="status-icon">{{ result.isGoodDay ? '✨' : '🌙' }}</text>
|
||||
<text class="status-text">{{ result.isGoodDay ? '吉日' : '平日' }}</text>
|
||||
</view>
|
||||
|
||||
<view class="info-grid">
|
||||
<view class="info-item">
|
||||
<text class="info-label">干支</text>
|
||||
<text class="info-value">{{ result.ganZhi }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">星期</text>
|
||||
<text class="info-value">{{ result.week }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">星座</text>
|
||||
<text class="info-value">{{ result.xingZuo }}</text>
|
||||
</view>
|
||||
<view class="info-item" v-if="result.jieQi">
|
||||
<text class="info-label">节气</text>
|
||||
<text class="info-value">{{ result.jieQi }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="yi-ji-section">
|
||||
<view class="yi-card">
|
||||
<text class="card-title">宜</text>
|
||||
<view class="tag-list">
|
||||
<text class="tag yi" v-for="(item, index) in result.yi" :key="index">{{ item }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="ji-card">
|
||||
<text class="card-title">忌</text>
|
||||
<view class="tag-list">
|
||||
<text class="tag ji" v-for="(item, index) in result.ji" :key="index">{{ item }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="chong-section">
|
||||
<text class="section-title">冲煞</text>
|
||||
<view class="chong-info">
|
||||
<text class="chong-text">冲{{ result.chong }} ({{ result.chongGan }}{{ result.chongZhi }})</text>
|
||||
<text class="sha-text">煞{{ result.sha }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="festival-section" v-if="result.festivals && result.festivals.length > 0">
|
||||
<text class="section-title">节日</text>
|
||||
<text class="festival-text">{{ result.festivals.join('、') }}</text>
|
||||
</view>
|
||||
|
||||
<view class="suggestion-section">
|
||||
<text class="suggestion-text">{{ result.suggestion }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/utils/api.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
date: new Date().toISOString().split('T')[0],
|
||||
loading: false,
|
||||
result: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onDateChange(e) {
|
||||
this.date = e.detail.value
|
||||
},
|
||||
async query() {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await api.toolApi.jiri({
|
||||
date: this.date
|
||||
})
|
||||
if (res.success) {
|
||||
this.result = res.data
|
||||
} else {
|
||||
uni.showToast({ title: res.error || '查询失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '查询失败', icon: 'none' })
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: linear-gradient(180deg, #FDF2F8 0%, #FCE7F3 50%, #FBCFE8 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.header-card {
|
||||
background: linear-gradient(135deg, #EC4899 0%, #DB2777 100%);
|
||||
border-radius: 32rpx;
|
||||
padding: 48rpx 32rpx;
|
||||
text-align: center;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 16rpx 48rpx rgba(236, 72, 153, 0.25);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(236, 72, 153, 0.08);
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 28rpx;
|
||||
color: #374151;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.picker-value {
|
||||
padding: 24rpx;
|
||||
background: #F9FAFB;
|
||||
border-radius: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, #EC4899 0%, #DB2777 100%);
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
text-align: center;
|
||||
margin-top: 32rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.result-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(236, 72, 153, 0.08);
|
||||
}
|
||||
|
||||
.result-header {
|
||||
text-align: center;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 700;
|
||||
color: #1F2937;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.result-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.day-status {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 24rpx;
|
||||
background: #F3F4F6;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.day-status.good {
|
||||
background: linear-gradient(135deg, #FEF3C7 0%, #FDE68A 100%);
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
font-size: 48rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #92400E;
|
||||
}
|
||||
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 16rpx;
|
||||
background: #F9FAFB;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 26rpx;
|
||||
color: #1F2937;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.yi-ji-section {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.yi-card, .ji-card {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.yi-card {
|
||||
background: #ECFDF5;
|
||||
}
|
||||
|
||||
.ji-card {
|
||||
background: #FEF2F2;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.yi-card .card-title {
|
||||
color: #059669;
|
||||
}
|
||||
|
||||
.ji-card .card-title {
|
||||
color: #DC2626;
|
||||
}
|
||||
|
||||
.tag-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.tag {
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.tag.yi {
|
||||
background: #D1FAE5;
|
||||
color: #065F46;
|
||||
}
|
||||
|
||||
.tag.ji {
|
||||
background: #FECACA;
|
||||
color: #991B1B;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.chong-section, .festival-section {
|
||||
margin-bottom: 24rpx;
|
||||
padding-top: 24rpx;
|
||||
border-top: 1rpx solid #F3F4F6;
|
||||
}
|
||||
|
||||
.chong-info {
|
||||
display: flex;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.chong-text, .sha-text {
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.festival-text {
|
||||
font-size: 26rpx;
|
||||
color: #DB2777;
|
||||
}
|
||||
|
||||
.suggestion-section {
|
||||
padding: 20rpx;
|
||||
background: #FDF2F8;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.suggestion-text {
|
||||
font-size: 26rpx;
|
||||
color: #9D174D;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,338 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="header-card">
|
||||
<text class="header-title">📅 农历查询</text>
|
||||
<text class="header-subtitle">公历农历互转</text>
|
||||
</view>
|
||||
|
||||
<view class="form-card">
|
||||
<view class="form-item">
|
||||
<text class="form-label">查询方式</text>
|
||||
<view class="type-tabs">
|
||||
<view class="type-tab" :class="{ active: queryType === 0 }" @click="queryType = 0">
|
||||
<text>公历转农历</text>
|
||||
</view>
|
||||
<view class="type-tab" :class="{ active: queryType === 1 }" @click="queryType = 1">
|
||||
<text>农历转公历</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="queryType === 0">
|
||||
<view class="form-item">
|
||||
<text class="form-label">公历日期</text>
|
||||
<picker mode="date" :value="solarDate" @change="onDateChange">
|
||||
<view class="picker-value">{{ solarDate }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">时辰</text>
|
||||
<picker mode="selector" :range="hours" :value="hourIndex" @change="onHourChange">
|
||||
<view class="picker-value">{{ hours[hourIndex] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="queryType === 1">
|
||||
<view class="form-item">
|
||||
<text class="form-label">农历年份</text>
|
||||
<picker mode="selector" :range="years" :value="yearIndex" @change="onYearChange">
|
||||
<view class="picker-value">{{ years[yearIndex] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">农历月份</text>
|
||||
<picker mode="selector" :range="months" :value="monthIndex" @change="onMonthChange">
|
||||
<view class="picker-value">{{ months[monthIndex] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">农历日期</text>
|
||||
<picker mode="selector" :range="days" :value="dayIndex" @change="onDayChange">
|
||||
<view class="picker-value">{{ days[dayIndex] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="checkbox-item" @click="isLeap = !isLeap">
|
||||
<view class="checkbox" :class="{ checked: isLeap }"></view>
|
||||
<text class="checkbox-label">闰月</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<button class="submit-btn" @click="query" :disabled="loading">
|
||||
<text class="btn-text">{{ loading ? '查询中...' : '开始查询' }}</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<view class="result-card" v-if="result">
|
||||
<view class="result-header">
|
||||
<text class="result-title">查询结果</text>
|
||||
</view>
|
||||
<view class="result-content">
|
||||
<view class="result-item">
|
||||
<text class="item-label">公历</text>
|
||||
<text class="item-value">{{ result.solar }}</text>
|
||||
</view>
|
||||
<view class="result-item">
|
||||
<text class="item-label">农历</text>
|
||||
<text class="item-value">{{ result.lunar }}</text>
|
||||
</view>
|
||||
<view class="result-item">
|
||||
<text class="item-label">干支</text>
|
||||
<text class="item-value">{{ result.lunarYear }}年 {{ result.lunarMonth }}月 {{ result.lunarDay }}日</text>
|
||||
</view>
|
||||
<view class="result-item">
|
||||
<text class="item-label">生肖</text>
|
||||
<text class="item-value">{{ result.lunarYearName }}</text>
|
||||
</view>
|
||||
<view class="result-item" v-if="result.week">
|
||||
<text class="item-label">星期</text>
|
||||
<text class="item-value">{{ result.week }}</text>
|
||||
</view>
|
||||
<view class="result-item" v-if="result.constellation">
|
||||
<text class="item-label">星座</text>
|
||||
<text class="item-value">{{ result.constellation }}</text>
|
||||
</view>
|
||||
<view class="result-item" v-if="result.jieQi">
|
||||
<text class="item-label">节气</text>
|
||||
<text class="item-value">{{ result.jieQi }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/utils/api.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
queryType: 0,
|
||||
solarDate: '2000-01-01',
|
||||
hourIndex: 0,
|
||||
hours: ['子时(23-1点)', '丑时(1-3点)', '寅时(3-5点)', '卯时(5-7点)', '辰时(7-9点)', '巳时(9-11点)', '午时(11-13点)', '未时(13-15点)', '申时(15-17点)', '酉时(17-19点)', '戌时(19-21点)', '亥时(21-23点)'],
|
||||
hourValues: [23, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21],
|
||||
yearIndex: 50,
|
||||
years: [],
|
||||
monthIndex: 0,
|
||||
months: ['正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '冬月', '腊月'],
|
||||
dayIndex: 0,
|
||||
days: ['初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十'],
|
||||
isLeap: false,
|
||||
loading: false,
|
||||
result: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
for (let i = 1900; i <= 2100; i++) {
|
||||
this.years.push(i + '年')
|
||||
}
|
||||
this.yearIndex = this.years.indexOf(new Date().getFullYear() + '年')
|
||||
},
|
||||
methods: {
|
||||
onDateChange(e) {
|
||||
this.solarDate = e.detail.value
|
||||
},
|
||||
onHourChange(e) {
|
||||
this.hourIndex = e.detail.value
|
||||
},
|
||||
onYearChange(e) {
|
||||
this.yearIndex = e.detail.value
|
||||
},
|
||||
onMonthChange(e) {
|
||||
this.monthIndex = e.detail.value
|
||||
},
|
||||
onDayChange(e) {
|
||||
this.dayIndex = e.detail.value
|
||||
},
|
||||
async query() {
|
||||
this.loading = true
|
||||
try {
|
||||
let params = { type: this.queryType }
|
||||
if (this.queryType === 0) {
|
||||
params.date = this.solarDate
|
||||
params.hour = this.hourValues[this.hourIndex]
|
||||
} else {
|
||||
params.lunarYear = this.years[this.yearIndex].replace('年', '')
|
||||
params.lunarMonth = this.monthIndex + 1
|
||||
params.lunarDay = this.dayIndex + 1
|
||||
params.isLeap = this.isLeap
|
||||
}
|
||||
const res = await api.toolApi.lunar(params)
|
||||
if (res.success) {
|
||||
this.result = res.data
|
||||
} else {
|
||||
uni.showToast({ title: res.error || '查询失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '查询失败', icon: 'none' })
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: linear-gradient(180deg, #EFF6FF 0%, #DBEAFE 50%, #BFDBFE 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.header-card {
|
||||
background: linear-gradient(135deg, #3B82F6 0%, #1D4ED8 100%);
|
||||
border-radius: 32rpx;
|
||||
padding: 48rpx 32rpx;
|
||||
text-align: center;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 16rpx 48rpx rgba(59, 130, 246, 0.25);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(59, 130, 246, 0.08);
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 28rpx;
|
||||
color: #374151;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.type-tabs {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.type-tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 20rpx;
|
||||
background: #F3F4F6;
|
||||
border-radius: 16rpx;
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.type-tab.active {
|
||||
background: linear-gradient(135deg, #3B82F6 0%, #1D4ED8 100%);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.picker-value {
|
||||
padding: 24rpx;
|
||||
background: #F9FAFB;
|
||||
border-radius: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.checkbox-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
border: 4rpx solid #D1D5DB;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.checkbox.checked {
|
||||
background: #3B82F6;
|
||||
border-color: #3B82F6;
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
font-size: 28rpx;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, #3B82F6 0%, #1D4ED8 100%);
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
text-align: center;
|
||||
margin-top: 32rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.result-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(59, 130, 246, 0.08);
|
||||
}
|
||||
|
||||
.result-header {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.result-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.result-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1rpx solid #F3F4F6;
|
||||
}
|
||||
|
||||
.item-label {
|
||||
font-size: 28rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.item-value {
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,219 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="header-card">
|
||||
<text class="header-title">🐉 生肖查询</text>
|
||||
<text class="header-subtitle">十二生肖属性</text>
|
||||
</view>
|
||||
|
||||
<view class="form-card">
|
||||
<view class="form-item">
|
||||
<text class="form-label">出生年份</text>
|
||||
<picker mode="selector" :range="years" :value="yearIndex" @change="onYearChange">
|
||||
<view class="picker-value">{{ years[yearIndex] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<button class="submit-btn" @click="query" :disabled="loading">
|
||||
<text class="btn-text">{{ loading ? '查询中...' : '开始查询' }}</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<view class="result-card" v-if="result">
|
||||
<view class="result-header">
|
||||
<text class="result-title">查询结果</text>
|
||||
</view>
|
||||
<view class="result-content">
|
||||
<view class="shengxiao-display">
|
||||
<text class="shengxiao-icon">{{ getShengXiaoIcon(result.shengXiao) }}</text>
|
||||
<text class="shengxiao-name">{{ result.shengXiao }}</text>
|
||||
<text class="shengxiao-ganzhi">{{ result.ganZhi }}年</text>
|
||||
</view>
|
||||
|
||||
<view class="info-card">
|
||||
<text class="info-text">{{ result.info }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/utils/api.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
yearIndex: 50,
|
||||
years: [],
|
||||
loading: false,
|
||||
result: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
for (let i = 1900; i <= 2100; i++) {
|
||||
this.years.push(i + '年')
|
||||
}
|
||||
this.yearIndex = this.years.indexOf(new Date().getFullYear() + '年')
|
||||
},
|
||||
methods: {
|
||||
onYearChange(e) {
|
||||
this.yearIndex = e.detail.value
|
||||
},
|
||||
getShengXiaoIcon(name) {
|
||||
const icons = {
|
||||
'鼠': '🐭', '牛': '🐮', '虎': '🐯', '兔': '🐰',
|
||||
'龙': '🐲', '蛇': '🐍', '马': '🐴', '羊': '🐑',
|
||||
'猴': '🐵', '鸡': '🐔', '狗': '🐶', '猪': '🐷'
|
||||
}
|
||||
return icons[name] || '🐉'
|
||||
},
|
||||
async query() {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await api.toolApi.shengxiao({
|
||||
year: this.years[this.yearIndex].replace('年', '')
|
||||
})
|
||||
if (res.success) {
|
||||
this.result = res.data
|
||||
} else {
|
||||
uni.showToast({ title: res.error || '查询失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '查询失败', icon: 'none' })
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: linear-gradient(180deg, #FFFBEB 0%, #FEF3C7 50%, #FDE68A 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.header-card {
|
||||
background: linear-gradient(135deg, #F59E0B 0%, #D97706 100%);
|
||||
border-radius: 32rpx;
|
||||
padding: 48rpx 32rpx;
|
||||
text-align: center;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 16rpx 48rpx rgba(245, 158, 11, 0.25);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(245, 158, 11, 0.08);
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 28rpx;
|
||||
color: #374151;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.picker-value {
|
||||
padding: 24rpx;
|
||||
background: #F9FAFB;
|
||||
border-radius: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, #F59E0B 0%, #D97706 100%);
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
text-align: center;
|
||||
margin-top: 32rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.result-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(245, 158, 11, 0.08);
|
||||
}
|
||||
|
||||
.result-header {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.shengxiao-display {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
|
||||
.shengxiao-icon {
|
||||
font-size: 120rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.shengxiao-name {
|
||||
font-size: 48rpx;
|
||||
font-weight: 700;
|
||||
color: #D97706;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.shengxiao-ganzhi {
|
||||
font-size: 28rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
background: #FFFBEB;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
font-size: 26rpx;
|
||||
color: #92400E;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,312 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="header-card">
|
||||
<text class="header-title">🔥 五行查询</text>
|
||||
<text class="header-subtitle">五行属性分析</text>
|
||||
</view>
|
||||
|
||||
<view class="form-card">
|
||||
<view class="form-item">
|
||||
<text class="form-label">出生日期</text>
|
||||
<picker mode="date" :value="date" @change="onDateChange">
|
||||
<view class="picker-value">{{ date }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">出生时辰</text>
|
||||
<picker mode="selector" :range="hours" :value="hourIndex" @change="onHourChange">
|
||||
<view class="picker-value">{{ hours[hourIndex] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<button class="submit-btn" @click="query" :disabled="loading">
|
||||
<text class="btn-text">{{ loading ? '查询中...' : '开始查询' }}</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<view class="result-card" v-if="result">
|
||||
<view class="result-header">
|
||||
<text class="result-title">五行分析</text>
|
||||
</view>
|
||||
|
||||
<view class="wuxing-chart">
|
||||
<view class="wuxing-item" v-for="(count, name) in result.wuXingCount" :key="name">
|
||||
<view class="wuxing-bar" :style="{ height: (count * 20) + 'rpx', background: getWuXingColor(name) }"></view>
|
||||
<text class="wuxing-name">{{ name }}</text>
|
||||
<text class="wuxing-count">{{ count }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="detail-section">
|
||||
<text class="section-title">四柱五行</text>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">年柱:</text>
|
||||
<text class="detail-value">{{ result.yearGan }}({{ result.yearWuXing }})</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">月柱:</text>
|
||||
<text class="detail-value">{{ result.monthGan }}({{ result.monthWuXing }})</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">日柱:</text>
|
||||
<text class="detail-value">{{ result.dayGan }}({{ result.dayWuXing }})</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">时柱:</text>
|
||||
<text class="detail-value">{{ result.hourGan }}({{ result.hourWuXing }})</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="missing-section" v-if="result.missing && result.missing.length > 0">
|
||||
<text class="section-title">五行缺失</text>
|
||||
<view class="missing-tags">
|
||||
<text class="missing-tag" v-for="item in result.missing" :key="item" :style="{ background: getWuXingColor(item) }">{{ item }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="info-section">
|
||||
<text class="section-title">五行释义</text>
|
||||
<view class="info-item" v-for="(info, name) in result.wuXingInfo" :key="name">
|
||||
<text class="info-name" :style="{ color: getWuXingColor(name) }">{{ name }}</text>
|
||||
<text class="info-desc">{{ info }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/utils/api.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
date: '2000-01-01',
|
||||
hourIndex: 0,
|
||||
hours: ['子时(23-1点)', '丑时(1-3点)', '寅时(3-5点)', '卯时(5-7点)', '辰时(7-9点)', '巳时(9-11点)', '午时(11-13点)', '未时(13-15点)', '申时(15-17点)', '酉时(17-19点)', '戌时(19-21点)', '亥时(21-23点)'],
|
||||
hourValues: [23, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21],
|
||||
loading: false,
|
||||
result: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onDateChange(e) {
|
||||
this.date = e.detail.value
|
||||
},
|
||||
onHourChange(e) {
|
||||
this.hourIndex = e.detail.value
|
||||
},
|
||||
getWuXingColor(name) {
|
||||
const colors = {
|
||||
'金': 'linear-gradient(135deg, #F59E0B 0%, #D97706 100%)',
|
||||
'木': 'linear-gradient(135deg, #10B981 0%, #059669 100%)',
|
||||
'水': 'linear-gradient(135deg, #3B82F6 0%, #1D4ED8 100%)',
|
||||
'火': 'linear-gradient(135deg, #EF4444 0%, #DC2626 100%)',
|
||||
'土': 'linear-gradient(135deg, #A78BFA 0%, #7C3AED 100%)'
|
||||
}
|
||||
return colors[name] || '#6B7280'
|
||||
},
|
||||
async query() {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await api.toolApi.wuxing({
|
||||
date: this.date,
|
||||
hour: this.hourValues[this.hourIndex]
|
||||
})
|
||||
if (res.success) {
|
||||
this.result = res.data
|
||||
} else {
|
||||
uni.showToast({ title: res.error || '查询失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '查询失败', icon: 'none' })
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: linear-gradient(180deg, #FEF2F2 0%, #FECACA 50%, #FCA5A5 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.header-card {
|
||||
background: linear-gradient(135deg, #EF4444 0%, #DC2626 100%);
|
||||
border-radius: 32rpx;
|
||||
padding: 48rpx 32rpx;
|
||||
text-align: center;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 16rpx 48rpx rgba(239, 68, 68, 0.25);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(239, 68, 68, 0.08);
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 28rpx;
|
||||
color: #374151;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.picker-value {
|
||||
padding: 24rpx;
|
||||
background: #F9FAFB;
|
||||
border-radius: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, #EF4444 0%, #DC2626 100%);
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
text-align: center;
|
||||
margin-top: 32rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.result-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(239, 68, 68, 0.08);
|
||||
}
|
||||
|
||||
.result-header {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.wuxing-chart {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: flex-end;
|
||||
height: 200rpx;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #F3F4F6;
|
||||
}
|
||||
|
||||
.wuxing-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.wuxing-bar {
|
||||
width: 40rpx;
|
||||
border-radius: 8rpx 8rpx 0 0;
|
||||
min-height: 20rpx;
|
||||
}
|
||||
|
||||
.wuxing-name {
|
||||
font-size: 24rpx;
|
||||
color: #6B7280;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.wuxing-count {
|
||||
font-size: 20rpx;
|
||||
color: #9CA3AF;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.detail-section, .missing-section, .info-section {
|
||||
margin-top: 24rpx;
|
||||
padding-top: 24rpx;
|
||||
border-top: 1rpx solid #F3F4F6;
|
||||
}
|
||||
|
||||
.detail-item {
|
||||
display: flex;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 26rpx;
|
||||
color: #6B7280;
|
||||
width: 100rpx;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 26rpx;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.missing-tags {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.missing-tag {
|
||||
padding: 8rpx 24rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 26rpx;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.info-name {
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.info-desc {
|
||||
font-size: 24rpx;
|
||||
color: #6B7280;
|
||||
line-height: 1.5;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="header-card">
|
||||
<text class="header-title">⭐ 星座查询</text>
|
||||
<text class="header-subtitle">十二星座运势</text>
|
||||
</view>
|
||||
|
||||
<view class="form-card">
|
||||
<view class="form-item">
|
||||
<text class="form-label">出生月份</text>
|
||||
<picker mode="selector" :range="months" :value="monthIndex" @change="onMonthChange">
|
||||
<view class="picker-value">{{ months[monthIndex] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">出生日期</text>
|
||||
<picker mode="selector" :range="days" :value="dayIndex" @change="onDayChange">
|
||||
<view class="picker-value">{{ days[dayIndex] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<button class="submit-btn" @click="query" :disabled="loading">
|
||||
<text class="btn-text">{{ loading ? '查询中...' : '开始查询' }}</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<view class="result-card" v-if="result">
|
||||
<view class="result-header">
|
||||
<text class="result-title">查询结果</text>
|
||||
</view>
|
||||
<view class="result-content">
|
||||
<view class="xingzuo-display">
|
||||
<text class="xingzuo-icon">{{ getXingZuoIcon(result.xingZuo) }}</text>
|
||||
<text class="xingzuo-name">{{ result.xingZuo }}</text>
|
||||
<text class="xingzuo-date">{{ result.dateRange }}</text>
|
||||
</view>
|
||||
|
||||
<view class="info-list">
|
||||
<view class="info-item">
|
||||
<text class="info-label">元素</text>
|
||||
<text class="info-value">{{ result.element }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="info-label">性格</text>
|
||||
<text class="info-value">{{ result.character }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="desc-card">
|
||||
<text class="desc-text">{{ result.desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/utils/api.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
monthIndex: 0,
|
||||
months: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
|
||||
dayIndex: 0,
|
||||
days: [],
|
||||
loading: false,
|
||||
result: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
for (let i = 1; i <= 31; i++) {
|
||||
this.days.push(i + '日')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onMonthChange(e) {
|
||||
this.monthIndex = e.detail.value
|
||||
},
|
||||
onDayChange(e) {
|
||||
this.dayIndex = e.detail.value
|
||||
},
|
||||
getXingZuoIcon(name) {
|
||||
const icons = {
|
||||
'白羊座': '♈', '金牛座': '♉', '双子座': '♊', '巨蟹座': '♋',
|
||||
'狮子座': '♌', '处女座': '♍', '天秤座': '♎', '天蝎座': '♏',
|
||||
'射手座': '♐', '摩羯座': '♑', '水瓶座': '♒', '双鱼座': '♓'
|
||||
}
|
||||
return icons[name] || '⭐'
|
||||
},
|
||||
async query() {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await api.toolApi.xingzuo({
|
||||
month: this.monthIndex + 1,
|
||||
day: this.dayIndex + 1
|
||||
})
|
||||
if (res.success) {
|
||||
this.result = res.data
|
||||
} else {
|
||||
uni.showToast({ title: res.error || '查询失败', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '查询失败', icon: 'none' })
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
page {
|
||||
background: linear-gradient(180deg, #F5F3FF 0%, #EDE9FE 50%, #DDD6FE 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.header-card {
|
||||
background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
|
||||
border-radius: 32rpx;
|
||||
padding: 48rpx 32rpx;
|
||||
text-align: center;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 16rpx 48rpx rgba(139, 92, 246, 0.25);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 44rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
display: block;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
font-size: 26rpx;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
margin-bottom: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(139, 92, 246, 0.08);
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 28rpx;
|
||||
color: #374151;
|
||||
font-weight: 500;
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.picker-value {
|
||||
padding: 24rpx;
|
||||
background: #F9FAFB;
|
||||
border-radius: 16rpx;
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background: linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%);
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
text-align: center;
|
||||
margin-top: 32rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.result-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 32rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(139, 92, 246, 0.08);
|
||||
}
|
||||
|
||||
.result-header {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.xingzuo-display {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
|
||||
.xingzuo-icon {
|
||||
font-size: 120rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.xingzuo-name {
|
||||
font-size: 48rpx;
|
||||
font-weight: 700;
|
||||
color: #7C3AED;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.xingzuo-date {
|
||||
font-size: 28rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.info-list {
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1rpx solid #F3F4F6;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 28rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 28rpx;
|
||||
color: #1F2937;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.desc-card {
|
||||
background: #F5F3FF;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
margin-top: 24rpx;
|
||||
}
|
||||
|
||||
.desc-text {
|
||||
font-size: 26rpx;
|
||||
color: #5B21B6;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
||||
@@ -37,20 +37,19 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
tools: [
|
||||
{ name: '农历查询', desc: '公历农历互转', icon: '📅', color: 'linear-gradient(135deg, #3B82F6 0%, #1D4ED8 100%)' },
|
||||
{ name: '干支查询', desc: '年月日时干支', icon: '🕐', color: 'linear-gradient(135deg, #10B981 0%, #059669 100%)' },
|
||||
{ name: '生肖查询', desc: '十二生肖属性', icon: '🐉', color: 'linear-gradient(135deg, #F59E0B 0%, #D97706 100%)' },
|
||||
{ name: '星座查询', desc: '十二星座运势', icon: '⭐', color: 'linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%)' },
|
||||
{ name: '五行查询', desc: '五行属性分析', icon: '🔥', color: 'linear-gradient(135deg, #EF4444 0%, #DC2626 100%)' },
|
||||
{ name: '吉日查询', desc: '黄道吉日查询', icon: '📆', color: 'linear-gradient(135deg, #EC4899 0%, #DB2777 100%)' }
|
||||
{ name: '农历查询', desc: '公历农历互转', icon: '📅', color: 'linear-gradient(135deg, #3B82F6 0%, #1D4ED8 100%)', path: '/pages/tool-lunar/tool-lunar' },
|
||||
{ name: '干支查询', desc: '年月日时干支', icon: '🕐', color: 'linear-gradient(135deg, #10B981 0%, #059669 100%)', path: '/pages/tool-ganzhi/tool-ganzhi' },
|
||||
{ name: '生肖查询', desc: '十二生肖属性', icon: '🐉', color: 'linear-gradient(135deg, #F59E0B 0%, #D97706 100%)', path: '/pages/tool-shengxiao/tool-shengxiao' },
|
||||
{ name: '星座查询', desc: '十二星座运势', icon: '⭐', color: 'linear-gradient(135deg, #8B5CF6 0%, #7C3AED 100%)', path: '/pages/tool-xingzuo/tool-xingzuo' },
|
||||
{ name: '五行查询', desc: '五行属性分析', icon: '🔥', color: 'linear-gradient(135deg, #EF4444 0%, #DC2626 100%)', path: '/pages/tool-wuxing/tool-wuxing' },
|
||||
{ name: '吉日查询', desc: '黄道吉日查询', icon: '📆', color: 'linear-gradient(135deg, #EC4899 0%, #DB2777 100%)', path: '/pages/tool-jiri/tool-jiri' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openTool(item) {
|
||||
uni.showToast({
|
||||
title: `${item.name}功能开发中`,
|
||||
icon: 'none'
|
||||
uni.navigateTo({
|
||||
url: item.path
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,11 +13,7 @@ const request = (options) => {
|
||||
timeout: 30000,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
if (res.data.success) {
|
||||
resolve(res.data.data)
|
||||
} else {
|
||||
reject(new Error(res.data.error || '请求失败'))
|
||||
}
|
||||
resolve(res.data)
|
||||
} else {
|
||||
reject(new Error('网络请求失败: ' + res.statusCode))
|
||||
}
|
||||
@@ -35,6 +31,7 @@ const baziApi = {
|
||||
url: '/bazi/paipan',
|
||||
method: 'POST',
|
||||
data: {
|
||||
userId: data.userId || 'default_user',
|
||||
name: data.name || '某人',
|
||||
sex: data.sex || 1,
|
||||
date: data.date,
|
||||
@@ -224,6 +221,51 @@ const recordApi = {
|
||||
}
|
||||
}
|
||||
|
||||
const toolApi = {
|
||||
lunar: (data) => {
|
||||
return request({
|
||||
url: '/tools/lunar',
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
ganzhi: (data) => {
|
||||
return request({
|
||||
url: '/tools/ganzhi',
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
shengxiao: (data) => {
|
||||
return request({
|
||||
url: '/tools/shengxiao',
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
xingzuo: (data) => {
|
||||
return request({
|
||||
url: '/tools/xingzuo',
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
wuxing: (data) => {
|
||||
return request({
|
||||
url: '/tools/wuxing',
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
jiri: (data) => {
|
||||
return request({
|
||||
url: '/tools/jiri',
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
baziApi,
|
||||
liuyaoApi,
|
||||
@@ -233,5 +275,6 @@ export default {
|
||||
zhanxingApi,
|
||||
taLuoApi,
|
||||
recordApi,
|
||||
toolApi,
|
||||
request
|
||||
}
|
||||
Reference in new issue
Block a user