baseRightsConfigList.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. <!-- 模板区域 -->
  2. <template>
  3. <div>
  4. <!--定义表格-->
  5. <BasicTable @register="registerTable">
  6. <!-- 表格顶部左侧操作 -->
  7. <template #tableTitle>
  8. <a-button type="primary" @click="channelConfigAdd" preIcon="ant-design:plus-outlined">创建渠道</a-button>
  9. </template>
  10. <!--操作栏-->
  11. <template #action="{ record }">
  12. <TableAction :actions="getTableAction(record)" :dropDownActions="dropDownAction(record)" />
  13. </template>
  14. </BasicTable>
  15. <a-modal v-model:open="keyInfoShow" title="关键信息" width="700px" :footer="null" :bodyStyle="{ padding: '16px' }">
  16. <div class=" keyInfo">
  17. <div class="dis ">
  18. <span class="label">AppID:</span>
  19. <span class="value">{{ keyInfoData.appId }}</span>
  20. <a-button type="link" ></a-button>
  21. </div>
  22. <div class="dis ">
  23. <span class="label">AppSecret:</span>
  24. <span class="value ">{{ keyInfoData.appSecret }}</span>
  25. <a-button type="link" @click="regenerate">重新生成</a-button>
  26. </div>
  27. <div class="dis ">
  28. <span class="label">AppKey:</span>
  29. <span class="value">{{ keyInfoData.appKey }}</span>
  30. <a-button type="link" @click="copyClick">复制</a-button>
  31. </div>
  32. <div class="dis ">
  33. <span class="label">权益发放H5链接:</span>
  34. <span class="value">{{ keyInfoData.rightsDistributionUrl }}</span>
  35. <a-button type="link" @click="copyClick">复制</a-button>
  36. </div>
  37. <div class="dis ">
  38. <span class="label">订单H5链接:</span>
  39. <span class="value">{{ keyInfoData.orderUrl }}</span>
  40. <a-button type="link" @click="copyClick">复制</a-button>
  41. </div>
  42. <div class="dis ">
  43. <span class="label">我的券包H5链接:</span>
  44. <span class="value">{{ keyInfoData.rollPackUrl }}</span>
  45. <a-button type="link" @click="copyClick">复制</a-button>
  46. </div>
  47. <div class="dis ">
  48. <span class="label">权益兑换H5链接:</span>
  49. <span class="value">{{ keyInfoData.rightsRedemptionUrl }}</span>
  50. <a-button type="link" @click="copyClick">复制</a-button>
  51. </div>
  52. </div>
  53. </a-modal>
  54. </div>
  55. </template>
  56. <!-- 行为区域 -->
  57. <script lang="ts" name="basic-table-demo" setup>
  58. import { ActionItem, BasicColumn, BasicTable, TableAction } from '/@/components/Table';
  59. import { useListPage } from '/@/hooks/system/useListPage';
  60. import { FormSchema } from '/@/components/Table';
  61. import { reactive, ref } from 'vue';
  62. import type { UnwrapRef } from 'vue';
  63. import type { Rule } from 'ant-design-vue/es/form';
  64. import * as channelAPI from '/@/api/channel/businessConfig';
  65. import { message, Modal } from 'ant-design-vue';
  66. import { useRouter, useRoute } from 'vue-router';
  67. //表单配置
  68. const router = useRouter();
  69. const formRef = ref();
  70. const channelId = ref(null);//渠道id
  71. const keyInfoShow = ref(false);//关键信息弹窗
  72. const keyInfoData = ref<ActionItem>({});//关键信息数据
  73. const channelConfigForm = reactive({
  74. id: null,
  75. pricingName: '',//计费模式名称
  76. pricingCode: "",//计费模式编码
  77. pricingUnit: "",//计费单位
  78. minPrice: "",//最低起投金额
  79. pricingDesc: "",//描述
  80. });
  81. const rules: Record<string, Rule[]> = {
  82. pricingName: [
  83. { required: true, message: '名称必填', trigger: 'blur' },
  84. ],
  85. pricingCode: [
  86. { required: true, message: '编码必填', trigger: 'blur' },
  87. ],
  88. pricingUnit: [
  89. { required: true, message: '必选', trigger: 'change' },
  90. ],
  91. minPrice: [
  92. { required: true, message: '起投金额必填', trigger: 'blur' },
  93. ],
  94. };
  95. //定义表格列字段
  96. const columns: BasicColumn[] = [
  97. {
  98. title: '渠道机构',
  99. dataIndex: 'institutionName',
  100. key: 'institutionName',
  101. width: 200,
  102. },
  103. {
  104. title: '权益发放场景',
  105. dataIndex: 'issueConnectionMethod',
  106. key: 'issueConnectionMethod',
  107. customRender: ({ record }) => {
  108. if (record.issueConnectionMethod == 1) {
  109. return 'H5'
  110. } else {
  111. return 'api'
  112. }
  113. },
  114. },
  115. {
  116. title: '消费者场景',
  117. dataIndex: 'consumerConnectionMethod',
  118. key: 'consumerConnectionMethod',
  119. customRender: ({ record }) => {
  120. if (record.issueConnectionMethod == 1) {
  121. return 'H5'
  122. } else if (record.consumerConnectionMethod == 2) {
  123. return 'api'
  124. } else {
  125. return '原生'
  126. }
  127. },
  128. },
  129. {
  130. title: '渠道归属',
  131. dataIndex: 'channelName',
  132. key: 'channelName',
  133. },
  134. {
  135. title: '状态',
  136. dataIndex: 'status',
  137. key: 'status',
  138. customRender: ({ record }) => {
  139. if (record.status == 1) {
  140. return '启用'
  141. } else if (record.status == 0) {
  142. return '禁用'
  143. } else {
  144. return '-'
  145. }
  146. },
  147. },
  148. {
  149. title: '创建时间',
  150. dataIndex: 'createTime',
  151. key: 'createTime',
  152. },
  153. {
  154. title: '联系人姓名',
  155. dataIndex: 'contact',
  156. key: 'contact',
  157. },
  158. {
  159. title: '联系人手机号',
  160. dataIndex: 'contactPhone',
  161. key: 'contactPhone',
  162. },
  163. ];
  164. const searchFormSchema: FormSchema[] = [
  165. {
  166. label: '渠道名称',
  167. field: 'pricingName',
  168. component: 'Input',
  169. colProps: {
  170. span: 6,
  171. },
  172. },
  173. {
  174. label: '渠道所属',
  175. field: 'pricingName',
  176. component: 'Input',
  177. colProps: {
  178. span: 6,
  179. },
  180. },
  181. {
  182. label: '状态',
  183. field: 'status',
  184. component: 'Select',
  185. colProps: {
  186. span: 6,
  187. },
  188. componentProps: {
  189. options: [
  190. { label: "全部", value: null },
  191. { label: "启用", value: 1 },
  192. { label: "禁用", value: 0 },
  193. ]
  194. }
  195. },
  196. {
  197. label: '日期范围',
  198. field: 'dateRangeSelect',
  199. component: 'RangeDate',
  200. colProps: {
  201. span: 6,
  202. },
  203. componentProps: {
  204. format: 'YYYY-MM-DD',
  205. placeholder: ['请选择开始日期', '请选择结束日期']
  206. },
  207. },
  208. {
  209. label: '联系人',
  210. field: 'pricingName',
  211. component: 'Input',
  212. colProps: {
  213. span: 6,
  214. },
  215. },
  216. ];
  217. /** useListPage 是整个框架的核心用于表格渲染,里边封装了很多公共方法;
  218. * 平台通过此封装,简化了代码,支持自定义扩展*/
  219. // 通过hook useListPage渲染表格(设置dataSource、columns、actionColumn等参数)
  220. const { tableContext } = useListPage({
  221. designScope: 'basic-table-demo',
  222. tableProps: {
  223. title: '用户列表',
  224. dataSource: [],
  225. columns: columns,
  226. formConfig: {
  227. schemas: searchFormSchema,
  228. showAdvancedButton: false,
  229. // 将表单内时间区域的值映射成 2个字段, 分别是 joinTime_begin 和 joinTime_end
  230. fieldMapToTime: [['dateRangeSelect', ['startDate', 'endDate'], 'YYYY-MM-DD']],
  231. },
  232. api: channelAPI.supplierConfigPageList,
  233. size: 'small',
  234. actionColumn: {
  235. width: 200,
  236. fixed: 'right'
  237. },
  238. },
  239. });
  240. // BasicTable绑定注册
  241. const [registerTable, { reload }] = tableContext;
  242. /**
  243. * 操作栏
  244. */
  245. function getTableAction(record: ActionItem): ActionItem[] {
  246. return [
  247. {
  248. label: '编辑',
  249. onClick: channelConfigEdit.bind(null, record),
  250. },
  251. ];
  252. }
  253. /**
  254. * 下拉操作栏
  255. * @param record 行数据
  256. */
  257. function dropDownAction(record: ActionItem): ActionItem[] {
  258. return [
  259. {
  260. label: '启用',
  261. onClick: channelConfigDisable.bind(null, record),
  262. disabled: record.status == 1,
  263. },
  264. {
  265. label: '禁用',
  266. onClick: channelConfigDisable.bind(null, record),
  267. disabled: record.status == 0,
  268. },
  269. {
  270. label: '删除',
  271. onClick: channelConfigDel.bind(null, record),
  272. },
  273. {
  274. label: '关键信息',
  275. onClick: getKeyInfo.bind(null, record),
  276. },
  277. ];
  278. }
  279. // 新增渠道 - 带参数在新标签页中打开
  280. const channelConfigAdd = () => {
  281. // 定义要传递的参数
  282. // 使用 router.resolve() 解析路由和参数
  283. const routeInfo = router.resolve({
  284. path: "/channel/baseRightsConfig/baseRightsConfigAdd",
  285. });
  286. // 构建完整的 URL
  287. const fullUrl = `${window.location.origin}${routeInfo.href}`;
  288. // 在新标签页中打开
  289. window.open(fullUrl, '_blank');
  290. }
  291. // 关键信息弹窗
  292. const getKeyInfo = (record: ActionItem) => {
  293. channelId.value = record.id;
  294. // 查询关键信息
  295. channelAPI.channelKeyInfo(record.id).then((res) => {
  296. if (res.code == 200) {
  297. keyInfoData.value = res.result;
  298. keyInfoShow.value = true;
  299. } else {
  300. message.error(res.message);
  301. }
  302. })
  303. }
  304. /**
  305. * 启用禁用
  306. * @param record 行数据
  307. */
  308. function channelConfigDisable(record: ActionItem) {
  309. if (record.status == 0) {
  310. channelAPI.supplierConfigEnable({ id: record.id, status: '1' }).then((res) => {
  311. if (res.code == 200) {
  312. reload();
  313. } else {
  314. message.error(res.message);
  315. }
  316. })
  317. } else {
  318. Modal.confirm({
  319. title: '禁用渠道业务',
  320. content: '确定要禁用该渠道业务吗,禁用后,该渠道的发放权益和消费者场景将全部关闭为不可用?',
  321. okText: '确定禁用',
  322. okType: 'danger',
  323. cancelText: '取消',
  324. onOk() {
  325. channelAPI.supplierConfigEnable({ id: record.id, status: '0' }).then((res) => {
  326. if (res.code == 200) {
  327. reload();
  328. } else {
  329. message.error(res.message);
  330. }
  331. })
  332. },
  333. onCancel() {
  334. },
  335. });
  336. }
  337. }
  338. /**
  339. * 广告位编辑
  340. * @param record
  341. */
  342. function channelConfigEdit(record: ActionItem) {
  343. const routeInfo = router.resolve({
  344. path: "/channel/baseRightsConfig/baseRightsConfigAdd",
  345. query: {id: record.id}
  346. });
  347. // 构建完整的 URL
  348. const fullUrl = `${window.location.origin}${routeInfo.href}`;
  349. // 在新标签页中打开
  350. window.open(fullUrl, '_blank');
  351. }
  352. // 删除
  353. const channelConfigDel = (record: ActionItem) => {
  354. Modal.confirm({
  355. title: '删除',
  356. content: '确定要删除该渠道的业务吗?',
  357. okText: '确定删除',
  358. okType: 'danger',
  359. cancelText: '取消',
  360. onOk() {
  361. channelAPI.supplierConfigDel(record.id).then((res) => {
  362. if (res.code == 200) {
  363. message.success(res.message);
  364. reload();
  365. } else {
  366. message.error(res.message);
  367. }
  368. })
  369. },
  370. onCancel() {
  371. },
  372. });
  373. }
  374. // 文本复制
  375. function copyClick(value) {
  376. // 创建input元素
  377. const el = document.createElement('input');
  378. // 给input元素赋值需要复制的文本
  379. el.setAttribute('value', value);
  380. // 将input元素插入页面
  381. document.body.appendChild(el);
  382. // 选中input元素的文本
  383. el.select();
  384. // 复制内容到剪贴板
  385. document.execCommand('copy');
  386. // 删除input元素
  387. document.body.removeChild(el);
  388. message.success('复制成功');
  389. };
  390. const regenerate = () => {
  391. channelAPI.regenerateAppId(channelId.value).then((res) => {
  392. if (res.code == 200) {
  393. message.success('已生成');
  394. channelAPI.channelKeyInfo(channelId.value).then((res) => {
  395. if (res.code == 200) {
  396. keyInfoData.value = res.result;
  397. } else {
  398. message.error(res.message);
  399. }
  400. })
  401. } else {
  402. message.error(res.message);
  403. }
  404. })
  405. }
  406. </script>
  407. <!-- 样式区域 -->
  408. <style lang='less' scoped>
  409. ::v-deep(.jeecg-basic-table .ant-table-wrapper) {
  410. padding: 20px;
  411. height: calc(100% - 10px);
  412. }
  413. ::v-deep(.ant-col) {
  414. width: auto;
  415. }
  416. .keyInfo {
  417. width: 100%;
  418. .label {
  419. width: 150px;
  420. }
  421. .value {
  422. display: flex;
  423. align-items: center;
  424. flex: 1;
  425. }
  426. }
  427. </style>