AppTab.tsx 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import { useState, useRef } from "react";
  2. import {
  3. ActionType,
  4. ProColumns,
  5. TableDropdown,
  6. } from "@ant-design/pro-components";
  7. import { ProTable } from "@ant-design/pro-components";
  8. import { Popconfirm, Tag, message } from "antd";
  9. import AddAppDrawer from "./AddAppDrawer";
  10. import {
  11. GetAppList,
  12. DeleteAppTemplate,
  13. OffMarketApp,
  14. OnMarketApp,
  15. } from "@/api/appStore";
  16. import type { AppItem } from "@/api/appStore";
  17. import { history } from "umi";
  18. export default () => {
  19. const actionRef = useRef<ActionType>();
  20. const [editData, setEditData] = useState<AppItem>();
  21. const handleToDetail = (id?: string) => {
  22. history.push(`/detail/application/${id}`);
  23. };
  24. const handleOffMarket = async (id?: string) => {
  25. if (id) {
  26. await OffMarketApp({ ids: [id] });
  27. actionRef.current?.reload();
  28. message.success("下架成功");
  29. }
  30. };
  31. const handleOnMarket = async (id?: string) => {
  32. if (id) {
  33. await OnMarketApp({ ids: [id] });
  34. actionRef.current?.reload();
  35. message.success("上架成功");
  36. }
  37. };
  38. const handleDelete = async (id?: string) => {
  39. if (id) {
  40. await DeleteAppTemplate({ ids: [id] });
  41. actionRef.current?.reload();
  42. message.success("删除成功");
  43. }
  44. };
  45. const columns: ProColumns<AppItem>[] = [
  46. {
  47. title: "图标",
  48. dataIndex: "icon",
  49. search: false,
  50. render: (_, record) => (
  51. <img
  52. src={`/api/File/Download?fileId=${record.icon}`}
  53. alt=""
  54. style={{
  55. width: 30,
  56. height: 30,
  57. borderRadius: "50%",
  58. }}
  59. />
  60. ),
  61. },
  62. {
  63. title: "应用名称",
  64. dataIndex: "name",
  65. copyable: true,
  66. ellipsis: true,
  67. },
  68. {
  69. title: "作者",
  70. dataIndex: "createByName",
  71. ellipsis: true,
  72. search: false,
  73. },
  74. // {
  75. // title: "应用场景",
  76. // dataIndex: "applicationScenarios",
  77. // ellipsis: true,
  78. // search: false,
  79. // renderText: (text) => {
  80. // return (JSON.parse(text || '[]')).map((item: string) => (
  81. // <Tag key={item}>{item}</Tag>
  82. // ));
  83. // },
  84. // },
  85. // {
  86. // title: "应用行业",
  87. // dataIndex: "industries",
  88. // ellipsis: true,
  89. // search: false,
  90. // renderText: (text) => {
  91. // return (JSON.parse(text || '[]')).map((item: string) => (
  92. // <Tag key={item}>{item}</Tag>
  93. // ));
  94. // },
  95. // },
  96. {
  97. disable: true,
  98. title: "标签",
  99. dataIndex: "tags",
  100. search: false,
  101. },
  102. {
  103. title: "上架状态",
  104. dataIndex: "isOnMarket",
  105. filters: true,
  106. ellipsis: true,
  107. valueType: "select",
  108. valueEnum: {
  109. on: {
  110. text: "已上架",
  111. status: "Error",
  112. },
  113. off: {
  114. text: "未上架",
  115. status: "Success",
  116. },
  117. },
  118. render: (_, record) => (
  119. <Tag color={record.isOnMarket ? "green" : "red"}>
  120. {record.isOnMarket ? "已上架" : "未上架"}
  121. </Tag>
  122. ),
  123. },
  124. {
  125. title: "使用量",
  126. dataIndex: "useNum",
  127. search: false,
  128. },
  129. {
  130. title: "价格",
  131. dataIndex: "price",
  132. search: false,
  133. renderText: (text) => {
  134. return text ? `¥${text}` : "免费";
  135. },
  136. },
  137. {
  138. title: "试用地址",
  139. dataIndex: "trialUrl",
  140. search: false,
  141. renderText: (text) =>
  142. text ? (
  143. <a target="_blank" rel="noopener noreferrer" href={text}>
  144. {text}
  145. </a>
  146. ) : (
  147. "-"
  148. ),
  149. },
  150. {
  151. title: "创建时间",
  152. dataIndex: "createTime",
  153. search: false,
  154. },
  155. {
  156. title: "更新时间",
  157. dataIndex: "updateTime",
  158. search: false,
  159. },
  160. {
  161. title: "操作",
  162. valueType: "option",
  163. key: "option",
  164. width: 180,
  165. render: (text, record, _, action) => [
  166. <a key="edit" onClick={() => setEditData(record)}>
  167. 编辑
  168. </a>,
  169. <a
  170. target="_blank"
  171. rel="noopener noreferrer"
  172. key="view"
  173. onClick={() => handleToDetail(record.id)}
  174. >
  175. 详情
  176. </a>,
  177. record.isOnMarket ? (
  178. <a
  179. target="_blank"
  180. rel="noopener noreferrer"
  181. key="off"
  182. onClick={() => handleOffMarket(record.id)}
  183. >
  184. 下架
  185. </a>
  186. ) : (
  187. <a
  188. target="_blank"
  189. rel="noopener noreferrer"
  190. key="on"
  191. onClick={() => handleOnMarket(record.id)}
  192. >
  193. 上架
  194. </a>
  195. ),
  196. <Popconfirm
  197. key="delete"
  198. title="确定删除吗?"
  199. onConfirm={() => handleDelete(record.id)}
  200. >
  201. <a className="text-red-500" target="_blank" rel="noopener noreferrer">
  202. 删除
  203. </a>
  204. </Popconfirm>,
  205. ],
  206. },
  207. ];
  208. return (
  209. <ProTable<AppItem>
  210. columns={columns}
  211. actionRef={actionRef}
  212. cardBordered
  213. request={async (params, sort, filter) => {
  214. console.log(params, sort, filter);
  215. const isOnMarket =
  216. params?.isOnMarket === "on"
  217. ? 1
  218. : params?.isOnMarket === "off"
  219. ? 0
  220. : undefined;
  221. const res = await GetAppList({
  222. currentPage: params.current || 1,
  223. pageSize: params.pageSize || 10,
  224. filters: [
  225. { name: "name", value: params?.name },
  226. { name: "isFree", value: params?.isFree },
  227. { name: "isOnMarket", value: isOnMarket },
  228. { name: "isDel", value: 0 },
  229. ],
  230. });
  231. const data = res?.result || {};
  232. return {
  233. data: data.model || [],
  234. success: true,
  235. total: data.totalCount || 0,
  236. };
  237. }}
  238. columnsState={{
  239. persistenceKey: "shalu-marketplace",
  240. persistenceType: "localStorage",
  241. defaultValue: {
  242. option: { fixed: "right", disable: true },
  243. },
  244. }}
  245. rowKey="id"
  246. search={{
  247. labelWidth: "auto",
  248. }}
  249. options={{
  250. setting: {
  251. listsHeight: 400,
  252. },
  253. }}
  254. pagination={{
  255. pageSize: 10,
  256. }}
  257. dateFormatter="string"
  258. headerTitle={
  259. <AddAppDrawer
  260. editData={editData}
  261. onClose={() => setEditData(undefined)}
  262. onSuccess={() => {
  263. actionRef.current?.reload();
  264. }}
  265. />
  266. }
  267. />
  268. );
  269. };