congmao-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +2 -0
  2. package/bin/index.js +20 -0
  3. package/package.json +42 -0
  4. package/src/commands/create.js +171 -0
  5. package/src/commands/mcp.js +157 -0
  6. package/src/mcp/CURSOR_SETUP.md +259 -0
  7. package/src/mcp/README.md +134 -0
  8. package/src/mcp/USAGE_EXAMPLES.md +181 -0
  9. package/src/mcp/get-cursor-config.js +58 -0
  10. package/src/mcp/package.json +23 -0
  11. package/src/mcp/pnpm-lock.yaml +2441 -0
  12. package/src/mcp/src/handlers.js +211 -0
  13. package/src/mcp/src/http-server.js +332 -0
  14. package/src/mcp/src/index.js +195 -0
  15. package/src/mcp/src/schemas.js +54 -0
  16. package/src/mcp/test-create-project.js +49 -0
  17. package/src/mcp/test-mcp.js +89 -0
  18. package/src/mcp/test-show-tree.js +66 -0
  19. package/src/template/Uni-app/README.md +19 -0
  20. package/src/template/Uni-app/babel.config.js +81 -0
  21. package/src/template/Uni-app/package.json +107 -0
  22. package/src/template/Uni-app/postcss.config.js +27 -0
  23. package/src/template/Uni-app/public/index.html +25 -0
  24. package/src/template/Uni-app/shims-uni.d.ts +11 -0
  25. package/src/template/Uni-app/shims-vue.d.ts +4 -0
  26. package/src/template/Uni-app/src/App.vue +17 -0
  27. package/src/template/Uni-app/src/main.js +12 -0
  28. package/src/template/Uni-app/src/manifest.json +75 -0
  29. package/src/template/Uni-app/src/pages/index/index.vue +49 -0
  30. package/src/template/Uni-app/src/pages.json +16 -0
  31. package/src/template/Uni-app/src/static/logo.png +0 -0
  32. package/src/template/Uni-app/src/uni.promisify.adaptor.js +13 -0
  33. package/src/template/Uni-app/src/uni.scss +76 -0
  34. package/src/template/Uni-app/yarn.lock +11466 -0
  35. package/src/template/Vue2/.editorconfig +14 -0
  36. package/src/template/Vue2/.env +2 -0
  37. package/src/template/Vue2/.env.development +2 -0
  38. package/src/template/Vue2/.env.site +2 -0
  39. package/src/template/Vue2/.prettierrc.js +39 -0
  40. package/src/template/Vue2/.stylelintignore +8 -0
  41. package/src/template/Vue2/README-zh_CN.md +115 -0
  42. package/src/template/Vue2/commitlint.config.js +1 -0
  43. package/src/template/Vue2/docs/docs-starter.png +0 -0
  44. package/src/template/Vue2/docs/docs-startup.png +0 -0
  45. package/src/template/Vue2/docs/docs-structure.png +0 -0
  46. package/src/template/Vue2/globals.d.ts +13 -0
  47. package/src/template/Vue2/index.html +27 -0
  48. package/src/template/Vue2/jsx.d.ts +13 -0
  49. package/src/template/Vue2/mock/index.ts +147 -0
  50. package/src/template/Vue2/package.json +91 -0
  51. package/src/template/Vue2/package.json.ejs +91 -0
  52. package/src/template/Vue2/public/favicon.ico +0 -0
  53. package/src/template/Vue2/shims-vue.d.ts +5 -0
  54. package/src/template/Vue2/src/App.vue +19 -0
  55. package/src/template/Vue2/src/assets/assets-login-bg-black.png +0 -0
  56. package/src/template/Vue2/src/assets/assets-login-bg-white.png +0 -0
  57. package/src/template/Vue2/src/assets/assets-logo-full.svg +39 -0
  58. package/src/template/Vue2/src/assets/assets-product-1.svg +5 -0
  59. package/src/template/Vue2/src/assets/assets-product-2.svg +5 -0
  60. package/src/template/Vue2/src/assets/assets-product-3.svg +5 -0
  61. package/src/template/Vue2/src/assets/assets-product-4.svg +5 -0
  62. package/src/template/Vue2/src/assets/assets-result-403.svg +32 -0
  63. package/src/template/Vue2/src/assets/assets-result-404.svg +36 -0
  64. package/src/template/Vue2/src/assets/assets-result-500.svg +32 -0
  65. package/src/template/Vue2/src/assets/assets-result-ie.svg +33 -0
  66. package/src/template/Vue2/src/assets/assets-result-maintenance.svg +49 -0
  67. package/src/template/Vue2/src/assets/assets-result-wifi.svg +23 -0
  68. package/src/template/Vue2/src/assets/assets-setting-auto.svg +13 -0
  69. package/src/template/Vue2/src/assets/assets-setting-dark.svg +5 -0
  70. package/src/template/Vue2/src/assets/assets-setting-light.svg +13 -0
  71. package/src/template/Vue2/src/assets/assets-t-logo.svg +41 -0
  72. package/src/template/Vue2/src/assets/assets-tencent-logo.png +0 -0
  73. package/src/template/Vue2/src/components/color/index.vue +35 -0
  74. package/src/template/Vue2/src/components/product-card/index.vue +121 -0
  75. package/src/template/Vue2/src/components/result/index.vue +118 -0
  76. package/src/template/Vue2/src/components/thumbnail/index.vue +49 -0
  77. package/src/template/Vue2/src/components/trend/index.vue +105 -0
  78. package/src/template/Vue2/src/config/color.ts +30 -0
  79. package/src/template/Vue2/src/config/global.ts +2 -0
  80. package/src/template/Vue2/src/config/host.ts +26 -0
  81. package/src/template/Vue2/src/config/style.ts +14 -0
  82. package/src/template/Vue2/src/constants/index.ts +46 -0
  83. package/src/template/Vue2/src/interface.ts +39 -0
  84. package/src/template/Vue2/src/layouts/blank.vue +12 -0
  85. package/src/template/Vue2/src/layouts/components/Breadcrumb.vue +39 -0
  86. package/src/template/Vue2/src/layouts/components/Content.vue +43 -0
  87. package/src/template/Vue2/src/layouts/components/Footer.vue +27 -0
  88. package/src/template/Vue2/src/layouts/components/Header.vue +321 -0
  89. package/src/template/Vue2/src/layouts/components/LayoutContent.vue +168 -0
  90. package/src/template/Vue2/src/layouts/components/LayoutHeader.vue +52 -0
  91. package/src/template/Vue2/src/layouts/components/LayoutSidebar.vue +51 -0
  92. package/src/template/Vue2/src/layouts/components/MenuContent.vue +108 -0
  93. package/src/template/Vue2/src/layouts/components/Notice.vue +221 -0
  94. package/src/template/Vue2/src/layouts/components/Search.vue +134 -0
  95. package/src/template/Vue2/src/layouts/components/SideNav.vue +150 -0
  96. package/src/template/Vue2/src/layouts/index.vue +100 -0
  97. package/src/template/Vue2/src/layouts/setting.vue +404 -0
  98. package/src/template/Vue2/src/main.js +9 -0
  99. package/src/template/Vue2/src/main.jsx +51 -0
  100. package/src/template/Vue2/src/pages/dashboard/base/components/MiddleChart.vue +158 -0
  101. package/src/template/Vue2/src/pages/dashboard/base/components/OutputOverview.vue +189 -0
  102. package/src/template/Vue2/src/pages/dashboard/base/components/RankList.vue +111 -0
  103. package/src/template/Vue2/src/pages/dashboard/base/components/TopPanel.vue +246 -0
  104. package/src/template/Vue2/src/pages/dashboard/base/index.ts +702 -0
  105. package/src/template/Vue2/src/pages/dashboard/base/index.vue +44 -0
  106. package/src/template/Vue2/src/pages/dashboard/detail/index.ts +267 -0
  107. package/src/template/Vue2/src/pages/dashboard/detail/index.vue +242 -0
  108. package/src/template/Vue2/src/pages/detail/advanced/components/Product.vue +167 -0
  109. package/src/template/Vue2/src/pages/detail/advanced/index.less +74 -0
  110. package/src/template/Vue2/src/pages/detail/advanced/index.vue +219 -0
  111. package/src/template/Vue2/src/pages/detail/base/index.less +105 -0
  112. package/src/template/Vue2/src/pages/detail/base/index.vue +46 -0
  113. package/src/template/Vue2/src/pages/detail/deploy/index.ts +204 -0
  114. package/src/template/Vue2/src/pages/detail/deploy/index.vue +224 -0
  115. package/src/template/Vue2/src/pages/detail/secondary/index.less +71 -0
  116. package/src/template/Vue2/src/pages/detail/secondary/index.vue +131 -0
  117. package/src/template/Vue2/src/pages/form/base/index.less +57 -0
  118. package/src/template/Vue2/src/pages/form/base/index.vue +254 -0
  119. package/src/template/Vue2/src/pages/form/step/index.less +37 -0
  120. package/src/template/Vue2/src/pages/form/step/index.vue +259 -0
  121. package/src/template/Vue2/src/pages/frame/doc/index.vue +86 -0
  122. package/src/template/Vue2/src/pages/frame/tdesign/index.vue +86 -0
  123. package/src/template/Vue2/src/pages/list/base/index.vue +267 -0
  124. package/src/template/Vue2/src/pages/list/card/index.vue +221 -0
  125. package/src/template/Vue2/src/pages/list/components/CommonTable.vue +313 -0
  126. package/src/template/Vue2/src/pages/list/filter/index.vue +15 -0
  127. package/src/template/Vue2/src/pages/list/tree/index.vue +174 -0
  128. package/src/template/Vue2/src/pages/login/components/components-header.vue +74 -0
  129. package/src/template/Vue2/src/pages/login/components/components-login.vue +154 -0
  130. package/src/template/Vue2/src/pages/login/components/components-register.vue +144 -0
  131. package/src/template/Vue2/src/pages/login/index.less +202 -0
  132. package/src/template/Vue2/src/pages/login/index.vue +53 -0
  133. package/src/template/Vue2/src/pages/nest-menu/Index.vue +10 -0
  134. package/src/template/Vue2/src/pages/result/403/index.vue +14 -0
  135. package/src/template/Vue2/src/pages/result/404/index.vue +14 -0
  136. package/src/template/Vue2/src/pages/result/500/index.vue +14 -0
  137. package/src/template/Vue2/src/pages/result/browser-incompatible/index.vue +77 -0
  138. package/src/template/Vue2/src/pages/result/fail/index.vue +57 -0
  139. package/src/template/Vue2/src/pages/result/maintenance/index.vue +14 -0
  140. package/src/template/Vue2/src/pages/result/network-error/index.vue +24 -0
  141. package/src/template/Vue2/src/pages/result/success/index.vue +59 -0
  142. package/src/template/Vue2/src/pages/user/index.less +148 -0
  143. package/src/template/Vue2/src/pages/user/index.ts +157 -0
  144. package/src/template/Vue2/src/pages/user/index.vue +204 -0
  145. package/src/template/Vue2/src/permission.js +56 -0
  146. package/src/template/Vue2/src/router/index.js +43 -0
  147. package/src/template/Vue2/src/router/modules/base.ts +29 -0
  148. package/src/template/Vue2/src/router/modules/components.ts +175 -0
  149. package/src/template/Vue2/src/router/modules/others.ts +55 -0
  150. package/src/template/Vue2/src/service/service-advance.ts +233 -0
  151. package/src/template/Vue2/src/service/service-base.ts +205 -0
  152. package/src/template/Vue2/src/service/service-detail-base.ts +84 -0
  153. package/src/template/Vue2/src/service/service-detail-deploy.ts +234 -0
  154. package/src/template/Vue2/src/service/service-detail.ts +57 -0
  155. package/src/template/Vue2/src/service/service-user.ts +64 -0
  156. package/src/template/Vue2/src/store/index.ts +22 -0
  157. package/src/template/Vue2/src/store/modules/notification.ts +90 -0
  158. package/src/template/Vue2/src/store/modules/permission.ts +66 -0
  159. package/src/template/Vue2/src/store/modules/setting.ts +122 -0
  160. package/src/template/Vue2/src/store/modules/tab-router.ts +83 -0
  161. package/src/template/Vue2/src/store/modules/user.ts +98 -0
  162. package/src/template/Vue2/src/style/font-family.less +6 -0
  163. package/src/template/Vue2/src/style/index.less +5 -0
  164. package/src/template/Vue2/src/style/layout.less +201 -0
  165. package/src/template/Vue2/src/style/reset.less +78 -0
  166. package/src/template/Vue2/src/style/variables.less +27 -0
  167. package/src/template/Vue2/src/utils/charts.ts +38 -0
  168. package/src/template/Vue2/src/utils/color.ts +118 -0
  169. package/src/template/Vue2/src/utils/date.ts +12 -0
  170. package/src/template/Vue2/src/utils/request.ts +60 -0
  171. package/src/template/Vue2/stylelint.config.js +5 -0
  172. package/src/template/Vue2/tsconfig.json +26 -0
  173. package/src/template/Vue2/vite.config.js +58 -0
  174. package/src/template/Vue3/package.json.ejs +8 -0
  175. package/src/template/Vue3/pages.json +10 -0
  176. package/src/template/Vue3/src/main.js +7 -0
  177. package/src/utils/copy.js +17 -0
  178. package/src/utils/eslint.js +205 -0
  179. package/src/utils/logo.js +18 -0
  180. package/src/utils/render.js +20 -0
@@ -0,0 +1,86 @@
1
+ <template>
2
+ <div :class="`${prefix}-iframe-page`" :style="getWrapStyle">
3
+ <t-loading :loading="loading" size="large" :style="getWrapStyle">
4
+ <iframe ref="frameRef" :src="frameSrc" :class="`${prefix}-iframe-page__main`" @load="hideLoading"></iframe>
5
+ </t-loading>
6
+ </div>
7
+ </template>
8
+ <script lang="ts">
9
+ import { prefix } from '@/config/global';
10
+ import STYLE_CONFIG from '@/config/style';
11
+
12
+ const computedStyle = getComputedStyle(document.documentElement);
13
+ const sizeXxxl = computedStyle.getPropertyValue('--td-comp-size-xxxl');
14
+ const paddingTBXxl = computedStyle.getPropertyValue('--td-comp-paddingTB-xxl');
15
+
16
+ export default {
17
+ name: 'DetailAdvanced',
18
+ data() {
19
+ return {
20
+ prefix,
21
+ loading: true,
22
+ frameSrc: 'https://tdesign.tencent.com/vue-next/getting-started',
23
+ settingStore: { ...STYLE_CONFIG },
24
+ getWrapStyle: `height: ${window.innerHeight}px`,
25
+ };
26
+ },
27
+ mounted() {
28
+ window.addEventListener('resize', this.calcHeight, false);
29
+ this.$nextTick(() => {
30
+ this.calcHeight();
31
+ });
32
+ },
33
+ methods: {
34
+ hideLoading() {
35
+ this.loading = false;
36
+ this.calcHeight();
37
+ },
38
+
39
+ getOuterHeight(dom: Element) {
40
+ let height = dom.clientHeight;
41
+ const computedStyle = window.getComputedStyle(dom);
42
+ height += parseInt(computedStyle.marginTop, 10);
43
+ height += parseInt(computedStyle.marginBottom, 10);
44
+ height += parseInt(computedStyle.borderTopWidth, 10);
45
+ height += parseInt(computedStyle.borderBottomWidth, 10);
46
+ return height;
47
+ },
48
+
49
+ calcHeight() {
50
+ const iframe = this.$refs.frameRef;
51
+ if (!iframe) {
52
+ return;
53
+ }
54
+ let clientHeight = 0;
55
+ const { showFooter, isUseTabsRouter, showBreadcrumb } = this.settingStore;
56
+ const headerHeight = parseFloat(sizeXxxl);
57
+ const navDom = document.querySelector('.t-tabs__nav');
58
+ const navHeight = isUseTabsRouter ? this.getOuterHeight(navDom) : 0;
59
+ const breadcrumbDom = document.querySelector('.t-breadcrumb');
60
+ const breadcrumbHeight = showBreadcrumb ? this.getOuterHeight(breadcrumbDom) : 0;
61
+ const contentPadding = parseFloat(paddingTBXxl) * 2;
62
+ const footerDom = document.querySelector('.t-layout__footer');
63
+ const footerHeight = showFooter ? this.getOuterHeight(footerDom) : 0;
64
+ const top = headerHeight + navHeight + breadcrumbHeight + contentPadding + footerHeight + 2;
65
+ window.innerHeight -= top;
66
+ clientHeight = document.documentElement.clientHeight - top;
67
+ iframe.style.height = `${clientHeight}px`;
68
+ this.getWrapStyle = `height: ${window.innerHeight}px`;
69
+ },
70
+ },
71
+ };
72
+ </script>
73
+ <style lang="less" scoped>
74
+ @import '@/style/variables';
75
+
76
+ .@{starter-prefix}-iframe-page {
77
+ &__main {
78
+ width: 100%;
79
+ height: 100%;
80
+ overflow: hidden;
81
+ background-color: #fff;
82
+ border: 0;
83
+ box-sizing: border-box;
84
+ }
85
+ }
86
+ </style>
@@ -0,0 +1,267 @@
1
+ <template>
2
+ <div>
3
+ <t-card class="list-card-container" :bordered="false">
4
+ <t-row justify="space-between">
5
+ <div class="left-operation-container">
6
+ <t-button @click="handleSetupContract"> 新建合同 </t-button>
7
+ <t-button variant="base" theme="default" :disabled="!selectedRowKeys.length"> 导出合同 </t-button>
8
+ <p v-if="!!selectedRowKeys.length" class="selected-count">已选{{ selectedRowKeys.length }}项</p>
9
+ </div>
10
+ <t-input v-model="searchValue" class="search-input" placeholder="请输入你需要搜索的内容" clearable>
11
+ <template #suffix-icon>
12
+ <search-icon size="20px" />
13
+ </template>
14
+ </t-input>
15
+ </t-row>
16
+
17
+ <div class="table-container">
18
+ <t-table
19
+ :columns="columns"
20
+ :data="data"
21
+ :rowKey="rowKey"
22
+ :verticalAlign="verticalAlign"
23
+ :hover="hover"
24
+ :pagination="pagination"
25
+ :selected-row-keys="selectedRowKeys"
26
+ :loading="dataLoading"
27
+ @page-change="rehandlePageChange"
28
+ @change="rehandleChange"
29
+ @select-change="rehandleSelectChange"
30
+ :headerAffixedTop="true"
31
+ :headerAffixProps="{ offsetTop: offsetTop, container: getContainer }"
32
+ >
33
+ <template #status="{ row }">
34
+ <t-tag v-if="row.status === CONTRACT_STATUS.FAIL" theme="danger" variant="light">审核失败</t-tag>
35
+ <t-tag v-if="row.status === CONTRACT_STATUS.AUDIT_PENDING" theme="warning" variant="light">待审核</t-tag>
36
+ <t-tag v-if="row.status === CONTRACT_STATUS.EXEC_PENDING" theme="warning" variant="light">待履行</t-tag>
37
+ <t-tag v-if="row.status === CONTRACT_STATUS.EXECUTING" theme="success" variant="light">履行中</t-tag>
38
+ <t-tag v-if="row.status === CONTRACT_STATUS.FINISH" theme="success" variant="light">已完成</t-tag>
39
+ </template>
40
+ <template #contractType="{ row }">
41
+ <p v-if="row.contractType === CONTRACT_TYPES.MAIN">审核失败</p>
42
+ <p v-if="row.contractType === CONTRACT_TYPES.SUB">待审核</p>
43
+ <p v-if="row.contractType === CONTRACT_TYPES.SUPPLEMENT">待履行</p>
44
+ </template>
45
+ <template #paymentType="{ row }">
46
+ <p v-if="row.paymentType === CONTRACT_PAYMENT_TYPES.PAYMENT" class="payment-col">
47
+ 付款
48
+ <trend class="dashboard-item-trend" type="up" />
49
+ </p>
50
+ <p v-if="row.paymentType === CONTRACT_PAYMENT_TYPES.RECIPT" class="payment-col">
51
+ 收款
52
+ <trend class="dashboard-item-trend" type="down" />
53
+ </p>
54
+ </template>
55
+
56
+ <template #op="slotProps">
57
+ <a class="t-button-link" @click="handleClickDetail()">详情</a>
58
+ <a class="t-button-link" @click="handleClickDelete(slotProps)">删除</a>
59
+ </template>
60
+ </t-table>
61
+ </div>
62
+ </t-card>
63
+ <t-dialog
64
+ header="确认删除当前所选合同?"
65
+ :body="confirmBody"
66
+ :visible.sync="confirmVisible"
67
+ @confirm="onConfirmDelete"
68
+ :onCancel="onCancel"
69
+ >
70
+ </t-dialog>
71
+ </div>
72
+ </template>
73
+ <script lang="ts">
74
+ import Vue from 'vue';
75
+ import { SearchIcon } from 'tdesign-icons-vue';
76
+ import Trend from '@/components/trend/index.vue';
77
+ import { prefix } from '@/config/global';
78
+
79
+ import { CONTRACT_STATUS, CONTRACT_STATUS_OPTIONS, CONTRACT_TYPES, CONTRACT_PAYMENT_TYPES } from '@/constants';
80
+
81
+ export default Vue.extend({
82
+ name: 'ListBase',
83
+ components: {
84
+ SearchIcon,
85
+ Trend,
86
+ },
87
+ data() {
88
+ return {
89
+ CONTRACT_STATUS,
90
+ CONTRACT_STATUS_OPTIONS,
91
+ CONTRACT_TYPES,
92
+ CONTRACT_PAYMENT_TYPES,
93
+ prefix,
94
+ dataLoading: false,
95
+ data: [],
96
+ selectedRowKeys: [1, 2],
97
+ value: 'first',
98
+ columns: [
99
+ { colKey: 'row-select', type: 'multiple', width: 64, fixed: 'left' },
100
+ {
101
+ title: '合同名称',
102
+ align: 'left',
103
+ width: 250,
104
+ ellipsis: true,
105
+ colKey: 'name',
106
+ fixed: 'left',
107
+ },
108
+ { title: '合同状态', colKey: 'status', width: 200, cell: { col: 'status' } },
109
+ {
110
+ title: '合同编号',
111
+ width: 200,
112
+ ellipsis: true,
113
+ colKey: 'no',
114
+ },
115
+ {
116
+ title: '合同类型',
117
+ width: 200,
118
+ ellipsis: true,
119
+ colKey: 'contractType',
120
+ },
121
+ {
122
+ title: '合同收付类型',
123
+ width: 200,
124
+ ellipsis: true,
125
+ colKey: 'paymentType',
126
+ },
127
+ {
128
+ title: '合同金额 (元)',
129
+ width: 200,
130
+ ellipsis: true,
131
+ colKey: 'amount',
132
+ },
133
+ {
134
+ align: 'left',
135
+ fixed: 'right',
136
+ width: 200,
137
+ colKey: 'op',
138
+ title: '操作',
139
+ },
140
+ ],
141
+ rowKey: 'index',
142
+ tableLayout: 'auto',
143
+ verticalAlign: 'top',
144
+ hover: true,
145
+ rowClassName: (rowKey: string) => `${rowKey}-class`,
146
+ // 与pagination对齐
147
+ pagination: {
148
+ defaultPageSize: 20,
149
+ total: 0,
150
+ defaultCurrent: 1,
151
+ },
152
+ searchValue: '',
153
+ confirmVisible: false,
154
+ deleteIdx: -1,
155
+ };
156
+ },
157
+ computed: {
158
+ confirmBody() {
159
+ if (this.deleteIdx > -1) {
160
+ const { name } = this.data?.[this.deleteIdx];
161
+ return `删除后,${name}的所有合同信息将被清空,且无法恢复`;
162
+ }
163
+ return '';
164
+ },
165
+ offsetTop() {
166
+ return this.$store.state.setting.isUseTabsRouter ? 48 : 0;
167
+ },
168
+ },
169
+ mounted() {
170
+ this.dataLoading = true;
171
+ this.$request
172
+ .get('/api/get-list')
173
+ .then((res) => {
174
+ if (res.code === 0) {
175
+ const { list = [] } = res.data;
176
+ this.data = list;
177
+ this.pagination = {
178
+ ...this.pagination,
179
+ total: list.length,
180
+ };
181
+ }
182
+ })
183
+ .catch((e: Error) => {
184
+ console.log(e);
185
+ })
186
+ .finally(() => {
187
+ this.dataLoading = false;
188
+ });
189
+ },
190
+
191
+ methods: {
192
+ getContainer() {
193
+ return document.querySelector('.tdesign-starter-layout');
194
+ },
195
+ rehandlePageChange(curr, pageInfo) {
196
+ console.log('分页变化', curr, pageInfo);
197
+ },
198
+ rehandleSelectChange(selectedRowKeys: number[]) {
199
+ this.selectedRowKeys = selectedRowKeys;
200
+ },
201
+ rehandleChange(changeParams, triggerAndData) {
202
+ console.log('统一Change', changeParams, triggerAndData);
203
+ },
204
+ handleClickDetail() {
205
+ this.$router.push('/detail/base');
206
+ },
207
+ handleSetupContract() {
208
+ this.$router.push('/form/base');
209
+ },
210
+ handleClickDelete(row: { rowIndex: any }) {
211
+ this.deleteIdx = row.rowIndex;
212
+ this.confirmVisible = true;
213
+ },
214
+ onConfirmDelete() {
215
+ // 真实业务请发起请求
216
+ this.data.splice(this.deleteIdx, 1);
217
+ this.pagination.total = this.data.length;
218
+ const selectedIdx = this.selectedRowKeys.indexOf(this.deleteIdx);
219
+ if (selectedIdx > -1) {
220
+ this.selectedRowKeys.splice(selectedIdx, 1);
221
+ }
222
+ this.confirmVisible = false;
223
+ this.$message.success('删除成功');
224
+ this.resetIdx();
225
+ },
226
+ onCancel() {
227
+ this.resetIdx();
228
+ },
229
+ resetIdx() {
230
+ this.deleteIdx = -1;
231
+ },
232
+ },
233
+ });
234
+ </script>
235
+
236
+ <style lang="less" scoped>
237
+ @import '@/style/variables';
238
+
239
+ .payment-col {
240
+ display: flex;
241
+
242
+ .trend-container {
243
+ display: flex;
244
+ align-items: center;
245
+ margin-left: 8px;
246
+ }
247
+ }
248
+
249
+ .left-operation-container {
250
+ padding: 0 0 6px 0;
251
+ margin-bottom: 16px;
252
+
253
+ .selected-count {
254
+ display: inline-block;
255
+ margin-left: var(--td-comp-margin-s);
256
+ color: var(--td-text-color-secondary);
257
+ }
258
+ }
259
+
260
+ .search-input {
261
+ width: 360px;
262
+ }
263
+
264
+ .t-button + .t-button {
265
+ margin-left: var(--td-comp-margin-s);
266
+ }
267
+ </style>
@@ -0,0 +1,221 @@
1
+ <template>
2
+ <div class="list-card">
3
+ <!-- 搜索区域 -->
4
+ <div class="list-card-operation">
5
+ <t-button @click="formVisible = true">新建产品</t-button>
6
+ <t-input v-model="searchValue" class="search-input" placeholder="请输入你需要搜索的内容" clearable>
7
+ <template #suffix-icon>
8
+ <search-icon v-if="searchValue === ''" size="20px" />
9
+ </template>
10
+ </t-input>
11
+ </div>
12
+ <!-- 卡片列表 -->
13
+ <template v-if="pagination.total > 0 && !dataLoading">
14
+ <div class="list-card-items">
15
+ <t-row :gutter="[16, 16]">
16
+ <t-col
17
+ :lg="4"
18
+ :xs="6"
19
+ :xl="3"
20
+ v-for="product in productList.slice(
21
+ pagination.pageSize * (pagination.current - 1),
22
+ pagination.pageSize * pagination.current,
23
+ )"
24
+ :key="product.index"
25
+ >
26
+ <product-card :product="product" @delete-item="handleDeleteItem" @manage-product="handleManageProduct" />
27
+ </t-col>
28
+ </t-row>
29
+ </div>
30
+ <div class="list-card-pagination">
31
+ <t-pagination
32
+ v-model="pagination.current"
33
+ :total="pagination.total"
34
+ :pageSizeOptions="[12, 24, 36]"
35
+ :page-size.sync="pagination.pageSize"
36
+ @page-size-change="onPageSizeChange"
37
+ @current-change="onCurrentChange"
38
+ />
39
+ </div>
40
+ </template>
41
+ <div v-else-if="dataLoading" class="list-card-loading">
42
+ <t-loading text="加载中..."></t-loading>
43
+ </div>
44
+ <!-- 产品管理弹窗 -->
45
+ <t-dialog header="新建产品" :visible.sync="formVisible" :width="680" :footer="false">
46
+ <div slot="body">
47
+ <!-- 表单内容 -->
48
+ <t-form :data="formData" ref="form" :rules="rules" @submit="onSubmit" :labelWidth="100">
49
+ <t-form-item label="产品名称" name="name">
50
+ <t-input :style="{ width: '480px' }" v-model="formData.name" placeholder="请输入产品名称"></t-input>
51
+ </t-form-item>
52
+ <t-form-item label="产品状态" name="status">
53
+ <t-radio-group v-model="formData.status">
54
+ <t-radio value="0">已停用</t-radio>
55
+ <t-radio value="1">已启用</t-radio>
56
+ </t-radio-group>
57
+ </t-form-item>
58
+ <t-form-item label="产品描述" name="description">
59
+ <t-input :style="{ width: '480px' }" v-model="formData.description" placeholder="请输入产品描述"></t-input>
60
+ </t-form-item>
61
+ <t-form-item label="产品类型" name="type">
62
+ <t-select v-model="formData.type" clearable :style="{ width: '480px' }">
63
+ <t-option v-for="(item, index) in options" :value="item.value" :label="item.label" :key="index">
64
+ {{ item.label }}
65
+ </t-option>
66
+ </t-select>
67
+ </t-form-item>
68
+ <t-form-item label="备注" name="mark">
69
+ <t-textarea :style="{ width: '480px' }" v-model="textareaValue" placeholder="请输入内容" name="description">
70
+ </t-textarea>
71
+ </t-form-item>
72
+ <t-form-item style="float: right">
73
+ <t-button variant="outline" @click="onClickCloseBtn">取消</t-button>
74
+ <t-button theme="primary" type="submit">确定</t-button>
75
+ </t-form-item>
76
+ </t-form>
77
+ </div>
78
+ </t-dialog>
79
+ <!-- 删除操作弹窗 -->
80
+ <t-dialog
81
+ header="确认删除所选产品?"
82
+ :body="confirmBody"
83
+ :visible.sync="confirmVisible"
84
+ @confirm="onConfirmDelete"
85
+ :onCancel="onCancel"
86
+ >
87
+ </t-dialog>
88
+ </div>
89
+ </template>
90
+ <script lang="ts">
91
+ import { prefix } from '@/config/global';
92
+ import { SearchIcon } from 'tdesign-icons-vue';
93
+ import ProductCard from '@/components/product-card/index.vue';
94
+
95
+ const INITIAL_DATA = {
96
+ name: '',
97
+ status: '',
98
+ description: '',
99
+ type: '',
100
+ mark: '',
101
+ amount: 0,
102
+ };
103
+
104
+ export default {
105
+ name: 'ListCard',
106
+ components: {
107
+ SearchIcon,
108
+ ProductCard,
109
+ },
110
+ data() {
111
+ return {
112
+ pagination: { current: 1, pageSize: 12, total: 0 },
113
+ prefix,
114
+ productList: [],
115
+ value: 'first',
116
+ rowKey: 'index',
117
+ tableLayout: 'auto',
118
+ verticalAlign: 'top',
119
+ bordered: true,
120
+ hover: true,
121
+ rowClassName: (rowKey) => `${rowKey}-class`,
122
+ formData: { ...INITIAL_DATA },
123
+ options: [
124
+ { label: '网关', value: '1' },
125
+ { label: '人工智能', value: '2' },
126
+ { label: 'CVM', value: '3' },
127
+ ],
128
+ formVisible: false,
129
+ textareaValue: '',
130
+ rules: {
131
+ name: [{ required: true, message: '请输入产品名称', type: 'error' }],
132
+ },
133
+ searchValue: '',
134
+ confirmVisible: false, // 控制确认弹窗
135
+ deleteProduct: undefined,
136
+ dataLoading: false,
137
+ };
138
+ },
139
+ computed: {
140
+ confirmBody(): string {
141
+ const { deleteProduct } = this;
142
+ return deleteProduct ? `删除后,${deleteProduct.name}的所有产品信息将被清空, 且无法恢复` : '';
143
+ },
144
+ },
145
+ mounted() {
146
+ this.dataLoading = true;
147
+ this.$request
148
+ .get('/api/get-card-list')
149
+ .then((res) => {
150
+ if (res.code === 0) {
151
+ const { list = [] } = res.data;
152
+ this.productList = list;
153
+ this.pagination = {
154
+ ...this.pagination,
155
+ total: list.length,
156
+ };
157
+ }
158
+ })
159
+ .catch((e: Error) => {
160
+ console.log(e);
161
+ })
162
+ .finally(() => {
163
+ this.dataLoading = false;
164
+ });
165
+ },
166
+ methods: {
167
+ onPageSizeChange(size: number): void {
168
+ this.pagination.pageSize = size;
169
+ this.pagination.current = 1;
170
+ },
171
+ onCurrentChange(current: number): void {
172
+ this.pagination.current = current;
173
+ },
174
+ onSubmit({ result, firstError }): void {
175
+ if (!firstError) {
176
+ this.$message.success('提交成功');
177
+ this.formVisible = false;
178
+ } else {
179
+ console.log('Errors: ', result);
180
+ this.$message.warning(firstError);
181
+ }
182
+ },
183
+ onClickCloseBtn(): void {
184
+ this.formVisible = false;
185
+ this.formData = {};
186
+ },
187
+ handleDeleteItem(product): void {
188
+ this.confirmVisible = true;
189
+ this.deleteProduct = product;
190
+ },
191
+ onConfirmDelete(): void {
192
+ const { index } = this.deleteProduct;
193
+ this.productList.splice(index - 1, 1);
194
+ this.confirmVisible = false;
195
+ this.$message.success('删除成功');
196
+ },
197
+ onCancel(): void {
198
+ this.deleteProduct = undefined;
199
+ this.formData = {};
200
+ },
201
+ handleManageProduct(product): void {
202
+ this.formVisible = true;
203
+ this.formData = { ...product, status: product?.isSetup ? '1' : '0' };
204
+ },
205
+ },
206
+ };
207
+ </script>
208
+ <style scoped lang="less">
209
+ .list-card-operation {
210
+ display: flex;
211
+ justify-content: space-between;
212
+
213
+ .search-input {
214
+ width: 360px;
215
+ }
216
+ }
217
+
218
+ .list-card-items {
219
+ margin: 14px 0 24px 0;
220
+ }
221
+ </style>