123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- <!--add by chenguo 2025年7月31日
- 可用于不修改api/*.js 接口,实现前端代码复用
- 通过添加请求前缀的方式访问接口 如:/his/store/productList => [your-prefix]/his/store/productList
- 使用说明:引入组件并指定prefix及componentName(尽可能唯一)
- 添加组件方式:
- <smart-endpoint-toggle-button
- prefix="[your-prefix]"
- component-name="[your-component-name]">
- </smart-endpoint-toggle-button>
- 提供可用的回调
- @afterEndpoint="handleAfterEndpointToggle"
- @beforeEndpoint="handleBeforeEndpointToggle"
- -->
- <template>
- <div class="endpoint-toggle-container">
- <div class="toggle-switch" :class="{ 'new-endpoint': isUsingNewEndpoint }">
- <div class="toggle-option old-endpoint" @click="selectOldEndpoint">
- <span>旧接口</span>
- </div>
- <div class="toggle-option new-endpoint" @click="selectNewEndpoint">
- <span>新接口</span>
- </div>
- <div class="toggle-slider"></div>
- </div>
- </div>
- </template>
- <script>import {
- resetEndpoint, setActive,
- } from '@/utils/request'
- export default {
- name: 'ScrmEndpointButton',
- props: {
- //prefix:加在js请求前的方法
- prefix: {
- type: String,
- required: true
- },
- // 组件名称,用于生成唯一标识
- componentName: {
- type: String,
- required: true
- },
- // 默认选中状态(false表示默认选中旧接口,true表示默认选中新接口)
- defaultNewEndpoint: {
- type: Boolean,
- default: false
- }
- },
- data() {
- return {
- isUsingNewEndpoint: false,
- stateKey: ''
- }
- },
- created() {
- console.log('SmartEndpointToggleButton created');
- // 生成基于组件名和路由的唯一状态键
- this.stateKey = this.generateStateKey()
- // 初始化状态
- this.initializeState()
- },
- activated() {
- console.log('SmartEndpointToggleButton activated,stateKey='+this.stateKey+',prefix='+this.prefix+',is='+this.isUsingNewEndpoint);
- setActive(this.stateKey);
- // 页面激活时恢复状态
- this.restoreState()
- },
- deactivated() {
- console.log('SmartEndpointToggleButton deactivated');
- // 页面失活时保存状态
- this.saveState()
- },
- destroyed() {
- console.log('SmartEndpointToggleButton destroyed');
- // 组件销毁
- resetEndpoint(this.stateKey)
- },
- methods: {
- // 生成状态存储的唯一键
- generateStateKey() {
- const routePath = this.$route ? this.$route.path : ''
- const routeQuery = this.$route && this.$route.query ? JSON.stringify(this.$route.query) : ''
- return `endpoint_toggle_${this.componentName}_${routePath}_${routeQuery}`
- },
- // 初始化状态
- initializeState() {
- setActive(this.stateKey)
- // 默认选中旧接口
- this.isUsingNewEndpoint = this.defaultNewEndpoint
- this.saveState();
- },
- // 保存状态到 sessionStorage
- saveState() {
- try {
- const state = {
- prefix: this.prefix,
- isUsingNewEndpoint: this.isUsingNewEndpoint,
- timestamp: Date.now()
- }
- sessionStorage.setItem(this.stateKey, JSON.stringify(state))
- } catch (e) {
- console.warn('Failed to save endpoint toggle state:', e)
- }
- },
- // 从 sessionStorage 恢复状态
- restoreState() {
- try {
- const stateStr = sessionStorage.getItem(this.stateKey)
- if (stateStr) {
- const state = JSON.parse(stateStr)
- this.isUsingNewEndpoint = state.isUsingNewEndpoint || false
- } else {
- this.isUsingNewEndpoint = this.defaultNewEndpoint
- }
- } catch (e) {
- console.warn('Failed to restore endpoint toggle state:', e)
- this.isUsingNewEndpoint = this.defaultNewEndpoint
- }
- },
- // 选择旧接口
- selectOldEndpoint() {
- if (this.isUsingNewEndpoint) {
- this.toggleEndpointState(false)
- }
- },
- // 选择新接口
- selectNewEndpoint() {
- if (!this.isUsingNewEndpoint) {
- this.toggleEndpointState(true)
- }
- },
- // 切换端点状态
- async toggleEndpointState(newState) {
- // 触发切换前事件
- const beforeResult = this.$emit('beforeEndpoint', this.isUsingNewEndpoint)
- if (beforeResult === false) {
- return
- }
- try {
- // 更新状态
- this.isUsingNewEndpoint = newState
- // 保存状态
- this.saveState()
- // 触发切换后事件
- this.$emit('afterEndpoint', this.isUsingNewEndpoint)
- // 执行回调
- //if (this.$listeners.afterToggle) {
- // await this.$listeners.afterToggle(this.isUsingNewEndpoint)
- //}
- } catch (error) {
- console.error('Failed to toggle endpoint state:', error)
- // 发生错误时回滚状态
- this.isUsingNewEndpoint = !newState
- }
- }
- }
- }
- </script>
- <style scoped>.endpoint-toggle-container {
- display: inline-block;
- vertical-align: middle;
- }
- .toggle-switch {
- position: relative;
- display: flex;
- width: 145px;
- height: 32px;
- background-color: #f5f7fa;
- border-radius: 16px;
- cursor: pointer;
- overflow: hidden;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) inset;
- }
- .toggle-option {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 2;
- transition: color 0.3s ease;
- font-size: 12px;
- font-weight: 500;
- }
- .toggle-option.old-endpoint {
- color: #ffffff;
- }
- .toggle-option.new-endpoint {
- color: #606266;
- }
- .toggle-switch.new-endpoint .toggle-option.old-endpoint {
- color: #606266;
- }
- .toggle-switch.new-endpoint .toggle-option.new-endpoint {
- color: #ffffff;
- }
- .toggle-slider {
- position: absolute;
- top: 2px;
- left: 2px;
- width: calc(50% - 2px);
- height: calc(100% - 4px);
- background-color: #3576f8;
- border-radius: 14px;
- transition: transform 0.3s ease;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
- z-index: 1;
- }
- .toggle-switch.new-endpoint .toggle-slider {
- transform: translateX(100%);
- }
- /* 悬停效果 */
- .toggle-option:hover {
- opacity: 0.6;
- }
- </style>
|