MainView.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. <template>
  2. <ElContainer class="h-full">
  3. <ElAside class="bg-aside" v-if="!isMobile">
  4. <div class="h-16 px-4 flex items-center justify-center cursor-pointer">
  5. <span class="text-lg font-[sh]">{{ title }}</span>
  6. </div>
  7. <SideMenu :default-active="activeMenu" :menus="menus" />
  8. </ElAside>
  9. <ElContainer>
  10. <ElHeader class="!h-16 border-b !box-border border-neutral-200 dark:border-neutral-800 flex items-center">
  11. <div class="p-4 mr-4 cursor-pointer" @click="toggleMenu" v-if="isMobile">
  12. <Menu2 class="w-5 h-5" />
  13. </div>
  14. <el-breadcrumb separator="/">
  15. <el-breadcrumb-item :to="{ path: '/' }">主页</el-breadcrumb-item>
  16. <el-breadcrumb-item v-if="route.name !== 'home'"
  17. >{{ route.meta?.title || route.path }}
  18. </el-breadcrumb-item>
  19. </el-breadcrumb>
  20. <div class="grow"></div>
  21. <ElAlert
  22. type="success"
  23. class="!w-auto !mr-8 invisible md:visible"
  24. :closable="false"
  25. v-if="user.roles.includes('user')"
  26. >
  27. <span>费率: {{ user.rate === '1.00' ? '-' : user.rate }},</span>
  28. <span> 已消费: {{ user.send }},</span>
  29. <span> 余额: {{ user.balance }},</span>
  30. <span> 筛号数量: {{ user.screenBalance }}</span>
  31. </ElAlert>
  32. <ElAlert
  33. type="success"
  34. class="!w-auto !mr-8 invisible md:visible"
  35. :closable="false"
  36. v-if="user.roles.includes('api')"
  37. >
  38. <span>费率: {{ user.rate === '1.00' ? '-' : user.rate }},</span>
  39. <span> 余额: {{ user.balance }}</span>
  40. </ElAlert>
  41. <DarkSwitch class="mr-4" />
  42. <el-dropdown @command="onCommand">
  43. <UserAvatar />
  44. <template #dropdown>
  45. <el-dropdown-menu>
  46. <el-dropdown-item command="changePassword">修改密码</el-dropdown-item>
  47. <el-dropdown-item command="logout">退出登录</el-dropdown-item>
  48. </el-dropdown-menu>
  49. </template>
  50. </el-dropdown>
  51. </ElHeader>
  52. <ElMain class="bg-neutral-50 dark:bg-neutral-900" id="main-container">
  53. <RouterView></RouterView>
  54. </ElMain>
  55. </ElContainer>
  56. <ElDrawer
  57. v-model="showDrawer"
  58. direction="ltr"
  59. size="80%"
  60. v-if="isMobile"
  61. class="!bg-slate-100 dark:!bg-zinc-800"
  62. >
  63. <SideMenu :default-active="activeMenu" :menus="menus" />
  64. </ElDrawer>
  65. <ChangePwd v-model="showChangePwdDialog"></ChangePwd>
  66. </ElContainer>
  67. <div
  68. class="watermark flex flex-wrap justify-between"
  69. v-if="user.username !== 'admin' && user.username !== 'zoumaAdmin'"
  70. >
  71. <span class="item" v-for="n in 200" :key="n">{{ user.username }}</span>
  72. </div>
  73. </template>
  74. <script setup>
  75. import { ElMessageBox } from 'element-plus'
  76. import DarkSwitch from '@/components/DarkSwitch.vue'
  77. import SideMenu from '@/components/SideMenu.vue'
  78. import { useRoute } from 'vue-router'
  79. import { ref, watch, shallowRef, inject } from 'vue'
  80. import { User, Home, Menu2, Settings, MessageDots, DeviceMobileMessage, Language } from '@vicons/tabler'
  81. import UserAvatar from '@/components/UserAvatar.vue'
  82. import ChangePwd from '@/components/ChangePwd.vue'
  83. import { http } from '@/plugins/http'
  84. import { useUserStore } from '@/stores/user'
  85. const title = '47.98.193.71' === location.host ? '悟空传媒' : import.meta.env.VITE_TITLE
  86. const route = useRoute()
  87. const activeMenu = ref(route.path || '/home')
  88. const isMobile = inject('isMobile')
  89. const showDrawer = ref(false)
  90. const { user } = useUserStore()
  91. const roles = user.roles
  92. const invitor = user.invitor
  93. let menus = []
  94. if (roles.includes('admin')) {
  95. menus = [
  96. {
  97. name: '/home',
  98. title: '主页',
  99. icon: Home
  100. },
  101. {
  102. name: 'rcs-parent',
  103. title: 'RCS管理',
  104. icon: DeviceMobileMessage,
  105. children: [
  106. {
  107. name: '/screenList',
  108. title: '筛号列表'
  109. },
  110. {
  111. name: '/phoneList',
  112. title: '发送列表'
  113. },
  114. {
  115. name: '/task',
  116. title: '任务列表'
  117. }
  118. ]
  119. },
  120. {
  121. name: 'sms-parent',
  122. title: 'SMS管理',
  123. icon: DeviceMobileMessage,
  124. children: [
  125. {
  126. name: '/smsPhoneList',
  127. title: '发送列表'
  128. },
  129. {
  130. name: '/smsTask',
  131. title: '短信任务列表'
  132. }
  133. ]
  134. },
  135. {
  136. name: 'user-parent',
  137. title: '用户管理',
  138. icon: User,
  139. children: [
  140. {
  141. name: '/user',
  142. title: '用户总列表'
  143. },
  144. {
  145. name: '/dealer',
  146. title: '发送用户列表'
  147. },
  148. {
  149. name: '/paymentView',
  150. title: '余额充值'
  151. },
  152. {
  153. name: '/balance',
  154. title: '余额明细'
  155. }
  156. ]
  157. },
  158. {
  159. name: 'contryConfig',
  160. title: '国家配置',
  161. icon: Language,
  162. children: [
  163. {
  164. name: '/destConfig',
  165. title: '目标国家'
  166. }
  167. ]
  168. },
  169. {
  170. name: 'settings',
  171. title: '系统设置',
  172. icon: Settings,
  173. children: [
  174. {
  175. name: '/device',
  176. title: '设备列表'
  177. },
  178. {
  179. name: '/channel',
  180. title: '渠道列表'
  181. },
  182. {
  183. name: '/operator',
  184. title: '运营商配置'
  185. },
  186. {
  187. name: '/rcsNumber',
  188. title: 'RCS号码'
  189. },
  190. {
  191. name: '/sysConfig',
  192. title: '参数设置'
  193. },
  194. {
  195. name: '/operationLog',
  196. title: '操作日志'
  197. },
  198. {
  199. name: '/statistics',
  200. title: '统计'
  201. }
  202. ]
  203. }
  204. ]
  205. } else if (roles.includes('superApi')) {
  206. menus = [
  207. {
  208. name: '/home',
  209. title: '主页',
  210. icon: Home
  211. },
  212. {
  213. name: 'rcs-parent',
  214. title: 'RCS管理',
  215. icon: DeviceMobileMessage,
  216. children: [
  217. {
  218. name: '/task',
  219. title: '任务列表'
  220. }
  221. ]
  222. },
  223. {
  224. name: 'user-parent',
  225. title: '用户管理',
  226. icon: User,
  227. children: [
  228. {
  229. name: '/dealer',
  230. title: '用户列表'
  231. },
  232. {
  233. name: '/paymentView',
  234. title: '余额充值'
  235. }
  236. ]
  237. }
  238. ]
  239. } else if (roles.includes('api')) {
  240. menus = [
  241. {
  242. name: '/home',
  243. title: '主页',
  244. icon: Home
  245. },
  246. {
  247. name: 'rcs-parent',
  248. title: 'RCS管理',
  249. icon: DeviceMobileMessage,
  250. children: [
  251. {
  252. name: '/task',
  253. title: '任务列表'
  254. },
  255. {
  256. name: '/paymentView',
  257. title: '余额充值'
  258. }
  259. ]
  260. },
  261. {
  262. name: 'user-parent',
  263. title: '用户管理',
  264. icon: User,
  265. children: [
  266. {
  267. name: '/dealer',
  268. title: '用户列表'
  269. }
  270. ]
  271. }
  272. ]
  273. } else if (roles.includes('user')) {
  274. if (invitor === 25 || invitor === 605 || invitor === 606 || invitor === 698) {
  275. menus = [
  276. {
  277. name: '/home',
  278. title: '主页',
  279. icon: Home
  280. },
  281. {
  282. name: 'rcs-parent',
  283. title: 'RCS管理',
  284. icon: DeviceMobileMessage,
  285. children: [
  286. {
  287. name: '/screenList',
  288. title: '筛号列表'
  289. },
  290. {
  291. name: '/phoneList',
  292. title: '发送列表'
  293. },
  294. {
  295. name: '/task',
  296. title: '任务列表'
  297. },
  298. {
  299. name: '/paymentView',
  300. title: '余额充值'
  301. },
  302. {
  303. name: '/balance',
  304. title: '余额明细'
  305. }
  306. ]
  307. }
  308. ]
  309. } else {
  310. menus = [
  311. {
  312. name: '/home',
  313. title: '主页',
  314. icon: Home
  315. },
  316. {
  317. name: 'rcs-parent',
  318. title: 'RCS管理',
  319. icon: DeviceMobileMessage,
  320. children: [
  321. {
  322. name: '/screenList',
  323. title: '筛号列表'
  324. },
  325. {
  326. name: '/phoneList',
  327. title: '发送列表'
  328. },
  329. {
  330. name: '/task',
  331. title: '任务列表'
  332. },
  333. {
  334. name: '/balance',
  335. title: '余额明细'
  336. }
  337. ]
  338. }
  339. ]
  340. }
  341. }
  342. function toggleMenu() {
  343. showDrawer.value = !showDrawer.value
  344. }
  345. watch(route, () => {
  346. activeMenu.value = route.name
  347. })
  348. const showChangePwdDialog = ref(false)
  349. function onCommand(cmd) {
  350. if (cmd === 'logout') {
  351. logout()
  352. } else if (cmd === 'changePassword') {
  353. showChangePwdDialog.value = true
  354. }
  355. }
  356. function logout() {
  357. ElMessageBox.confirm('确定退出登录吗?', '提示', {
  358. confirmButtonText: '确定',
  359. cancelButtonText: '取消',
  360. type: 'warning'
  361. }).then(() => {
  362. http.setToken(null)
  363. location.reload()
  364. })
  365. }
  366. </script>
  367. <style lang="less" scoped>
  368. .watermark {
  369. position: fixed;
  370. top: 0;
  371. left: 0;
  372. right: 0;
  373. bottom: 0;
  374. background-repeat: repeat;
  375. opacity: 0.05;
  376. pointer-events: none;
  377. font-size: 50px;
  378. z-index: 9;
  379. .item {
  380. display: inline-block;
  381. padding: 20px;
  382. transform: rotate(-30deg);
  383. }
  384. }
  385. </style>