article.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import { useArticle, useCategory } from "@/modules";
  2. import { css } from "@linaria/core";
  3. import { defineComponent, onMounted, reactive, watch } from "vue";
  4. import { useRoute, useRouter } from "vue-router";
  5. import PageTabs from "./PageTabs";
  6. import { Empty, message } from "ant-design-vue";
  7. export default defineComponent({
  8. setup() {
  9. const route = useRoute();
  10. const router = useRouter();
  11. const categoryStore = useCategory();
  12. const articleStore = useArticle();
  13. const state = reactive({
  14. currFloor: {} as any,
  15. currMid: {} as any,
  16. currTree: {} as any,
  17. currBg: "",
  18. content: "",
  19. loading: true,
  20. });
  21. watch(
  22. () => categoryStore.listController.state.list,
  23. () => {
  24. initCategory();
  25. }
  26. );
  27. onMounted(() => {
  28. initCategory();
  29. initArticle();
  30. });
  31. const initCategory = () => {
  32. const id = route.params.id;
  33. const currCategory = categoryStore.listController.state.list.find(
  34. (e: CategoryItem) => {
  35. return e._id == id;
  36. }
  37. );
  38. if (!currCategory) {
  39. if (categoryStore.listController.state.list.length > 0) {
  40. router.replace("/404");
  41. }
  42. return;
  43. }
  44. if (currCategory?.pid == "top") {
  45. state.currTree = categoryStore.categoryTree.find((e) => {
  46. return e._id == id;
  47. });
  48. state.currMid = state.currTree.children[0];
  49. if (state.currMid.children && state.currMid.children.length) {
  50. const cid = route.query.cid;
  51. if (cid) {
  52. state.currFloor = state.currMid.children.find((e: any) => {
  53. return e._id == cid;
  54. });
  55. } else {
  56. state.currFloor = state.currMid.children[0];
  57. }
  58. } else {
  59. state.currFloor = state.currMid;
  60. }
  61. return;
  62. }
  63. state.currMid = currCategory;
  64. if (currCategory.children && currCategory.children.length) {
  65. const cid = route.query.cid;
  66. if (cid) {
  67. state.currFloor = currCategory.children.find((e: any) => {
  68. return e._id == cid;
  69. });
  70. } else {
  71. state.currFloor = currCategory.children[0];
  72. }
  73. } else {
  74. state.currFloor = state.currMid;
  75. }
  76. state.currTree = categoryStore.categoryTree.find((e) => {
  77. return e._id == currCategory.pid;
  78. });
  79. };
  80. const initArticle = async () => {
  81. const aid = route.query.aid;
  82. if (!aid) {
  83. state.loading = false;
  84. return;
  85. }
  86. const res = await articleStore.listController.itemDetail(aid as string);
  87. if (res.errorNo != 200) {
  88. message.warn("未查询到数据!");
  89. state.loading = false;
  90. return;
  91. }
  92. state.loading = false;
  93. state.content = res.result.content;
  94. };
  95. return () => {
  96. return (
  97. <div class={page}>
  98. <div
  99. class={"page_title_box"}
  100. style={{
  101. backgroundImage: `url(${
  102. state.currMid.cover ? state.currMid.cover : state.currTree.cover
  103. })`,
  104. }}
  105. >
  106. <div class={"title detail_page_w"}>
  107. <h1>{state.currTree.name}</h1>
  108. <h2>{state.currTree.subName}</h2>
  109. </div>
  110. </div>
  111. <div class={"page_tabs_box"}>
  112. <div class="detail_page_w">
  113. <PageTabs
  114. data={state.currTree.children}
  115. activeKey={state.currMid._id}
  116. />
  117. </div>
  118. </div>
  119. <div class={"page_content"}>
  120. <div class={"detail_page_w"}>
  121. <div innerHTML={state.content}></div>
  122. {!state.loading && !state.content && (
  123. <div class={"ant-list-empty-text"}>
  124. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  125. </div>
  126. )}
  127. </div>
  128. </div>
  129. </div>
  130. );
  131. };
  132. },
  133. });
  134. const page = css`
  135. .page_title_box {
  136. position: relative;
  137. height: 500px;
  138. background-position: center;
  139. background-repeat: no-repeat;
  140. background-size: cover;
  141. transition: all 0.2s ease-in-out;
  142. &::after {
  143. content: "";
  144. position: absolute;
  145. bottom: 0;
  146. left: 0;
  147. width: 100%;
  148. height: 220px;
  149. background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000000 100%);
  150. opacity: 0.7;
  151. z-index: 1;
  152. }
  153. .title {
  154. position: relative;
  155. height: 100%;
  156. display: flex;
  157. flex-direction: column;
  158. justify-content: flex-end;
  159. padding-bottom: 28px;
  160. z-index: 2;
  161. h1 {
  162. font-size: 36px;
  163. font-weight: 400;
  164. margin-bottom: 16px;
  165. color: #fff;
  166. }
  167. h2 {
  168. margin-bottom: 0;
  169. height: 1em;
  170. font-size: 14px;
  171. font-weight: 300;
  172. color: #fff;
  173. }
  174. }
  175. }
  176. .page_tabs_box {
  177. background-color: #fff;
  178. border-bottom: 1px solid #e5e5e5;
  179. }
  180. .page_content {
  181. padding: 50px 0;
  182. line-height: 1.5;
  183. img {
  184. display: inline;
  185. }
  186. }
  187. @media screen and (max-width: 1280px) {
  188. .page_title_box {
  189. height: 400px;
  190. .title {
  191. h1 {
  192. font-size: 28px;
  193. }
  194. }
  195. }
  196. }
  197. @media screen and (max-width: 750px) {
  198. .page_title_box {
  199. height: 320px;
  200. .title {
  201. h1 {
  202. font-size: 24px;
  203. }
  204. }
  205. }
  206. }
  207. `;