混凝土运输管理微信小程序、替班
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

262 lines
5.4 KiB

1 week ago
  1. <template>
  2. <view class="roleSelector">
  3. <uv-popup ref="popup" :round="30" :customStyle="{height: '60vh'}">
  4. <view class="content">
  5. <view class="header">
  6. <view class="title">选择身份</view>
  7. <view class="close-btn" @click="close">
  8. <uv-icon name="close" size="20" color="#999"></uv-icon>
  9. </view>
  10. </view>
  11. <view class="role-tip">请选择您的身份类型</view>
  12. <view class="role-list">
  13. <view
  14. v-for="(role, index) in roleOptions"
  15. :key="index"
  16. :class="['role-item', selectedRole === role.value && 'active']"
  17. @click="selectRole(role.value)">
  18. <view class="role-icon">
  19. <uv-icon :name="getRoleIcon(role.value)" size="20" :color="selectedRole === role.value ? '#007AFF' : '#666'"></uv-icon>
  20. </view>
  21. <view class="role-info">
  22. <view class="role-name">{{ role.label }}</view>
  23. <view class="role-desc">{{ getRoleDesc(role.value) }}</view>
  24. </view>
  25. <view class="role-check">
  26. <uv-icon v-if="selectedRole === role.value" name="checkmark-circle" size="20" color="#007AFF"></uv-icon>
  27. <uv-icon v-else name="close-circle" size="20" color="#ccc"></uv-icon>
  28. </view>
  29. </view>
  30. </view>
  31. <view class="action-buttons">
  32. <view class="btn cancel" @click="close">取消</view>
  33. <view class="btn confirm" @click="confirmRoleChange">确认</view>
  34. </view>
  35. </view>
  36. </uv-popup>
  37. </view>
  38. </template>
  39. <script>
  40. import { mapState, mapGetters, mapMutations } from 'vuex'
  41. export default {
  42. name: 'RoleSelector',
  43. data() {
  44. return {
  45. selectedRole: '0'
  46. }
  47. },
  48. computed: {
  49. ...mapState(['role']),
  50. ...mapGetters(['getRoleOptions']),
  51. roleOptions() {
  52. return this.getRoleOptions;
  53. }
  54. },
  55. methods: {
  56. ...mapMutations(['switchRole']),
  57. // 打开角色选择弹窗
  58. open() {
  59. this.selectedRole = this.role;
  60. this.$refs.popup.open('bottom');
  61. },
  62. // 关闭弹窗
  63. close() {
  64. this.$refs.popup.close();
  65. },
  66. // 选择角色
  67. selectRole(roleValue) {
  68. this.selectedRole = roleValue;
  69. },
  70. // 确认角色切换
  71. confirmRoleChange() {
  72. if (this.selectedRole !== this.role) {
  73. // 使用Vuex mutation切换角色
  74. this.switchRole(this.selectedRole);
  75. uni.showToast({
  76. title: `已切换到${this.getCurrentRoleText(this.selectedRole)}`,
  77. icon: 'success'
  78. });
  79. // 触发父组件事件
  80. this.$emit('roleChanged', this.selectedRole);
  81. }
  82. this.close();
  83. },
  84. // 获取角色图标
  85. getRoleIcon(roleValue) {
  86. switch(roleValue) {
  87. case '0': return 'man';
  88. case '1': return 'bag';
  89. case '2': return 'man-add';
  90. case '3': return 'setting';
  91. default: return 'man';
  92. }
  93. },
  94. // 获取角色描述
  95. getRoleDesc(roleValue) {
  96. switch(roleValue) {
  97. case '0': return '接单赚钱,自由工作';
  98. case '1': return '发布订单,管理业务';
  99. case '2': return '协助管理,处理订单';
  100. case '3': return '区域管理,审核订单';
  101. default: return '';
  102. }
  103. },
  104. // 获取当前角色文本
  105. getCurrentRoleText(roleValue) {
  106. const role = this.roleOptions.find(r => r.value === roleValue);
  107. return role ? role.label : '用户/泵司';
  108. }
  109. }
  110. }
  111. </script>
  112. <style lang="scss" scoped>
  113. .roleSelector {
  114. .content {
  115. padding: 30rpx 20rpx;
  116. height: 100%;
  117. box-sizing: border-box;
  118. display: flex;
  119. flex-direction: column;
  120. }
  121. .header {
  122. display: flex;
  123. justify-content: space-between;
  124. align-items: center;
  125. margin-bottom: 30rpx;
  126. padding-bottom: 20rpx;
  127. border-bottom: 1rpx solid #f0f0f0;
  128. .title {
  129. font-size: 32rpx;
  130. font-weight: bold;
  131. color: #333;
  132. }
  133. .close-btn {
  134. padding: 10rpx;
  135. cursor: pointer;
  136. }
  137. }
  138. .role-tip {
  139. font-size: 28rpx;
  140. color: #666;
  141. margin-bottom: 30rpx;
  142. text-align: center;
  143. }
  144. .role-list {
  145. flex: 1;
  146. display: flex;
  147. flex-direction: column;
  148. gap: 20rpx;
  149. margin-bottom: 40rpx;
  150. }
  151. .role-item {
  152. display: flex;
  153. align-items: center;
  154. padding: 25rpx 20rpx;
  155. border-radius: 15rpx;
  156. border: 2rpx solid #f0f0f0;
  157. transition: all 0.3s ease;
  158. cursor: pointer;
  159. &.active {
  160. border-color: #007AFF;
  161. background-color: #f0f8ff;
  162. }
  163. &:hover {
  164. background-color: #f8f8f8;
  165. }
  166. }
  167. .role-icon {
  168. width: 60rpx;
  169. height: 60rpx;
  170. border-radius: 30rpx;
  171. background-color: #f5f5f5;
  172. display: flex;
  173. align-items: center;
  174. justify-content: center;
  175. margin-right: 20rpx;
  176. }
  177. .role-info {
  178. flex: 1;
  179. }
  180. .role-name {
  181. font-size: 30rpx;
  182. font-weight: bold;
  183. color: #333;
  184. margin-bottom: 8rpx;
  185. }
  186. .role-desc {
  187. font-size: 24rpx;
  188. color: #999;
  189. line-height: 1.4;
  190. }
  191. .role-check {
  192. width: 40rpx;
  193. height: 40rpx;
  194. display: flex;
  195. align-items: center;
  196. justify-content: center;
  197. }
  198. .action-buttons {
  199. display: flex;
  200. gap: 20rpx;
  201. padding-top: 20rpx;
  202. border-top: 1rpx solid #f0f0f0;
  203. .btn {
  204. flex: 1;
  205. height: 80rpx;
  206. border-radius: 40rpx;
  207. display: flex;
  208. align-items: center;
  209. justify-content: center;
  210. font-size: 28rpx;
  211. cursor: pointer;
  212. transition: all 0.3s ease;
  213. &.cancel {
  214. background-color: #f5f5f5;
  215. color: #666;
  216. &:hover {
  217. background-color: #e8e8e8;
  218. }
  219. }
  220. &.confirm {
  221. background-color: #007AFF;
  222. color: #fff;
  223. &:hover {
  224. background-color: #0056CC;
  225. }
  226. }
  227. }
  228. }
  229. }
  230. </style>