subsList.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. <template>
  2. <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
  3. <cwg-header :title="t('Ib.Custom.Manage2')" />
  4. <view class="account-content">
  5. <!-- 移动端:按钮在筛选上方 -->
  6. <cwg-match-media :max-width="991">
  7. <view class="search-content mobile-search-content">
  8. <view class="search-bar mobile-add-btn-wrap">
  9. <button hover-class="" type="primary" class="search-button" @click="addSub">
  10. <cwg-icon name="icon_add" :size="18" color="#fff"></cwg-icon>
  11. {{ t('Ib.Report.Title5') }}
  12. </button>
  13. </view>
  14. <view class="search-bar">
  15. <cwg-complex-search :fields="filterFields" v-model="searchParams" @search="handleSearch"
  16. @reset="handleReset" />
  17. </view>
  18. </view>
  19. </cwg-match-media>
  20. <!-- PC端:按钮和筛选在同一行 -->
  21. <cwg-match-media :min-width="991">
  22. <view class="search-content pc-search-content">
  23. <view class="search-bar">
  24. <cwg-complex-search :fields="filterFields" v-model="searchParams" @search="handleSearch"
  25. @reset="handleReset" noData />
  26. </view>
  27. <view class="search-bar">
  28. <button hover-class="" type="primary" class="search-button" @click="addSub">
  29. <cwg-icon name="icon_add" :size="18" color="#fff"></cwg-icon>
  30. {{ t('Ib.Report.Title5') }}
  31. </button>
  32. </view>
  33. </view>
  34. </cwg-match-media>
  35. <cwg-tabel ref="tableRef" :columns="columns" :mobilePrimaryFields="mobilePrimaryFields" :queryParams="search"
  36. :api="listApi" :show-operation="true" :showPagination="true">
  37. </cwg-tabel>
  38. </view>
  39. <ApplyIbDialog ref="applyIbDialogRef" :visible="applyVisible" @close="closeApplyIb" @confirm="confirmApply"
  40. :title="formDia ? 'Ib.Report.Title5' : 'Ib.Custom.Commit3'" :isFormApplyIb="formDia" :paramsType="applyType"
  41. :detail="applyDetail" />
  42. <cwg-popup :visible="exclusiveVisible" :title="t('Ib.Custom.Commit5')" :cancelText="t('Btn.Cancel')"
  43. :confirmText="t('Btn.Confirm')" @close="cancelExclusiveCommission" @confirm="confirmExclusiveCommission">
  44. <view class="dia-content">
  45. <uni-forms ref="exclusiveCommissionFormRef" labelWidth="240">
  46. <uni-forms-item :label="t('Ib.Custom.Commit5')" prop="selectedPoint">
  47. <cwg-combox v-model:value="exclusiveCommissionForm.selectedPoint"
  48. :options="exclusiveCommissionForm.pointOptions" :placeholder="t('placeholder.choose')" />
  49. </uni-forms-item>
  50. </uni-forms>
  51. </view>
  52. </cwg-popup>
  53. </cwg-page-wrapper>
  54. </template>
  55. <script setup lang="ts">
  56. // 代理管理
  57. import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
  58. import { onLoad } from '@dcloudio/uni-app'
  59. import { useI18n } from 'vue-i18n' // uni-app 中已集成,但需配置
  60. import { customApi } from '@/service/custom'
  61. import { financialApi } from '@/service/financial'
  62. import Config from '@/config/index'
  63. import { ibApi } from '@/service/ib'
  64. import { useFilters } from '@/composables/useFilters'
  65. import ApplyIbDialog from '@/pages/ib/components/applyIbDialog.vue'
  66. import { nextTick } from 'vue'
  67. const { numberFormat, numberDecimal } = useFilters()
  68. const { t, locale } = useI18n()
  69. const { Code } = Config
  70. const searchParams = ref({})
  71. const search = reactive({
  72. ibNo: '',
  73. name: '',
  74. cId: '',
  75. })
  76. const filterFields = computed(() => [
  77. { key: 'ibNo', type: 'input', label: t('Label.IbAccount'), placeholder: t('Label.IbAccount'), defaultValue: '' },
  78. {
  79. key: 'name',
  80. type: 'input',
  81. label: t('Ib.Custom.NameLabel'),
  82. placeholder: t('Ib.Custom.NameLabel'),
  83. defaultValue: '',
  84. },
  85. { key: 'cId', type: 'input', label: 'CID', placeholder: 'CID', defaultValue: '' },
  86. { key: 'date', label: t('placeholder.Start') + ' - ' + t('placeholder.End'), type: 'daterange', defaultValue: ['', ''] },
  87. ])
  88. const tableRef = ref(null)
  89. const applyIbDialogRef = ref(null)
  90. const applyVisible = ref(false)
  91. const applyType = ref('')
  92. const applyDetail = ref()
  93. const formDia = ref(false)
  94. const exclusiveVisible = ref(false)
  95. const exclusiveCommissionFormRef = ref(null)
  96. const exclusiveCommissionForm = ref({
  97. agentId: '',
  98. selectedPoint: '',
  99. pointOptions: [],
  100. })
  101. const exclusiveRow = ref<any>(null)
  102. // 表格列配置
  103. const columns = computed(() => [
  104. {
  105. prop: 'cId',
  106. label: t('Label.CidAccount'),
  107. align: 'center',
  108. },
  109. {
  110. prop: 'ibNo',
  111. label: t('Label.IbAccount'),
  112. align: 'center',
  113. },
  114. {
  115. prop: 'name',
  116. label: t('Ib.Custom.NameLabel'),
  117. align: 'center',
  118. },
  119. {
  120. prop: 'agentNum',
  121. label: t('Ib.Custom.AgentNum'),
  122. align: 'center',
  123. },
  124. {
  125. prop: 'customNum',
  126. label: t('Ib.Custom.CustomerNum'),
  127. align: 'center',
  128. },
  129. {
  130. prop: 'addTime',
  131. label: t('Label.ApplyTime'),
  132. align: 'center',
  133. },
  134. {
  135. prop: 'lastTime',
  136. label: t('Ib.Custom.LastActiveTime'),
  137. align: 'center',
  138. },
  139. {
  140. prop: 'action',
  141. label: t('Label.Action'),
  142. type: 'action',
  143. align: 'center',
  144. menuList: [
  145. {
  146. label: t('Ib.Custom.Commit3'),
  147. type: 'vietnamDistribution',
  148. btnClick: (row) => handleMenuClick({ type: 'vietnamDistribution', row }),
  149. show: true,
  150. },
  151. {
  152. label: t('Ib.Custom.Commit5'),
  153. type: 'exclusiveCommission',
  154. btnClick: (row) => handleMenuClick({ type: 'exclusiveCommission', row }),
  155. show: (row) => row.exclusiveCommissionOptions?.length > 0,
  156. },
  157. ],
  158. },
  159. ])
  160. const mobilePrimaryFields = computed(() => [
  161. {
  162. prop: 'cId',
  163. label: t('Label.CidAccount'),
  164. align: 'center',
  165. },
  166. {
  167. prop: 'ibNo',
  168. label: t('Label.IbAccount'),
  169. align: 'center',
  170. },
  171. {
  172. prop: 'name',
  173. label: t('Ib.Custom.NameLabel'),
  174. align: 'center',
  175. },
  176. {
  177. prop: 'more',
  178. type: 'more',
  179. width: 20,
  180. align: 'right',
  181. },
  182. ])
  183. const listApi = ref(ibApi.IbSubs)
  184. const handleSearch = (params: any) => {
  185. // 拦截处理 daterange,将 date 拆分为 startDate 和 endDate
  186. console.log(params)
  187. const payload = { ...params }
  188. Object.assign(search, payload)
  189. nextTick(() => {
  190. tableRef.value.refreshTable()
  191. })
  192. }
  193. const handleReset = (params: any) => {
  194. Object.assign(search, params)
  195. nextTick(() => {
  196. tableRef.value.refreshTable()
  197. })
  198. }
  199. onMounted(() => {
  200. // applyVisible.value = true
  201. })
  202. const handleMenuClick = (item) => {
  203. if (item.type == 'vietnamDistribution') {
  204. const { agentId, id } = item.row
  205. applyDetail.value = {
  206. id: id || agentId,
  207. }
  208. formDia.value = false
  209. applyType.value = 'vietnam'
  210. applyVisible.value = true
  211. } else if (item.type == 'exclusiveCommission') {
  212. openExclusiveCommission(item.row)
  213. }
  214. }
  215. const addSub = () => {
  216. formDia.value = true
  217. applyVisible.value = true
  218. }
  219. const closeApplyIb = () => {
  220. applyDetail.value = {}
  221. applyVisible.value = false
  222. }
  223. const confirmApply = (data) => {
  224. tableRef.value.refreshTable()
  225. }
  226. const normalizePointOptions = (options: any[]) => {
  227. if (!Array.isArray(options)) return []
  228. return options.map((o: any) => ({
  229. text: o.label ?? o.text ?? o.name ?? String(o.value ?? ''),
  230. value: o.value,
  231. }))
  232. }
  233. const openExclusiveCommission = async (row: any) => {
  234. exclusiveCommissionForm.value.agentId = row.id
  235. exclusiveCommissionForm.value.selectedPoint = ''
  236. exclusiveCommissionForm.value.pointOptions = normalizePointOptions(row?.exclusiveCommissionOptions || [])
  237. exclusiveVisible.value = true
  238. }
  239. const cancelExclusiveCommission = () => {
  240. exclusiveVisible.value = false
  241. exclusiveCommissionForm.value.selectedPoint = ''
  242. exclusiveCommissionForm.value.pointOptions = []
  243. }
  244. const confirmExclusiveCommission = async () => {
  245. try {
  246. const res = await ibApi.agentHiddenPointAdd({
  247. agentId: exclusiveCommissionForm.value.agentId,
  248. point: [{ value: exclusiveCommissionForm.value.selectedPoint }],
  249. })
  250. if (res.code == Code.StatusOK) {
  251. cancelExclusiveCommission()
  252. tableRef.value?.refreshTable?.()
  253. }
  254. } catch (e) {
  255. }
  256. }
  257. </script>
  258. <style lang="scss" scoped>
  259. @import "@/uni.scss";
  260. .search-content {
  261. display: flex;
  262. }
  263. /* PC 端对齐方式 */
  264. .pc-search-content {
  265. justify-content: space-between;
  266. align-items: flex-start;
  267. margin-bottom: px2rpx(10);
  268. }
  269. /* 移动端排版方式 */
  270. .mobile-search-content {
  271. flex-direction: column;
  272. margin-bottom: px2rpx(10);
  273. .mobile-add-btn-wrap {
  274. display: flex;
  275. justify-content: flex-end;
  276. width: 100%;
  277. margin-bottom: px2rpx(10);
  278. .search-button {
  279. background-color: var(--bs-secondary);
  280. margin: 0 0 0 auto;
  281. /* 强制按钮靠右且消除其它 margin */
  282. }
  283. }
  284. }
  285. .search-button {
  286. display: flex;
  287. align-items: center;
  288. background-color: var(--bs-secondary);
  289. line-height: px2rpx(36);
  290. min-width: px2rpx(120);
  291. border-radius: px2rpx(8);
  292. }
  293. </style>