article.tsx 5.5 KB

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