master
飘泊客 9 months ago
parent 22da3e9c8d
commit 65f6494499

@ -6,5 +6,7 @@
# @FilePath: \byhl-zt-app\.env.development
# @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
###
VITE_SERVICE_ENV = dev
VITE_APP_BASE_API = '/api'
VITE_SERVICE_ENV = development
VITE_APP_BASEURL = '/api'
VITE_APP_SERVER_URL = 'https://byffp.top'
VITE_APP_IMG_UTL = 'https://byffp.top/avatar/'

@ -1,2 +1,4 @@
VITE_SERVICE_ENV = prod
VITE_APP_BASE_API = '/api'
VITE_SERVICE_ENV = production
VITE_APP_BASEURL = '/api'
VITE_APP_SERVER_URL = 'https://byffp.top'
VITE_APP_IMG_UTL = 'https://byffp.top/avatar/'

@ -1,16 +1,25 @@
{ // launch.json configurations app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtypelocalremote, localremote
"version": "0.0",
"configurations": [{
"app-plus" :
{
"launchtype" : "local"
},
"default" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
{
// launch.json configurations app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtypelocalremote, localremote
"version" : "0.0",
"configurations" : [
{
"app-plus" : {
"launchtype" : "local"
},
"default" : {
"launchtype" : "local"
},
"type" : "uniCloud"
},
{
"openVueDevtools" : false,
"playground" : "standard",
"type" : "uni-app:app-android"
},
{
"openVueDevtools" : false,
"type" : "uni-app:app-ios"
}
]
}

4
auto-imports.d.ts vendored

@ -69,7 +69,6 @@ declare global {
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const resolveDirective: typeof import('vue')['resolveDirective']
const setActivePinia: typeof import('pinia')['setActivePinia']
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
const shallowReactive: typeof import('vue')['shallowReactive']
@ -92,7 +91,7 @@ declare global {
}
// for vue template auto import
import { UnwrapRef } from 'vue'
declare module 'vue' {
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
@ -162,7 +161,6 @@ declare module 'vue' {
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly resolveDirective: UnwrapRef<typeof import('vue')['resolveDirective']>
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>

15
components.d.ts vendored

@ -14,21 +14,6 @@ declare module 'vue' {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SliderCaptcha: typeof import('./src/components/Captcha/SliderCaptcha.vue')['default']
VanActionSheet: typeof import('vant/es')['ActionSheet']
VanButton: typeof import('vant/es')['Button']
VanCalendar: typeof import('vant/es')['Calendar']
VanCell: typeof import('vant/es')['Cell']
VanCellGroup: typeof import('vant/es')['CellGroup']
VanField: typeof import('vant/es')['Field']
VanForm: typeof import('vant/es')['Form']
VanIcon: typeof import('vant/es')['Icon']
VanList: typeof import('vant/es')['List']
VanNavBar: typeof import('vant/es')['NavBar']
VanPicker: typeof import('vant/es')['Picker']
VanPopup: typeof import('vant/es')['Popup']
VanSearch: typeof import('vant/es')['Search']
VanSticky: typeof import('vant/es')['Sticky']
VanTag: typeof import('vant/es')['Tag']
WordClickCaptcha: typeof import('./src/components/Captcha/WordClickCaptcha.vue')['default']
}
}

@ -46,9 +46,10 @@
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-3050420220804004",
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3050420220804004",
"@dcloudio/uni-ui": "^1.4.20",
"@uni-helper/axios-adapter": "^1.5.2",
"axios": "^1.4.0",
"crypto-js": "^4.1.1",
"lodash": "1.3.1",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"pinia": "^2.0.36",
"pinia-plugin-persistedstate": "^3.2.0",

@ -44,6 +44,9 @@ dependencies:
'@dcloudio/uni-ui':
specifier: ^1.4.20
version: 1.4.20
'@uni-helper/axios-adapter':
specifier: ^1.5.2
version: 1.5.2(axios@1.4.0)
axios:
specifier: ^1.4.0
version: 1.4.0
@ -51,8 +54,8 @@ dependencies:
specifier: ^4.1.1
version: 4.1.1
lodash:
specifier: 1.3.1
version: 1.3.1
specifier: ^4.17.21
version: 4.17.21
moment:
specifier: ^2.29.4
version: 2.29.4
@ -69,7 +72,7 @@ dependencies:
specifier: ^3.2.37
version: 3.2.37
vue-i18n:
specifier: ^9.2.2
specifier: ^9.1.9
version: 9.2.2(vue@3.2.37)
devDependencies:
@ -77,7 +80,7 @@ devDependencies:
specifier: ^0.25.2
version: 0.25.2(eslint@8.21.0)(typescript@4.7.4)
'@dcloudio/types':
specifier: ^3.0.13
specifier: ^3.0.7
version: 3.0.13
'@dcloudio/uni-automator':
specifier: 3.0.0-alpha-3050420220804004
@ -1106,7 +1109,7 @@ packages:
'@iconify/types': 1.1.0
debug: 4.3.4
kolorist: 1.5.1
local-pkg: 0.4.2
local-pkg: 0.4.3
transitivePeerDependencies:
- supports-color
dev: true
@ -1500,6 +1503,16 @@ packages:
eslint-visitor-keys: 3.3.0
dev: true
/@uni-helper/axios-adapter@1.5.2(axios@1.4.0):
resolution: {integrity: sha512-0NUHqVpC2a2KoT855csKhA2nV5bhGtIW9SUSyfZ248PmAsRsrnRjzygEeR/1IDGM6cbHdyAFGAdPtA/mwgC6Dg==}
peerDependencies:
axios: ^1.5.0
dependencies:
axios: 1.4.0
local-pkg: 0.4.3
unplugin: 1.5.1
dev: false
/@unocss/cli@0.45.5:
resolution: {integrity: sha512-gB/XZ6ksS/le1r33JhLam7UtJhd2fvtbgYV2rU76DOoqIa+qCZFbrMDFyF+PJz6yCW0goYF9ybtZXND42aygZQ==}
engines: {node: '>=14'}
@ -1750,10 +1763,6 @@ packages:
'@vue/compiler-dom': 3.2.37
'@vue/shared': 3.2.37
/@vue/devtools-api@6.2.1:
resolution: {integrity: sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ==}
dev: false
/@vue/devtools-api@6.5.1:
resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==}
dev: false
@ -1927,6 +1936,14 @@ packages:
acorn: 8.11.2
dev: true
/acorn-jsx@5.3.2(acorn@8.11.2):
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
acorn: 8.11.2
dev: true
/acorn-jsx@5.3.2(acorn@8.8.0):
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@ -1939,7 +1956,6 @@ packages:
resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
/acorn@8.8.0:
resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
@ -3386,8 +3402,8 @@ packages:
resolution: {integrity: sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
acorn: 8.8.0
acorn-jsx: 5.3.2(acorn@8.8.0)
acorn: 8.11.2
acorn-jsx: 5.3.2(acorn@8.11.2)
eslint-visitor-keys: 3.3.0
dev: true
@ -3830,7 +3846,6 @@ packages:
/graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
dev: true
/grapheme-splitter@1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
@ -4362,7 +4377,7 @@ packages:
dependencies:
universalify: 2.0.0
optionalDependencies:
graceful-fs: 4.2.10
graceful-fs: 4.2.11
/jsx-ast-utils@3.3.2:
resolution: {integrity: sha512-4ZCADZHRkno244xlNnn4AOG6sRQ7iBZ5BbgZ4vW4y5IZw7cVUD1PPeblm1xx/nfmMxPdt/LHsXZW8z/j58+l9Q==}
@ -4466,7 +4481,6 @@ packages:
/local-pkg@0.4.3:
resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
engines: {node: '>=14'}
dev: true
/localstorage-polyfill@1.0.1:
resolution: {integrity: sha512-m4iHVZxFH5734oQcPKU08025gIz2+4bjWR9lulP8ZYxEJR0BpA0w32oJmkzh8y3UI9ci7xCBehQDc3oA1X+VHw==}
@ -4502,14 +4516,8 @@ packages:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
/lodash@1.3.1:
resolution: {integrity: sha512-F7AB8u+6d00CCgnbjWzq9fFLpzOMCgq6mPjOW4+8+dYbrnc0obRrC+IHctzfZ1KKTQxX0xo/punrlpOWcf4gpw==}
engines: {'0': node, '1': rhino}
dev: false
/lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: true
/loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
@ -4705,7 +4713,7 @@ packages:
/mlly@0.5.7:
resolution: {integrity: sha512-rz+n2i9862ymLH+UDlHpsuTVyCIAs+9WejS2De2VUlAKdpq8OJ9x/C2M7nNUMLEW1H+D6n0uZlpz8+tMGxCmyQ==}
dependencies:
acorn: 8.8.0
acorn: 8.11.2
pathe: 0.3.3
pkg-types: 0.3.3
dev: true
@ -5913,7 +5921,7 @@ packages:
/strip-literal@0.4.0:
resolution: {integrity: sha512-ql/sBDoJOybTKSIOWrrh8kgUEMjXMwRAkZTD0EwiwxQH/6tTPkZvMIEjp0CRlpi6V5FMiJyvxeRkEi1KrGISoA==}
dependencies:
acorn: 8.8.0
acorn: 8.11.2
dev: true
/supports-color@2.0.0:
@ -6180,7 +6188,7 @@ packages:
'@rollup/pluginutils': 4.2.1
escape-string-regexp: 5.0.0
fast-glob: 3.2.11
local-pkg: 0.4.2
local-pkg: 0.4.3
magic-string: 0.26.2
mlly: 0.5.7
pathe: 0.3.3
@ -6374,7 +6382,6 @@ packages:
chokidar: 3.5.3
webpack-sources: 3.2.3
webpack-virtual-modules: 0.6.0
dev: true
/unquote@1.1.1:
resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==}
@ -6544,7 +6551,7 @@ packages:
'@intlify/core-base': 9.2.2
'@intlify/shared': 9.2.2
'@intlify/vue-devtools': 9.2.2
'@vue/devtools-api': 6.2.1
'@vue/devtools-api': 6.5.1
vue: 3.2.37
dev: false
@ -6553,7 +6560,7 @@ packages:
peerDependencies:
vue: ^3.2.0
dependencies:
'@vue/devtools-api': 6.2.1
'@vue/devtools-api': 6.5.1
vue: 3.2.37
dev: false
@ -6577,7 +6584,6 @@ packages:
/webpack-sources@3.2.3:
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
engines: {node: '>=10.13.0'}
dev: true
/webpack-virtual-modules@0.4.4:
resolution: {integrity: sha512-h9atBP/bsZohWpHnr+2sic8Iecb60GxftXsWNLLLSqewgIsGzByd2gcIID4nXcG+3tNe4GQG3dLcff3kXupdRA==}
@ -6585,7 +6591,6 @@ packages:
/webpack-virtual-modules@0.6.0:
resolution: {integrity: sha512-KnaMTE6EItz/f2q4Gwg5/rmeKVi79OR58NoYnwDJqCk9ywMtTGbBnBcfoBtN4QbYu0lWXvyMoH2Owxuhe4qI6Q==}
dev: true
/webpack@5.89.0:
resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==}

@ -1,11 +1,3 @@
<!--
* @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Date: 2023-07-28 16:10:52
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @LastEditTime: 2023-08-01 18:05:55
* @FilePath: \byhl-zt-app\src\App.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import {
Navigate
@ -14,7 +6,6 @@
getToken
} from "@/utils/Storage";
import socket from "@/utils/socketTask";
import ws from "@/utils/socketTask";
const checkLogin = () => {
if (!getToken) {
Navigate.redirect('/pages/login')

@ -0,0 +1,80 @@
import request from '@/utils/request'
import type {
HomeSearchPage,
PageParams,
editClue,
AssetsPage
} from '@/types/consult'
import type { OAuth2LoginParam, CaptchaConfig } from '@/components/Captcha/types'
import { LoginResult, LoginObj } from '@/types/user'
const BASIC_AUTHORIZATION = 'Basic dWk6dWk='
// 正式环境baseUrl = /api
const baseUrl = '/api'
export interface CaptchaData {
id: string
captcha: {
backgroundImage: string
templateImage: string
backgroundImageWidth: number
backgroundImageHeight: number
sliderImageWidth: number
sliderImageHeight: number
data: {
randomY?: string
}
}
}
export const loginAPI = (mobile: string, password: string) => {
return request.post(baseUrl + 'login/password', {
mobile,
password
})
}
/**
*
* @param parameter
*/
export function accountLogin(parameter: OAuth2LoginParam) {
return request<LoginResult>({
url: baseUrl + '/oauth2/token',
method: 'POST',
headers: {
Authorization: BASIC_AUTHORIZATION
},
params: parameter
})
}
/**
*
* @returns
*/
export function getCodeData() {
return request.get<LoginObj>(baseUrl + '/captcha/code')
}
/**
*
* @param id id
* @param data true:/false:
* @returns
*/
export function captchaCheck(id: string, data: CaptchaConfig) {
return request.post<boolean>(baseUrl + '/captcha/tianai/check', data, { params: { id } })
}
// 资源列表
export const getKnowledgePage = (params: HomeSearchPage) =>
request.get<AssetsPage>(baseUrl + '/clue/page', { params })
// 资源详情-id
export const getDetails = (id: number) =>
request.get<any>(baseUrl + '/clue/details/' + id )
// 资源编辑
export const editClueUpdate = (data: any) =>
request.post<any>(baseUrl + '/clue/update', data)
export const getReadCount = () =>
request.get<any>(baseUrl + '/notify/user-announcement/not/read/count')
// export const getDoctorPage = (params: PageParams) =>
// request.get<DoctorPage>('/home/page/doc', { params })

@ -6,7 +6,7 @@
* @FilePath: \byhl-zt-app\src\api\login.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import request from '@/utils/request'
import request from '@/utils/request'
import type { OAuth2LoginParam } from '@/components/Captcha/types'
import { LoginResult, LoginObj } from '@/types/user'
const BASIC_AUTHORIZATION = 'Basic dWk6dWk='

@ -24,7 +24,7 @@
<script setup lang="ts">
import { ref, computed, nextTick } from 'vue'
import { captchaCheck, type CaptchaData, captchaGen } from '@/api/captcha'
import { captchaCheck, type CaptchaData, captchaGen } from '@/api/index'
import type { CaptchaConfig } from '@/components/Captcha/types'
import { useCaptcha } from '@/components/Captcha/useCaptcha'
import type { CSSProperties } from 'vue'

@ -32,7 +32,7 @@
</template>
<script setup lang="ts">
import { captchaGen, captchaCheck, type CaptchaData } from '@/api/captcha'
import { captchaGen, captchaCheck, type CaptchaData } from '@/api/index'
import type { CaptchaConfig } from '@/components/Captcha/types'
import { useCaptcha } from '@/components/Captcha/useCaptcha'
import type { CSSProperties } from 'vue'

@ -32,7 +32,7 @@
</template>
<script setup lang="ts">
import { captchaGen, captchaCheck, type CaptchaData } from '@/api/captcha'
import { captchaGen, captchaCheck, type CaptchaData } from '@/api/index'
import type { CaptchaConfig } from '@/components/Captcha/types'
import { useCaptcha } from '@/components/Captcha/useCaptcha'
import type { CSSProperties } from 'vue'

@ -29,7 +29,7 @@
</template>
<script setup lang="ts">
import { captchaGen, captchaCheck, type CaptchaData } from '@/api/captcha'
import { captchaGen, captchaCheck, type CaptchaData } from '@/api/index'
import type { CaptchaConfig, Track } from '@/components/Captcha/types'
const props = defineProps<{

@ -1,63 +1,20 @@
<script setup lang="ts">
import CpIcon from '@/components/CpIcon.vue';
import { parseTime } from '@/utils/index'
import { Modal } from '@/plugins/Modal'
import {
ref
} from 'vue'
import type {
AssetsList,
HomeSearchPage
} from '@/types/consult'
import {
getKnowledgePage
} from '@/api/home'
interface SearchObj {
nid?: string
searchDate?: string
list: any[]
loading: boolean
finished: boolean
}
const props = defineProps<SearchObj>()
// const { nid, searchDate } = toRefs(props)
const { list, loading, finished } = toRefs(props)
const emits = defineEmits(['clickDetail', 'toPlay', 'initData'])
const emits = defineEmits(['clickDetail', 'toPlay'])
//
const list = ref<AssetsList>([])
//:true false()
const loading = ref(false);
//:falsw true
const finished = ref(false);
//
let params: HomeSearchPage = {
page: 1,
size: 10,
nid: null,
startTime: null,
endTime: null
}
onMounted(() => {
initListData()
// initListData()
})
const initListData = async(type?: string) => {
if (type == 'search') {
initList()
}
if (props.nid) {
params.nid = props.nid
}
if (props.searchDate) {
let arr = props.searchDate.split('-')
params.endTime = arr[0]
params.startTime = arr[1]
}
const { data } = await getKnowledgePage(params)
list.value.push(...data.records)
loading.value = false;
if (list.value.length === data.total) {
finished.value = true;
} else {
params.page++
}
uni.stopPullDownRefresh()
const initData = () => {
console.log('3333')
emits('initData')
}
const clickDetail = (id: number) => {
emits('clickDetail', id)
@ -65,56 +22,23 @@ const clickDetail = (id: number) => {
const playCall = async (call: string) => {
emits('toPlay', call)
}
const initList = () => {
list.value = []
finished.value = false
params.page = 1
params.nid = null
params.startTime = null
params.endTime = null
}
defineExpose({
initListData
})
// //
onPullDownRefresh(() => {
initListData('search')
})
</script>
<template>
<view class="knowledge-list">
<van-list v-model:loading="loading" :finished="finished" finished-text="" @load="initListData">
<!-- 列表数据 -->
<view class="mt-20rpx">
<view v-for="item in list" :key="item.clueId" class="card-item bg-white p-15rpx mb-16rpx border-l-7 border-cyan-500 relative" @click="clickDetail(item.clueId)">
<view class="flex items-center justify-between">
<view class="font-bold text-c5 text-sm van-ellipsis flex-initial pr-15rpx">{{ item.nid }}</view>
<view class="flex-none">{{ item.clueStageName ? item.clueStageName: '--' }}</view>
</view>
<view class="flex py-15rpx justify-between">
<view class="flex-initial van-ellipsis">
<text class="block text-xs mb-10rpx">{{ item.originName }}</text>
<text class="block text-xs mb-10rpx">线索日期{{ item.clueTime ? item.clueTime : '--' }}</text>
<!-- <text class="block text-xs">标签有意向咨询多次</text> -->
<view class="van-ellipsis">
<van-tag v-for="it in item.clueLabelList" type="primary" class="mr-5rpx">{{ it }}</van-tag>
</view>
</view>
<view class="flex-none" @click.stop="playCall(item.nid)">
<uni-icons custom-prefix="iconfont" class="text-c6! block mt-6rpx active:text-c7!" type="icon-dianhua" size="36"></uni-icons>
</view>
</view>
<img v-if="item.isNewClue" class="absolute w-44rpx top-0 left-0" src="@/static/images/new.png">
</view>
</view>
</van-list>
</view>
</template>
<style lang="scss" scoped>
.knowledge-list {
// overflow-y: scroll;
height: 100%;
}
.CpIcon {
font-size: 48px;
margin-right: 5px;
}
.absolute {
width: 40rpx;
height: 40rpx;
}
</style>

@ -1,29 +0,0 @@
/*
* @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Date: 2023-07-28 16:10:52
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @LastEditTime: 2023-08-09 17:08:53
* @FilePath: \byhl-zt-app\src\config\env.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
/** 请求服务的环境配置 */
type ServiceEnv = Record<ServiceEnvType, ServiceEnvConfig>
export const serviceEnv: ServiceEnv = {
dev: {
url: 'http://172.18.0.225:8000',
},
prod: {
url: 'http://admin.ballcat.cn',
}
}
export const imgUrl = 'https://hccake-img.oss-cn-shanghai.aliyuncs.com/'
/**
*
* @param env
*/
export function getServiceEnvConfig(env: ImportMetaEnv) {
const { VITE_SERVICE_ENV = 'dev' } = env
return serviceEnv[VITE_SERVICE_ENV]
}

@ -1,7 +1,7 @@
import { createSSRApp } from 'vue'
import App from './App.vue'
// import { setupStore } from './store'
import 'vant/lib/index.css'
import 'uno.css'
import '@/style/main.scss'
import 'virtual:svg-icons-register'

@ -1,5 +1,5 @@
{
"name" : "cmd",
"name" : "线索分发系统",
"appid" : "__UNI__F6B11EE",
"description" : "",
"versionName" : "1.0.0",
@ -15,6 +15,9 @@
"autoclose" : true,
"delay" : 0
},
"compatible" : {
"ignoreVersion" : true //trueHBuilderX1.9.0
},
"modules" : {},
"distribute" : {
"android" : {
@ -35,10 +38,47 @@
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>"
]
],
"minSdkVersion" : 21
},
"ios" : {
"dSYMs" : false
},
"sdkConfigs" : {
"ad" : {}
},
"ios" : {},
"sdkConfigs" : {}
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
}
}
},
"quickapp" : {},

@ -17,7 +17,6 @@
"path": "pages/common/assetsDetail/index",
"style": {
"navigationBarTitleText": "线索详情",
"enablePullDownRefresh": true,
"navigationStyle": "custom"
}
},

@ -0,0 +1,326 @@
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { onLoad } from "@dcloudio/uni-app";
import { getDetails, editClueUpdate } from "@/api/index";
import { Navigate } from '@/utils/index'
import 'vant/es/toast/style'
let addProp = ref(false)
let editCode = ref(false)
let showcluePicker = ref(false)
const refForm = ref()
let addForm = reactive({
customInformation: ''
// record: [{val: ''}]
})
let customFieldName = {
text: 'name',
value: 'clueStageId'
}
let formData: any = ref({})
let index = 0
onLoad((option: any) => {
index = option.index
getDetails(option.id).then(res => {
formData.value = res.data
}).catch(err => {
Navigate.show_info('数据错误')
setTimeout(() => {
uni.navigateBack({
delta: 1
})
}, 700)
})
})
const cancellationFun = () => {
addProp.value = false
addForm.customInformation = ''
// addForm.record = [{val: ''}]
refForm.value.resetValidation()
}
const openAddProp = () => {
addForm.customInformation = formData.value.customInformation
addProp.value = true
}
interface activeObj {
id: number
labelName: string
}
const activeArr = ref<activeObj[]>([])
const activeArrFun = () => {
if (formData.value.clueLabelName != '') {
JSON.parse(formData.value.clueLabelName).forEach((t1: any) => {
formData.value.organizeEntities.forEach((t2: any) => {
let data = t2.labelEntityList.filter((t3: any) => t3.labelName == t1)[0]
if (data) {
activeArr.value.push({id: data.id, labelName: data.labelName})
}
})
});
}
}
const saveCode = async () => {
editCode.value = !editCode.value
if (editCode.value == true && formData.value.clueLabelName) {
activeArrFun()
} else if(editCode.value == false) {
// console.log("🚀 ~ file: index.vue:58 ~ saveCode ~ formData.value:", formData.value)
const params = {
clueId: formData.value.clueId,
clueLabelList: activeArr.value,
customInformation: formData.value.customInformation,
clueStageId: formData.value.clueStageId,
clueStageName: formData.value.clueStageName
}
const res: any = await editClueUpdate(params)
Navigate.show_info('操作成功');
if (res.code == 200) {
uni.$emit('updatePage', {index: index, clueLabelList: activeArr.value})
formData.value.clueLabelName = JSON.stringify(activeArr.value.map((item: any) => {
return item[Object.keys(item)[1]]
}) || "")
}
activeArr.value = []
}
}
const addClueCode = (id: number, labelName: string) => {
let index = activeArr.value.findIndex((item: activeObj) => item.id == id)
if (index !== -1) {
activeArr.value.splice(index, 1)
} else {
activeArr.value.push({ id, labelName})
}
}
const onConfirm = (data: any) => {
showcluePicker.value = false
activeArrFun()
const params = {
clueId: formData.value.clueId,
clueLabelList: activeArr.value,
customInformation: formData.value.customInformation,
clueStageId: data.selectedOptions[0].clueStageId,
clueStageName: data.selectedOptions[0].name
}
editClueUpdate(params).then(res => {
uni.$emit('updatePage', {index: index, clueStageName: data.selectedOptions[0].name})
formData.value.clueStageName = data.selectedOptions[0].name
Navigate.show_info('操作成功');
})
}
const editInformation = () => {
activeArrFun()
const params = {
clueId: formData.value.clueId,
clueLabelList: activeArr.value,
customInformation: addForm.customInformation,
clueStageId: formData.value.clueStageId,
clueStageName: formData.value.clueStageName
}
editClueUpdate(params).then(res => {
formData.value.customInformation = addForm.customInformation
cancellationFun()
Navigate.show_info('操作成功');
})
}
const compareId = (id: number) => {
return activeArr.value.some(item => item.id == id)
}
const onRecordSubmit = () => {
}
const onBack = () => {
uni.switchTab({
url: '/pages/index'
})
}
// const addRecord = () => {
// addForm.record.push({val: ''})
// }
</script>
<template>
<view>
<van-nav-bar
title="详情"
left-text="返回"
left-arrow
safe-area-inset-top
style="padding-top: var(--status-bar-height);"
@click-left="onBack"
/>
<view class="flex justify-between border-b-1 border-b-stone-300 items-center px-32rpx py-20rpx bg-teal-500">
<h2 class="title-doc-block text-base font-bold! border-b-stone-300 text-white">
业务标签
</h2>
<text class="block text-c7 font-600" @click="saveCode">{{ editCode ? '' : '' }}</text>
</view>
<view v-if="editCode == false">
<!-- <view v-if="formData.organizeEntities && formData.organizeEntities.length > 0">
<view v-for="item in formData.organizeEntities">
<h2 class="title-doc-block mt-32rpx py-24rpx px-32rpx fs-14">{{ item.name }}</h2>
</view>
</view> -->
<view v-if="formData.clueLabelName && JSON.parse(formData.clueLabelName).length != 0" class="px-32rpx flex flex-wrap">
<view v-for="it in JSON.parse(formData.clueLabelName)" style="background-color: #007aff; color: #fff;" class="block-button mr-16rpx mt-16rpx mb-16rpx" :class="{'tag-active': it == 3}">{{ it }}</view>
</view>
<van-empty v-else image-size="60rpx" description="未打标" />
</view>
<view v-else>
<view v-for="item in formData.organizeEntities">
<h2 class="title-doc-block mt-32rpx py-24rpx px-32rpx fs-14">{{ item.name }}</h2>
<view class="px-32rpx flex flex-wrap">
<view v-for="it in item.labelEntityList" class="block-button mr-16rpx mb-16rpx" :class="{'tag-active': compareId(it.id)}" @click="addClueCode(it.id, it.labelName)">{{ it.labelName }}</view>
</view>
</view>
</view>
<view class="flex justify-between border-b-1 border-b-stone-300 items-center px-32rpx py-20rpx bg-teal-500">
<h2 class="title-doc-block text-base font-bold! text-c2 border-b-stone-300 text-white">
线索阶段
</h2>
</view>
<van-cell title="阶段" is-link :value="formData.clueStageName" @click="showcluePicker = true" />
<view v-if="formData.otherClue">
<view class="flex justify-between border-b-1 border-b-stone-300 items-center px-32rpx py-20rpx bg-teal-500">
<!-- <van-icon name="fire-o" color="#007aff" class="mr-10rpx font-600"/> -->
<h2 class="title-doc-block text-base font-bold! text-white">自定义属性</h2>
</view>
<van-cell-group>
<van-cell v-for="(it, key) in JSON.parse(formData.otherClue)" :title="key" :value="it" />
</van-cell-group>
</view>
<view>
<view class="flex justify-between border-b-1 border-b-stone-300 items-center px-32rpx py-20rpx bg-teal-500">
<h2 class="title-doc-block text-base font-bold! text-c2 border-b-stone-300 text-white">
客户资料
</h2>
<text class="block text-c7 font-600" @click="openAddProp"></text>
</view>
</view>
<van-cell title="客户资料" :label="formData.customInformation || '未录入'" />
<!-- <view class="flex items-center v_cell px-32rpx" @click.stop="showcluePicker = true">
<view class="van-cell__title van-field__label"><label>阶段</label></view>
<view class="van-cell__value van-field__value text-left text-c2">{{ formData.clueStageName }}</view>
<i class="van-badge__wrapper van-icon van-icon-arrow van-cell__right-icon"></i>
</view> -->
<!-- <view class="flex justify-between border-b-1 border-b-stone-300 items-center px-32rpx py-20rpx bg-teal-500">
<h2 class="title-doc-block text-base font-bold! text-white"><van-icon name="fire-o" color="#007aff" class="mr-10rpx"/>跟进时间轴</h2>
<text class="block text-c7" @click="addProp = true">添加记录</text>
</view>
<view>
<van-steps direction="vertical" :active="88">
<van-step>
<view class="flex justify-between">
<van-tag type="primary" style="font-size: 14px;">标签</van-tag>
<text>2019-08-23</text>
</view>
<view class="card-block leading-5">
<text class="block">1w我是的一句话</text>
<text class="block">1w我是的二句话</text>
</view>
</van-step>
<van-step>
<view class="flex justify-between">
<van-tag type="primary" style="font-size: 14px;">标签</van-tag>
<text>2019-08-23</text>
</view>
<view class="card-block leading-5">
<text class="block">1w我是的一句话</text>
<text class="block">1w我是的二句话</text>
</view>
</van-step>
</van-steps>
</view> -->
<van-popup v-model:show="addProp" :style="{ width: '80%', borderRadius: '7px' }">
<view>
<text class="title-doc-block text-base font-bold! block text-center pt-30rpx mt-15rpx">客户资料编辑</text>
<van-form ref="refForm" @submit="editInformation">
<!-- <van-cell-group inset> -->
<!-- <van-field
v-model="addForm.stageName"
name="阶段名"
label="阶段名"
placeholder="阶段名"
:rules="[{ required: true, message: '请填写阶段名' }]"
>
<template #button>
<van-icon name="add" color="#18CC73" @click="addRecord" />
</template>
</van-field> -->
<!-- v-for="(item, index) in addForm.record" -->
<van-field
v-model="addForm.customInformation"
autosize
clearable
type="textarea"
maxlength="80"
show-word-limit
label="备注"
placeholder="客户资料"
>
</van-field>
<!-- </van-cell-group> -->
<view style="margin: 16px;" class="flex justify-around">
<van-button block class="w-30vw!" @click="cancellationFun">
取消
</van-button>
<van-button block type="primary" class="w-30vw!" native-type="submit">
提交
</van-button>
</view>
</van-form>
</view>
</van-popup>
<van-popup v-model:show="showcluePicker" round position="bottom">
<van-picker
:columns="formData.clueStageEntities"
@cancel="showcluePicker = false"
:columns-field-names="customFieldName"
@confirm="onConfirm"
/>
</van-popup>
</view>
</template>
<style scoped lang="scss">
page {
font-size: 14px;
}
::v-deep .van-field__label {
width: 100rpx;
}
.tag-active {
border: 1px solid #007aff!important;
background-color: #007aff;
color: #fff!important;
}
.title-doc-block {
margin: 0;
font-weight: 400;
line-height: 16px;
}
.block-button {
position: relative;
display: inline-block;
height: 54rpx;
text-align: center;
line-height: 54rpx;
border: 1px solid $uni-border-color;
padding: 0 20rpx;
border-radius: 4px;
}
.card-block {
border-radius: 4px;
padding: 15rpx;
border: 1px solid #ebeef5;
background-color: #fff;
overflow: hidden;
box-shadow: 0 2px 8px 0 rgba(0,0,0,.1);
margin-top: 15rpx;
color: $uni-text-color-placeholder;
}
::v-deep .van-picker__confirm {
// border: 1px solid #fff;
// padding-top: 10px;
}
</style>

@ -2,26 +2,33 @@
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { onLoad } from "@dcloudio/uni-app";
import { getDetails, editClueUpdate } from "@/api/home";
import { showToast } from 'vant';
import { getDetails, editClueUpdate } from "@/api/index";
import { Navigate } from '@/utils/index'
import 'vant/es/toast/style'
let addProp = ref(false)
let editCode = ref(false)
let showcluePicker = ref(false)
const refForm = ref()
let addForm = reactive({
stageName: '',
record: [{val: ''}]
})
const customInformation = ref("")
// let addForm = reactive({
// customInformation: ''
// // record: [{val: ''}]
// })
let customFieldName = {
text: 'name',
value: 'clueStageId'
}
let formData: any = ref({})
let index = 0
onLoad((option: any) => {
index = option.index
uni.showLoading({})
getDetails(option.id).then(res => {
uni.hideLoading()
formData.value = res.data
}).catch(err => {
showToast('数据错误')
uni.hideLoading()
Navigate.show_info('数据错误')
setTimeout(() => {
uni.navigateBack({
delta: 1
@ -31,32 +38,51 @@ onLoad((option: any) => {
})
const cancellationFun = () => {
addProp.value = false
addForm.stageName = ''
addForm.record = [{val: ''}]
refForm.value.resetValidation()
customInformation.value = ''
// addForm.record = [{val: ''}]
// refForm.value.resetValidation()
}
const openAddProp = () => {
customInformation.value = formData.value.customInformation
addProp.value = true
}
interface activeObj {
id: number
labelName: string
}
const activeArr = ref<activeObj[]>([])
const activeArrFun = () => {
if (formData.value.clueLabelName != '') {
JSON.parse(formData.value.clueLabelName).forEach((t1: any) => {
formData.value.organizeEntities.forEach((t2: any) => {
let data = t2.labelEntityList.filter((t3: any) => t3.labelName == t1)[0]
if (data) {
activeArr.value.push({id: data.id, labelName: data.labelName})
}
})
});
}
}
const saveCode = async () => {
editCode.value = !editCode.value
if (editCode.value == true && formData.value.clueLabelName) {
JSON.parse(formData.value.clueLabelName).forEach((t1: any) => {
formData.value.organizeEntities.forEach((t2: any) => {
let data = t2.labelEntityList.filter((t3: any) => t3.labelName == t1)[0]
if (data) {
activeArr.value.push({id: data.id, labelName: data.labelName})
}
})
});
} else if(editCode.value == false && activeArr.value.length > 0) {
const res = await editClueUpdate({clueId: formData.value.clueId, clueLabelList: activeArr.value})
formData.value.clueLabelName = JSON.stringify(activeArr.value.map((item: any) => {
return item[Object.keys(item)[1]]
}))
activeArrFun()
} else if(editCode.value == false) {
const params = {
clueId: formData.value.clueId,
clueLabelList: activeArr.value,
customInformation: formData.value.customInformation,
clueStageId: formData.value.clueStageId,
clueStageName: formData.value.clueStageName
}
const res: any = await editClueUpdate(params)
Navigate.show_info('操作成功');
if (res.code == 200) {
uni.$emit('updatePage', {index: index, clueLabelList: activeArr.value})
formData.value.clueLabelName = JSON.stringify(activeArr.value.map((item: any) => {
return item[Object.keys(item)[1]]
}) || "")
}
activeArr.value = []
}
}
@ -69,31 +95,50 @@ const addClueCode = (id: number, labelName: string) => {
}
}
const onConfirm = (data: any) => {
// console.log("🚀 ~ file: index.vue:64 ~ onConfirm ~ res:", data.selectedOptions[0])
showcluePicker.value = false
editClueUpdate({clueId: formData.value.clueId, clueStageName: data.selectedOptions[0].name, clueStageId: data.selectedOptions[0].clueStageId}).then(res => {
activeArrFun()
const params = {
clueId: formData.value.clueId,
clueLabelList: activeArr.value,
customInformation: formData.value.customInformation,
clueStageId: data.selectedOptions[0].clueStageId,
clueStageName: data.selectedOptions[0].name
}
editClueUpdate(params).then(res => {
uni.$emit('updatePage', {index: index, clueStageName: data.selectedOptions[0].name})
formData.value.clueStageName = data.selectedOptions[0].name
uni.showToast({
title: '操作成功',
icon: 'none'
})
activeArr.value = []
Navigate.show_info('操作成功');
})
}
const editInformation = () => {
activeArrFun()
const params = {
clueId: formData.value.clueId,
clueLabelList: activeArr.value,
customInformation: customInformation.value,
clueStageId: formData.value.clueStageId,
clueStageName: formData.value.clueStageName
}
editClueUpdate(params).then(res => {
uni.$emit('updatePage', {index: index, customInformation: customInformation.value})
formData.value.customInformation = customInformation.value
cancellationFun()
activeArr.value = []
Navigate.show_info('操作成功');
})
}
const compareId = (id: number) => {
return activeArr.value.some(item => item.id == id)
}
const onRecordSubmit = () => {
}
const onBack = () => {
uni.switchTab({
url: '/pages/index'
})
}
const addRecord = () => {
addForm.record.push({val: ''})
console.log("🚀 ~ file: index.vue:23 ~ addRecord ~ addForm:", addForm)
}
// const addRecord = () => {
// addForm.record.push({val: ''})
// }
</script>
<template>
@ -102,52 +147,60 @@ const addRecord = () => {
title="详情"
left-text="返回"
left-arrow
safe-area-inset-top
style="padding-top: var(--status-bar-height);"
@click-left="onBack"
/>
<view class="flex justify-between border-b-1 border-b-stone-300 items-center px-32rpx py-20rpx bg-teal-500">
<h2 class="title-doc-block text-base font-bold! border-b-stone-300 text-white">
<van-icon name="fire-o" color="#007aff" class="mr-10rpx"/>业务标签
业务标签
</h2>
<text class="block text-c7" @click="saveCode">{{ editCode ? '' : '' }}</text>
<text class="block text-c7 font-600" @click="saveCode">{{ editCode ? '' : '' }}</text>
</view>
<div v-if="editCode == false">
<view v-for="item in formData.organizeEntities">
<h2 class="title-doc-block mt-32rpx py-24rpx px-32rpx fs-14">{{ item.name }}</h2>
<view v-if="formData.clueLabelName" class="px-32rpx flex flex-wrap">
<view v-for="it in JSON.parse(formData.clueLabelName)" class="block-button mr-16rpx mb-16rpx" :class="{'tag-active': it == 3}">{{ it }}</view>
</view>
</view>
</div>
<div v-else>
<view v-if="editCode == false">
<!-- <view v-if="formData.organizeEntities && formData.organizeEntities.length > 0">
<view v-for="item in formData.organizeEntities">
<h2 class="title-doc-block mt-32rpx py-24rpx px-32rpx fs-14">{{ item.name }}</h2>
</view>
</view> -->
<view v-if="formData.clueLabelName && JSON.parse(formData.clueLabelName).length != 0" class="px-32rpx flex flex-wrap">
<view v-for="it in JSON.parse(formData.clueLabelName)" style="background-color: #007aff; color: #fff;" class="block-button mr-16rpx mt-16rpx mb-16rpx" :class="{'tag-active': it == 3}">{{ it }}</view>
</view>
<van-empty v-else image-size="60rpx" description="未打标" />
</view>
<view v-else>
<view v-for="item in formData.organizeEntities">
<h2 class="title-doc-block mt-32rpx py-24rpx px-32rpx fs-14">{{ item.name }}</h2>
<view class="px-32rpx flex flex-wrap">
<view v-for="it in item.labelEntityList" class="block-button mr-16rpx mb-16rpx" :class="{'tag-active': compareId(it.id)}" @click="addClueCode(it.id, it.labelName)">{{ it.labelName }}</view>
</view>
</view>
</div>
</view>
<view class="flex justify-between border-b-1 border-b-stone-300 items-center px-32rpx py-20rpx bg-teal-500">
<h2 class="title-doc-block text-base font-bold! text-c2 border-b-stone-300 text-white">
<van-icon name="fire-o" color="#007aff" class="mr-10rpx"/>线索阶段
线索阶段
</h2>
</view>
<van-field
v-model="formData.clueStageName"
is-link
readonly
label="阶段"
placeholder="选择线索阶段"
@click="showcluePicker = true"
/>
<div v-if="formData.otherClue">
<van-cell title="阶段" is-link :value="formData.clueStageName" @click="showcluePicker = true" />
<view v-if="formData.otherClue">
<view class="flex justify-between border-b-1 border-b-stone-300 items-center px-32rpx py-20rpx bg-teal-500">
<h2 class="title-doc-block text-base font-bold! text-white"><van-icon name="fire-o" color="#007aff" class="mr-10rpx"/>自定义属性</h2>
<!-- <van-icon name="fire-o" color="#007aff" class="mr-10rpx font-600"/> -->
<h2 class="title-doc-block text-base font-bold! text-white">自定义属性</h2>
</view>
<van-cell-group>
<van-cell v-for="(it, key) in JSON.parse(formData.otherClue)" :title="key" :value="it" />
</van-cell-group>
</div>
<van-cell title="备注" :label="formData.remark" />
</view>
<view>
<view class="flex justify-between border-b-1 border-b-stone-300 items-center px-32rpx py-20rpx bg-teal-500">
<h2 class="title-doc-block text-base font-bold! text-c2 border-b-stone-300 text-white">
客户资料
</h2>
<text class="block text-c7 font-600" @click="openAddProp"></text>
</view>
</view>
<van-cell title="客户资料" :label="formData.customInformation || '未录入'" />
<!-- <view class="flex items-center v_cell px-32rpx" @click.stop="showcluePicker = true">
<view class="van-cell__title van-field__label"><label>阶段</label></view>
<view class="van-cell__value van-field__value text-left text-c2">{{ formData.clueStageName }}</view>
@ -182,46 +235,31 @@ const addRecord = () => {
</van-steps>
</view> -->
<van-popup v-model:show="addProp" :style="{ width: '80%', borderRadius: '7px' }">
<view>
<text class="title-doc-block text-base font-bold! block text-center pt-30rpx mt-15rpx">添加记录</text>
<van-form ref="refForm" @submit="onRecordSubmit">
<van-cell-group inset>
<van-field
v-model="addForm.stageName"
name="阶段名"
label="阶段名"
placeholder="阶段名"
:rules="[{ required: true, message: '请填写阶段名' }]"
>
<template #button>
<van-icon name="add" color="#18CC73" @click="addRecord" />
</template>
</van-field>
<van-field
v-for="(item, index) in addForm.record"
v-model="item.val"
autosize
clearable
type="textarea"
maxlength="50"
show-word-limit
label="记录-1"
placeholder="记录"
>
</van-field>
</van-cell-group>
<div style="margin: 16px;" class="flex justify-around">
<van-button block class="w-30vw!" @click="cancellationFun">
取消
</van-button>
<van-button block type="primary" class="w-30vw!" native-type="submit">
提交
</van-button>
</div>
</van-form>
</view>
<view>
<text class="title-doc-block text-base font-bold! block text-center pt-30rpx mt-15rpx">客户资料编辑</text>
<!-- <van-field
v-model="customInformation"
autosize
clearable
type="textarea"
maxlength="80"
show-word-limit
label="备注"
placeholder="客户资料"
>
</van-field> -->
<textarea v-model="customInformation" maxlength="140" placeholder="客户资料" class="p-15rpx text-sm" auto-height />
<view style="margin: 16px;" class="flex justify-around">
<van-button block class="w-30vw!" size="small" @click="cancellationFun">
取消
</van-button>
<van-button block type="primary" size="small" class="w-30vw!" @click="editInformation">
提交
</van-button>
</view>
</view>
</van-popup>
<van-popup v-model:show="showcluePicker" round position="bottom">
<van-popup v-model:show="showcluePicker" round position="bottom" class="popup">
<van-picker
:columns="formData.clueStageEntities"
@cancel="showcluePicker = false"
@ -255,7 +293,6 @@ const addRecord = () => {
height: 54rpx;
text-align: center;
line-height: 54rpx;
color: $uni-text-color-placeholder;
border: 1px solid $uni-border-color;
padding: 0 20rpx;
border-radius: 4px;
@ -270,4 +307,10 @@ const addRecord = () => {
margin-top: 15rpx;
color: $uni-text-color-placeholder;
}
// #ifdef APP-PLUS
::v-deep .popup .van-haptics-feedback {
height: 60rpx;
line-height: 60rpx;
}
// #endif
</style>

@ -2,13 +2,21 @@
import {
ref
} from 'vue'
import { parseTime } from '@/utils/index'
// import { parseTime } from '@/utils/index'
import { Navigate } from '@/utils/index'
import { Modal } from '@/plugins/Modal'
import AssetsList from '@/components/home/AssetsList.vue'
import { useDebounceFn } from '@vueuse/core'
// import AssetsList from '@/components/home/AssetsList.vue'
import type {
AssetsListType,
HomeSearchPage
} from '@/types/consult'
import {
useUserStore
} from '@/store/user'
import {
getKnowledgePage
} from '@/api/index'
const store = useUserStore()
type behavioraback = {
type: number
@ -22,30 +30,91 @@
nid: '',
searchDate: ''
})
let searchEl = ref<InstanceType<typeof AssetsList>>()
// let searchEl = ref<InstanceType<typeof AssetsList>>()
let pickerProp = ref<boolean>(false)
let behaviorProp = ref<boolean>(false)
let behavioractions = ref<behaviora[]>([])
let minDate = ref<Date>(new Date(2022, 0, 1))
let maxDate = ref<Date>(new Date(2026, 8, 1))
let actionShow = ref<boolean>(false)
let scrollTop = ref(0)
let isImmediatelySlide = ref(true)
//
const list = ref<AssetsListType>([])
//:true false()
const loading = ref(false);
//:falsw true
const finished = ref(false);
//
let params: HomeSearchPage = {
page: 1,
size: 10,
nid: null,
startTime: null,
endTime: null,
salesmanType: 4
}
onMounted(() => {
store.initCount()
// #ifdef APP-PLUS
initListData()
// #endif
uni.$on('updatePage', function(data){
// isImmediatelySlide.value = false
// initListData('search')
const { clueLabelList, clueStageName, customInformation, index } = data
if (clueLabelList) {
list.value[index].clueLabelList = clueLabelList.map((item: any) => item.labelName)
}
if (clueStageName) {
list.value[index].clueStageName = clueStageName
}
if (customInformation) {
list.value[index].customInformation = customInformation
}
})
})
onShow(() => {
setTimeout(() => {
if (scrollTop.value != 0 && isImmediatelySlide.value) {
uni.pageScrollTo({
scrollTop: scrollTop.value, //
duration: 0
});
}
}, 10)
})
watch(() => store.readCount, (nval) => {
uni.setTabBarBadge({
index: 0,
text: nval
})
if (nval == 0) {
uni.removeTabBarBadge({
index: 0
})
}
},
{
deep: true
}
)
const searchClick = () => {
searchEl.value?.initListData('search')
// watch(pickerProp, (nval) => {
// const pages = getCurrentPages();
// const page = pages[pages.length - 1];
// const currentWebview = page.$getAppWebview();
// currentWebview.setStyle({
// pullToRefresh: {
// // falseisreload使
// support: !nval,
// style: plus.os.name === 'Android' ? 'circle' : 'default'
// }
// })
// })
const searchClick = useDebounceFn(() => {
initListData('search')
actionShow.value = false
}
}, 300, { maxWait: 3000 })
const moreExpand = () => {
actionShow.value = true
}
@ -55,9 +124,46 @@
const initSerach = () => {
searchObj.searchDate = ''
}
const openDetail = (id: number) => {
Navigate.to('/pages/common/assetsDetail/index', { params: { id } })
const openDetail = (id: number, index: number) => {
Navigate.to('/pages/common/assetsDetail/index', { params: { id, index } })
isImmediatelySlide.value = true
}
const initListData = useDebounceFn(async(type?: string) => {
if (type == 'search') {
initList()
}
if (searchObj.nid) {
params.nid = searchObj.nid
}
if (searchObj.searchDate) {
let arr = searchObj.searchDate.split('-')
params.endTime = arr[0]
params.startTime = arr[1]
}
const { data } = await getKnowledgePage(params)
list.value.push(...data.records)
loading.value = false;
uni.pageScrollTo({
scrollTop: scrollTop.value, //
duration: 0
});
uni.hideLoading()
if (data.records.length < params.size) {
finished.value = true;
} else {
params.page++
}
uni.stopPullDownRefresh()
}, 300, { maxWait: 3000 })
const initList = () => {
list.value = []
finished.value = false
params.page = 1
params.nid = null
params.startTime = null
params.endTime = null
}
const formatDate = (date: any) => `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
const confirmClick =(values: object[]) => {
const [start, end] = values
@ -93,15 +199,35 @@
});
}
}
onPageScroll((e) => {
if (e.scrollTop != 0) {
scrollTop.value = e.scrollTop
uni.setStorage({
key: "newsTop",
data: e.scrollTop
})
}
})
onPullDownRefresh(() => {
initListData('search')
})
onReachBottom(() => {
// #ifdef APP-PLUS
uni.showLoading({})
initListData()
// #endif
})
</script>
<template>
<view class="home-page mb-100rpx">
<view class="home-page mb-100rpx" @touchmove.prevent>
<div class="status_top"></div>
<!-- 头部-seach -->
<view class="home-header px-30rpx">
<view class="text-center text-white font-bold text-base py-15rpx">客户列表</view>
<van-sticky>
<van-search
<uni-search-bar v-model="searchObj.nid" placeholder="请输入搜索号码" @confirm="searchClick" />
<!-- <van-search
v-model="searchObj.nid"
show-action
shape="round"
@ -110,15 +236,47 @@
>
<template #action>
<view class="flex items-center">
<view class="text-primary van-haptics-feedback mr-14rpx" @click.stop="searchClick">搜索</view>
<view @click.stop="moreExpand"><uni-icons type="bottom"></uni-icons> </view>
</view>
<view class="text-primary van-haptics-feedback mr-14rpx" @click.stop="searchClick">搜索</view> -->
<!-- #ifdef H5 -->
<!-- <view @click.stop="moreExpand"><uni-icons type="bottom"></uni-icons> </view> -->
<!-- #endif -->
<!-- </view>
</template>
</van-search>
</van-search> -->
</van-sticky>
</view>
<view class="px-30rpx assets-list">
<AssetsList ref="searchEl" :nid="searchObj.nid" :searchDate="searchObj.searchDate" @clickDetail="openDetail" @toPlay="clickPlay" />
<view class="px-30rpx assets-list" @touchmove.stop @touch.stop>
<!-- <AssetsList ref="searchEl" :list="list" :loading="loading" :finished="finished" :searchDate="searchObj.searchDate" @initData="initListData" @clickDetail="openDetail" @toPlay="clickPlay" /> -->
<view class="knowledge-list">
<van-list v-model:loading="loading" :offset="300" :finished="finished" finished-text="" @load="initListData">
<!-- 列表数据 -->
<view class="mt-20rpx">
<view v-for="(item, index) in list" :key="item.clueId" class="card-item bg-white p-15rpx mb-16rpx border-l-7 border-cyan-500 relative" @click="openDetail(item.clueId, index)">
<view class="flex items-center justify-between">
<view class="font-bold text-c5 text-sm van-ellipsis flex-initial pr-15rpx">{{ item.nid }}</view>
<view class="flex-none">{{ item.clueStageName ? item.clueStageName: '--' }}</view>
</view>
<view class="flex py-15rpx justify-between">
<view class="flex-initial van-ellipsis">
<text class="block text-xs mb-10rpx">{{ item.originName }}</text>
<text class="block text-xs mb-10rpx">线索日期{{ item.createTime ? item.createTime : '--' }}</text>
<!-- <text class="block text-xs">标签有意向咨询多次</text> -->
<!-- <view class="van-ellipsis">
<van-tag v-for="it in item.clueLabelList" type="primary" class="mr-5rpx">{{ it }}</van-tag>
</view> -->
<view class="van-ellipsis">
<text class="block text-xs">客户资料<text class="grey-col">{{ item.customInformation }}</text></text>
</view>
</view>
<view class="flex-none" @click.stop="clickPlay(item.nid)">
<uni-icons custom-prefix="iconfont" class="text-c6! block mt-6rpx active:text-c7!" type="icon-dianhua" size="36"></uni-icons>
</view>
</view>
<image v-if="item.isNewClue" class="absolute w-44rpx top-0 left-0" src="@/static/images/new.png" />
</view>
</view>
</van-list>
</view>
</view>
<van-action-sheet v-model:show="actionShow" title="" cancel-text="" :round="false" :closeable="false" close-on-click-action @cancel="onCancel">
<view class="content">
@ -136,7 +294,9 @@
<van-button type="primary" class="w-40vw" @click="searchClick"></van-button>
</view>
</view>
<van-calendar v-model:show="pickerProp" type="range" @confirm="confirmClick" @cancel="cancelPicker" />
<view>
<van-calendar v-model:show="pickerProp" type="range" @confirm="confirmClick" @cancel="cancelPicker" />
</view>
</view>
</van-action-sheet>
<van-action-sheet
@ -170,5 +330,31 @@
height: 220rpx;
background-image: linear-gradient(to bottom , #18B4B3, $uni-bg-color-grey);
}
.status_top {
height: var(--status-bar-height);
}
.knowledge-list {
// overflow-y: scroll;
height: 100%;
}
.CpIcon {
font-size: 48px;
margin-right: 5px;
}
.absolute {
width: 40rpx;
height: 40rpx;
}
.grey-col {
color: #969799;
}
::v-deep .uni-searchbar {
padding: 10px 0;
}
::v-deep .van-sticky--fixed {
background-color: #A8DFDF;
}
::v-deep .uni-searchbar__cancel {
color: #fff;
}
</style>

@ -1,32 +1,25 @@
<!--
* @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Date: 2023-07-28 16:10:52
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @LastEditTime: 2023-08-09 16:13:58
* @FilePath: \byhl-zt-app\src\pages\login.vue
-->
<script setup lang="ts">
import { loginAPI } from '@/api/user'
import { loginAPI } from '@/api/index'
import { useUserStore } from '@/store/user'
import { Modal } from '@/plugins/Modal'
import { Navigate, passEncrypt } from '@/utils'
import { showSuccessToast } from 'vant'
import { LoginResult } from '@/types/user'
import { SliderCaptcha as LoginCaptcha } from '@/components/Captcha/index'
import type { LoginFormInstance } from '@/components/Captcha/types'
import { accountLogin, getCodeData } from '@/api/login'
// import { SliderCaptcha as LoginCaptcha } from '@/components/Captcha/index'
// import type { LoginFormInstance } from '@/components/Captcha/types'
import { accountLogin, getCodeData } from '@/api/index'
import socket from "@/utils/socketTask";
import { getToken } from "@/utils/Storage"
const store = useUserStore()
//
const enableLoginCaptcha = true
// const enableLoginCaptcha = true
//
const loginLoading = ref(false)
//
const isLoginError = ref(false)
//
const loginFormRef = ref<LoginFormInstance>()
const loginCaptchaRef = ref()
// const loginFormRef = ref<LoginFormInstance>()
// const loginCaptchaRef = ref()
const loginForm = reactive({
username: '',
password: '',
@ -36,7 +29,7 @@
})
const codeUrl = ref('')
const captchaEnabled = ref(false)
// const captchaEnabled = ref(false)
//
const pwdLogin = async () => {
// await UserStore.Login(loginForm).catch(err => {
@ -86,10 +79,10 @@
url: '/pages/index'
});
})
.catch((err: { response: any }) => {
.catch(err => {
isLoginError.value = true
getCode()
Modal.msg(((err.response || {}).data || {}).message || '请求出现错误,请稍后再试')
Modal.msg((((err.response || {}).data || {}).error || ((err.response || {}).data || {}).message) || '请求出现错误,请稍后再试')
}).finally(() => {
loginLoading.value = false
})
@ -143,7 +136,7 @@
<!-- <image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
</image> -->
<text class="title">
橘猫呼叫系统
线索分发系统
</text>
</view>
<view class="login-form-content">
@ -152,11 +145,9 @@
<input v-model="loginForm.mobile" class="input" type="text" placeholder="请输入账号" maxlength="30">
</view>
<view class="input-item flex align-center">
<v
iew class="iconfont icon-password icon" />
<input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20">
</view>
<view class="iconfont icon-password icon" />
<input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20">
</view>
<view class="input-item flex align-center">
<view class="iconfont icon-code icon" />
<input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4">
@ -169,7 +160,7 @@
</view>
</view>
<view class="xieyi text-center">
<!-- <view class="xieyi text-center">
<text class="text-grey1">
登录即代表同意
</text>
@ -179,7 +170,7 @@
<text class="text-blue" @click="handlePrivacy">
隐私协议
</text>
</view>
</view> -->
<!-- 登陆验证码 -->
<!-- <login-captcha v-if="enableLoginCaptcha" ref="loginCaptchaRef" @success="handleSubmit" /> -->
</view>

@ -9,10 +9,10 @@
<script setup lang="ts">
import { useUserStore } from '@/store/user'
import { Modal } from '@/plugins/Modal'
// import { imgUrl } from '@/config/env.ts'
import store from '@/utils/socketTask'
// const avatar = imgUrl
const { userInfo, setTokens } = useUserStore()
const baseUrl = import.meta.env.VITE_APP_IMG_UTL
const handleToLogin = async () => {
let isConfirm = await Modal.confirm('确认退出登录吗')
if (isConfirm) {
@ -32,12 +32,12 @@ onLoad (() => {
<template>
<view class="mine-container m-30rpx bg-white">
<view class="pt-150rpx">
<image :src="'http://39.100.77.21:8001/avatar/' + userInfo?.avatar" class="w-160rpx h-160rpx border block m-auto rounded-full" />
<image :src="baseUrl + userInfo?.avatar" class="w-160rpx h-160rpx border block m-auto rounded-full" />
</view>
<van-cell-group>
<van-cell title="账号名称" :value="userInfo?.nickname" />
<van-cell title="组" value="未知" />
<van-cell title="软件版本" value="1.0.1" />
<van-cell title="软件版本" value="1.0.0" />
</van-cell-group>
</view>
<van-button type="primary" class="w-90vw block! m-auto! fixed! button" @click="handleToLogin">退</van-button>

@ -1,67 +1,67 @@
<script setup lang="ts">
import {Modal} from "@/plugins/Modal";
import {updateUser, UserService} from "@/service/api/system/user";
<script setup lang="ts">
// import {Modal} from "@/plugins/Modal";
// import {updateUser, UserService} from "@/service/api/system/user";
const user = reactive<updateUser>({
nickName: "",
phonenumber: "",
email: "",
sex: ""
})
const form = ref(null)
const sexy = ref([{
text: '男',
value: "0"
}, {
text: '女',
value: "1"
}])
const rules = ref({
nickName: {
rules: [{
required: true,
errorMessage: '用户昵称不能为空'
}]
},
phonenumber: {
rules: [{
required: true,
errorMessage: '手机号码不能为空'
}, {
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
errorMessage: '请输入正确的手机号码'
}]
},
email: {
rules: [{
required: true,
errorMessage: '邮箱地址不能为空'
}, {
format: 'email',
errorMessage: '请输入正确的邮箱地址'
}]
}
})
const submit = () => {
(form.value as any).validate().then(async () => {
await UserService.updateUserProfile(user)
Modal.msgSuccess('修改成功')
})
}
onLoad(async()=>{
const res =await UserService.getUserProfile()
Object.assign(user, res.data.data)
})
onShow(async () => {
await nextTick()
if (form.value != null) {
(form.value as any).setRules(rules.value)
}
})
// const user = reactive<updateUser>({
// nickName: "",
// phonenumber: "",
// email: "",
// sex: ""
// })
// const form = ref(null)
// const sexy = ref([{
// text: '',
// value: "0"
// }, {
// text: '',
// value: "1"
// }])
// const rules = ref({
// nickName: {
// rules: [{
// required: true,
// errorMessage: ''
// }]
// },
// phonenumber: {
// rules: [{
// required: true,
// errorMessage: ''
// }, {
// pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
// errorMessage: ''
// }]
// },
// email: {
// rules: [{
// required: true,
// errorMessage: ''
// }, {
// format: 'email',
// errorMessage: ''
// }]
// }
// })
// const submit = () => {
// (form.value as any).validate().then(async () => {
// await UserService.updateUserProfile(user)
// Modal.msgSuccess('')
// })
// }
// onLoad(async()=>{
// const res =await UserService.getUserProfile()
// Object.assign(user, res.data.data)
// })
// onShow(async () => {
// await nextTick()
// if (form.value != null) {
// (form.value as any).setRules(rules.value)
// }
// })
</script>
<template>
<view class="container">
<view class="example">
<!-- <view class="example">
<uni-forms ref="form" :model="user" labelWidth="80px">
<uni-forms-item label="用户昵称" name="nickName">
<uni-easyinput v-model="user.nickName" placeholder="请输入昵称"/>
@ -77,40 +77,40 @@ onShow(async () => {
</uni-forms-item>
</uni-forms>
<button type="primary" @click="submit"></button>
</view>
</view> -->
</view>
</template>
<style lang="scss" scoped>
page {
background-color: #ffffff;
}
// page {
// background-color: #ffffff;
// }
.example {
padding: 15px;
background-color: #fff;
}
// .example {
// padding: 15px;
// background-color: #fff;
// }
.segmented-control {
margin-bottom: 15px;
}
// .segmented-control {
// margin-bottom: 15px;
// }
.button-group {
margin-top: 15px;
display: flex;
justify-content: space-around;
}
// .button-group {
// margin-top: 15px;
// display: flex;
// justify-content: space-around;
// }
.form-item {
display: flex;
align-items: center;
flex: 1;
}
// .form-item {
// display: flex;
// align-items: center;
// flex: 1;
// }
.button {
display: flex;
align-items: center;
height: 35px;
line-height: 35px;
margin-left: 10px;
}
</style>
// .button {
// display: flex;
// align-items: center;
// height: 35px;
// line-height: 35px;
// margin-left: 10px;
// }
// </style>

@ -1,5 +1,5 @@
<script setup lang="ts">
import {UserService} from "@/service/api/system/user";
// import {UserService} from "@/service/api/system/user";
let user = ref({
nickName: '',
@ -10,11 +10,10 @@ let user = ref({
const postGroup = ref('')
const roleGroup = ref('')
const getUser = async () => {
const res:any = await UserService.getUserProfile()
user.value=res.data.data
roleGroup.value = res.data.roleGroup
postGroup.value = res.data.postGroup
// const res:any = await UserService.getUserProfile()
// user.value=res.data.data
// roleGroup.value = res.data.roleGroup
// postGroup.value = res.data.postGroup
}
onLoad(() => {
getUser()

@ -1,7 +1,7 @@
<script setup lang="ts">
import {Modal} from "@/plugins/Modal";
import {UserService} from "@/service/api/system/user";
import { Navigate} from "@/utils";
// import {Modal} from "@/plugins/Modal";
// import { UserService } from "@/service/api/system/user";
// import { Navigate} from "@/utils";
const form=ref(null)
const user = reactive({
@ -41,9 +41,9 @@ const rules = reactive({
})
const submit=async ()=>{
(form.value as any).validate().then(async () => {
await UserService.updateUserPwd({oldPassword:user.oldPassword,newPassword:user.newPassword})
Modal.msgSuccess('修改成功')
Navigate.back()
// await UserService.updateUserPwd({oldPassword:user.oldPassword,newPassword:user.newPassword})
// Modal.msgSuccess('')
// Navigate.back()
})
}

@ -10,7 +10,7 @@ import type { User } from '@/types/user'
import { setToken, removeToken } from '@/utils/Storage'
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { getReadCount } from "@/api/home";
import { getReadCount } from "@/api/index";
export interface UserInfo extends User {
roleCodes: string[]
permissions: string[]

@ -33,13 +33,14 @@ export type AssetsObj = {
originName: string
otherClue: string
remark: string
customInformation?: string
}
// 资源列表
export type AssetsList = AssetsObj[]
export type AssetsListType = AssetsObj[]
// 分页 api接口data指定类型
export type AssetsPage = PageData<AssetsList>
export type AssetsPage = PageData<AssetsListType>
// {
// pageTotal: number // 总页数
// total: number // 总条数
@ -70,6 +71,7 @@ export type HomeSearch = {
nid?: string | null
startTime?: string | null
endTime?: string | null
salesmanType: number
}
export type HomeSearchPage = HomeSearch & PageParams
@ -81,5 +83,6 @@ export interface editClue {
clueId: string
clueLabelList?: clue[]
clueStageName?: string
customInformation?: string
clueStageId?: number
}

@ -3,7 +3,7 @@
* - dev:
* - prod:
*/
type ServiceEnvType = 'dev' | 'prod'
type ServiceEnvType = 'development' | 'production'
/** 后台服务的环境配置 */
interface ServiceEnvConfig {

@ -1,11 +1,3 @@
/*
* @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Date: 2023-07-28 16:10:52
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @LastEditTime: 2023-08-09 15:38:40
* @FilePath: \byhl-zt-app\src\utils\index.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import CryptoJS from 'crypto-js/index'
import { ENUM_STORAGE_KEY } from '@/enums/common'
interface NavigateOptions {

@ -1,24 +1,17 @@
/*
* @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Date: 2023-07-28 16:10:52
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @LastEditTime: 2023-08-09 15:57:54
* @FilePath: \byhl-zt-app\src\utils\request.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import axios from 'axios'
import { createUniAppAxiosAdapter } from '@uni-helper/axios-adapter'
import { useUserStore } from '@/store/user'
export const baseURL = import.meta.env.VITE_APP_BASE_API
// 真机app VITE_APP_SERVER_URL h5 VITE_APP_BASEURL
export const baseURL = import.meta.env.VITE_APP_SERVER_URL
const request = axios.create({
// TODO 1. 基础地址,超时时间
baseURL,
timeout: 5000
timeout: 5000,
adapter: createUniAppAxiosAdapter()
})
request.interceptors.request.use(
function(config) {
const store = useUserStore()
const store = useUserStore()
if (store.accessToken && config.headers) {
config.headers['Authorization'] = `Bearer ${store.accessToken}` // config.headers.Authorization也是可以的
}
@ -34,6 +27,15 @@ request.interceptors.response.use(
return res.data
},
function(err) {
console.log('request-err', err)
let code = err.response.status
const store = useUserStore()
if(code == 401) {
store.setTokens('')
uni.reLaunch({
url: '/pages/login'
});
}
return Promise.reject(err)
}
)

@ -1,15 +1,13 @@
import {
useUserStore
} from '@/store/user'
import {
getToken
} from "@/utils/Storage";
import { showToast } from 'vant';
const store = useUserStore()
import { useUserStore } from '@/store/user'
import { Navigate } from '@/utils/index'
let timer = null
// let retimer=null
// const socketUrl = window.location.host
const socketUrl = 'ws://39.100.77.21:8000'
// const socketUrl = 'ws://39.100.77.21:8000'
const socketUrl = 'wss://byffp.top'
let ws: any = null
const connectSocket = () => {
uni.onSocketOpen(function (res) {
@ -17,20 +15,17 @@ const connectSocket = () => {
// heartbeatSocket()
})
uni.onSocketError(function (res) {
uni.showToast({
title: '连接中断,请重新登录',
icon: 'none'
})
Navigate.show_info('连接中断,请重新登录')
console.log('WebSocket连接打开失败请检查');
})
uni.onSocketClose(function (res) {
console.log('WebSocket 已关闭!');
});
uni.onSocketMessage((res) => {
console.log("🚀 ~ file: socketTask.ts:26 ~ uni.onSocketMessage ~ res:", res)
let data = JSON.parse(res.data as string)
const store = useUserStore()
if (data.type === 'announcement-push') {
showToast(data.content)
Navigate.show_info(data.content)
store.setReadCount(store.readCount + 1)
}
})
@ -55,7 +50,7 @@ export default {
return new Promise((resolve, reject) => {
if ( ws == null) {
ws = uni.connectSocket({
url: `${socketUrl}/ws?access_token=${getToken()}`,
url: `${socketUrl}/api/ws?access_token=${getToken()}`,
success(data) {
console.log("websocket连接成功");
resolve(true)

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

@ -1,76 +1,65 @@
/*
* @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @Date: 2023-07-28 16:10:52
* @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
* @LastEditTime: 2023-08-08 18:20:30
* @FilePath: \byhl-zt-app\vite.config.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import path from 'path'
import { defineConfig } from 'vite'
import { defineConfig, loadEnv } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import Unocss from 'unocss/vite'
import transformWeClass from 'unplugin-transform-we-class/vite'
import AutoImport from 'unplugin-auto-import/vite'
import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
// const VITE_APP_SERVER_URL: string = loadEnv(mode, process.cwd()).VITE_APP_SERVER_URL;
// https://vitejs.dev/config/
export default defineConfig({
server: {
open: true,
cors: true,
host: '0.0.0.0',
proxy: {
"^/api": { //服务器接口路径地址,根据路径设置
target: 'http://39.100.77.21:8000', //你的服务器地址
changeOrigin: true, // 允许跨域
ws: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
resolve: {
alias: {
'~/': `${path.resolve(__dirname, 'src')}/`,
},
},
plugins: [
uni(),
Components({
resolvers: [VantResolver()],
}),
createSvgIconsPlugin({
//指定图标文件夹,绝对路径(NODE代码)
iconDirs: [path.resolve(process.cwd(), 'src/icons')],
symbolId: 'icon-[name]',
}),
// https://github.com/antfu/unocss
// Unocss(),
export default ({ mode }) => {
// console.log('loadEnv(mode, process.cwd()).VITE_APP_SERVER_URL=', loadEnv(mode, process.cwd()).VITE_APP_SERVER_URL)
return defineConfig({
server: {
open: false,
cors: true,
host: '0.0.0.0',
proxy: {
"^/api": { //服务器接口路径地址,根据路径设置
target: loadEnv(mode, process.cwd()).VITE_APP_SERVER_URL, //你的服务器地址
changeOrigin: true, // 允许跨域
secure: false,
ws: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
resolve: {
alias: {
'~/': `${path.resolve(__dirname, 'src')}/`,
},
},
plugins: [
uni(),
Components({
resolvers: [VantResolver()],
}),
createSvgIconsPlugin({
//指定图标文件夹,绝对路径(NODE代码)
iconDirs: [path.resolve(process.cwd(), 'src/icons')],
symbolId: 'icon-[name]',
}),
// https://github.com/antfu/unocss
// Unocss(),
// app打包配置
// uniapp打包app时打包2次一次使用 vue 模式打包h5第2次使用 nvue 模式打包app
// 第2次打包 unocss 会抛出warn
// entry module not found, have you add `import 'uno.css'` in your main entry?
// 导致打包终止
process.env.UNI_COMPILER !== 'nvue' ? Unocss() : undefined,
// app打包配置
// uniapp打包app时打包2次一次使用 vue 模式打包h5第2次使用 nvue 模式打包app
// 第2次打包 unocss 会抛出warn
// entry module not found, have you add `import 'uno.css'` in your main entry?
// 导致打包终止
process.env.UNI_COMPILER !== 'nvue' ? Unocss() : undefined,
// https://github.com/MellowCo/unplugin-transform-we-class
transformWeClass(),
// https://github.com/antfu/unplugin-auto-import
AutoImport({
imports: [
'vue',
'uni-app',
'pinia',
],
dts: true,
vueTemplate: true,
}),
],
})
transformWeClass(),
AutoImport({
imports: [
'vue',
'uni-app',
'pinia',
],
dts: true,
vueTemplate: true,
})
]
})
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save