初始化
This commit is contained in:
commit
2f504b56ff
|
@ -0,0 +1,8 @@
|
||||||
|
# 页面标题
|
||||||
|
VITE_APP_TITLE = 企业微信客户
|
||||||
|
|
||||||
|
# 开发环境配置
|
||||||
|
VITE_APP_ENV = 'development'
|
||||||
|
|
||||||
|
# 若依管理系统/开发环境
|
||||||
|
VITE_APP_BASE_API = '/dev-api'
|
|
@ -0,0 +1,12 @@
|
||||||
|
# 页面标题
|
||||||
|
VITE_APP_TITLE = 企业微信客户
|
||||||
|
|
||||||
|
# 生产环境配置
|
||||||
|
VITE_APP_ENV = 'production'
|
||||||
|
|
||||||
|
|
||||||
|
# 若依管理系统/生产环境
|
||||||
|
VITE_APP_BASE_API = '/prod-api'
|
||||||
|
|
||||||
|
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||||
|
VITE_BUILD_COMPRESS = gzip
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Vue 3 + TypeScript + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||||
|
|
||||||
|
## Type Support For `.vue` Imports in TS
|
||||||
|
|
||||||
|
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
||||||
|
|
||||||
|
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
||||||
|
|
||||||
|
1. Disable the built-in TypeScript Extension
|
||||||
|
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
||||||
|
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
||||||
|
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
|
@ -0,0 +1 @@
|
||||||
|
Qui5f0IP67T3uIhB
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>客户选择</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
|
||||||
|
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"name": "wxjs",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vue-tsc && vite build",
|
||||||
|
"build-only": "vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@vitejs/plugin-legacy": "^5.2.0",
|
||||||
|
"@wecom/jssdk": "^1.4.3",
|
||||||
|
"axios": "^1.5.1",
|
||||||
|
"vant": "^4.7.2",
|
||||||
|
"vue": "^3.3.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.8.7",
|
||||||
|
"@vitejs/plugin-vue": "^4.2.3",
|
||||||
|
"typescript": "^5.0.2",
|
||||||
|
"vite": "^4.4.5",
|
||||||
|
"vue-tsc": "^1.8.5"
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,281 @@
|
||||||
|
<template>
|
||||||
|
<div style="height:45px" v-if="list.length">
|
||||||
|
<span>已选择的客户</span>
|
||||||
|
<van-button
|
||||||
|
size="small"
|
||||||
|
type="warning"
|
||||||
|
@click="delUser"
|
||||||
|
style="float:right"
|
||||||
|
>
|
||||||
|
清空选择
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<van-list
|
||||||
|
class="listCss"
|
||||||
|
v-model:loading="loading"
|
||||||
|
:finished="finished"
|
||||||
|
finished-text="到底啦~~~"
|
||||||
|
v-if="list.length"
|
||||||
|
>
|
||||||
|
<van-radio-group inset>
|
||||||
|
<van-cell
|
||||||
|
v-for="(item, index) in list"
|
||||||
|
:title="item.value"
|
||||||
|
:label="item.corpFullName"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<img
|
||||||
|
:src="item.avatar"
|
||||||
|
style="
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10px;
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</van-cell>
|
||||||
|
</van-radio-group>
|
||||||
|
</van-list>
|
||||||
|
<van-empty description="暂未选择客户" v-else />
|
||||||
|
|
||||||
|
<van-button
|
||||||
|
style="width: 100%; position: fixed; bottom: 0"
|
||||||
|
type="primary"
|
||||||
|
v-if="showBn"
|
||||||
|
@click="setValueUSer"
|
||||||
|
>
|
||||||
|
{{ list.length ? "重新选择(" + list.length + ")" : "客户选择" }}
|
||||||
|
</van-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
import { showConfirmDialog } from 'vant';
|
||||||
|
import { getJsConf, getAgentConf, getUserData } from "@/api/wx";
|
||||||
|
// import * as ww from '@wecom/jssdk'
|
||||||
|
let url = window.location.href.split("#")[0];
|
||||||
|
|
||||||
|
const list = ref([]);
|
||||||
|
const loading = ref(false);
|
||||||
|
const finished = ref(false);
|
||||||
|
const key = getQueryString("key");
|
||||||
|
const selectorType = getQueryString("selectorType");
|
||||||
|
let agentId = "1000164";
|
||||||
|
let code = getQueryString("code");
|
||||||
|
let showBn = ref(false)
|
||||||
|
let userid=localStorage.getItem('userid')
|
||||||
|
|
||||||
|
if (code||userid) {
|
||||||
|
JSsdkPromis().then(res=>{
|
||||||
|
showBn.value =true
|
||||||
|
initSelctData()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
url = encodeURIComponent(url + "&");
|
||||||
|
window.open(
|
||||||
|
"https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww70d3bce9fa48251f&redirect_uri=" +
|
||||||
|
url +
|
||||||
|
"response_type=code&scope=snsapi_base&state=STATE&agentid=" +
|
||||||
|
agentId +
|
||||||
|
"#wechat_redirect",
|
||||||
|
"_self"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//清空
|
||||||
|
function delUser(){
|
||||||
|
showConfirmDialog({
|
||||||
|
title: '清空',
|
||||||
|
message:
|
||||||
|
'是否清空当前选中的客户',
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
list.value = []
|
||||||
|
wx.invoke(
|
||||||
|
"saveApprovalSelectedItems",
|
||||||
|
{
|
||||||
|
key: key, // 字符串,从 URL 中获取到的 key
|
||||||
|
selectedData:JSON.stringify(list.value),
|
||||||
|
},
|
||||||
|
(res) => {
|
||||||
|
if (res.err_msg === "saveApprovalSelectedItems:ok") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// on confirm
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// on cancel
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
//初始化jsSdk校验
|
||||||
|
function JSsdkPromis() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
getJsConf({ url: url, agentId }).then((res) => {
|
||||||
|
let config = res.data;
|
||||||
|
|
||||||
|
wx.config({
|
||||||
|
beta: true, // 必须这么写,否则wx.invoke调用形式的jsapi会有问题
|
||||||
|
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
|
||||||
|
appId: "ww70d3bce9fa48251f", // 必填,企业微信的corpID,必须是本企业的corpID,不允许跨企业使用
|
||||||
|
timestamp: config.timestamp, // 必填,生成签名的时间戳
|
||||||
|
nonceStr: config.nonceStr, // 必填,生成签名的随机串
|
||||||
|
signature: config.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
|
||||||
|
jsApiList: [
|
||||||
|
"saveApprovalSelectedItems",
|
||||||
|
"getApprovalSelectedItems",
|
||||||
|
"selectExternalContact",
|
||||||
|
], // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
|
||||||
|
});
|
||||||
|
wx.ready(function () {
|
||||||
|
getAgentConf({ url: url, agentId }).then((res) => {
|
||||||
|
let config = res.data;
|
||||||
|
wx.agentConfig({
|
||||||
|
corpid: "ww70d3bce9fa48251f", // 必填,企业微信的corpid,必须与当前登录的企业一致
|
||||||
|
agentid: agentId, // 必填,企业微信的应用id (e.g. 1000247)
|
||||||
|
timestamp: config.timestamp, // 必填,生成签名的时间戳
|
||||||
|
nonceStr: config.nonceStr, // 必填,生成签名的随机串
|
||||||
|
signature: config.signature, // 必填,签名,见 附录-JS-SDK使用权限签名算法
|
||||||
|
jsApiList: [
|
||||||
|
"saveApprovalSelectedItems",
|
||||||
|
"getApprovalSelectedItems",
|
||||||
|
"selectExternalContact",
|
||||||
|
], //必填,传入需要使用的接口名称
|
||||||
|
success: function (res) {
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
},
|
||||||
|
fail: function (res) {
|
||||||
|
if (res.errMsg.indexOf("function not exist") > -1) {
|
||||||
|
alert("版本过低请升级");
|
||||||
|
}
|
||||||
|
reject()
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化拿选中的数据
|
||||||
|
function initSelctData() {
|
||||||
|
wx.invoke(
|
||||||
|
"getApprovalSelectedItems",
|
||||||
|
{
|
||||||
|
key: key, // 字符串,从 URL 中获取到的 key
|
||||||
|
},
|
||||||
|
(res) => {
|
||||||
|
if (res.err_msg === "getApprovalSelectedItems:ok") {
|
||||||
|
|
||||||
|
if(res.selectedData){
|
||||||
|
let selectId = JSON.parse(res.selectedData);
|
||||||
|
let data = selectId.map((item) => {
|
||||||
|
return JSON.parse(item.key) ;
|
||||||
|
});
|
||||||
|
|
||||||
|
list.value = data
|
||||||
|
finished.value = true;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取成功,res.selectedData 为获取到的已选中选项的 JSON 字符串,注意可能为空。格式见下文。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//根据客户id拿客户详情
|
||||||
|
function getUSerDataList(data) {
|
||||||
|
|
||||||
|
let useridList = data;
|
||||||
|
finished.value = false;
|
||||||
|
getUserData({
|
||||||
|
useridList,
|
||||||
|
agentId,
|
||||||
|
userid,
|
||||||
|
code
|
||||||
|
}).then((res) => {
|
||||||
|
userid = res.data.userid;
|
||||||
|
localStorage.setItem('userid', res.data.userid)
|
||||||
|
list.value = res.data.contacts.map((item) => {
|
||||||
|
return {
|
||||||
|
key: item.externalUserId,
|
||||||
|
value: item.name,
|
||||||
|
corpFullName: item.corpName,
|
||||||
|
avatar: item.avatar,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
finished.value = true;
|
||||||
|
let data = JSON.parse(JSON.stringify(list.value))
|
||||||
|
data.forEach(item=>{
|
||||||
|
|
||||||
|
let corpName = item.corpFullName?'('+item.corpFullName+')':''
|
||||||
|
item.key = JSON.stringify(item)
|
||||||
|
item.value = item.value+corpName
|
||||||
|
})
|
||||||
|
wx.invoke(
|
||||||
|
"saveApprovalSelectedItems",
|
||||||
|
{
|
||||||
|
key: key, // 字符串,从 URL 中获取到的 key
|
||||||
|
selectedData: JSON.stringify(data),
|
||||||
|
},
|
||||||
|
(res) => {
|
||||||
|
if (res.err_msg === "saveApprovalSelectedItems:ok") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//获取地址栏参数
|
||||||
|
function getQueryString(name) {
|
||||||
|
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
|
||||||
|
let r = window.location.search.substr(1).match(reg);
|
||||||
|
if (r != null) {
|
||||||
|
return unescape(r[2]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//重新选择客户
|
||||||
|
function setValueUSer() {
|
||||||
|
wx.invoke(
|
||||||
|
"selectExternalContact",
|
||||||
|
{
|
||||||
|
filterType: 0, //0表示展示全部外部联系人列表,1表示仅展示未曾选择过的外部联系人。默认值为0;除了0与1,其他值非法。在企业微信2.4.22及以后版本支持该参数
|
||||||
|
},
|
||||||
|
function (res) {
|
||||||
|
if (res.err_msg == "selectExternalContact:ok") {
|
||||||
|
getUSerDataList(res.userIds);
|
||||||
|
} else {
|
||||||
|
//错误处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.flexdCss {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.tagCss {
|
||||||
|
margin-top: 55px;
|
||||||
|
}
|
||||||
|
.listCss {
|
||||||
|
height: calc(100vh - 90px);
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
:deep(.van-tag) {
|
||||||
|
padding: 5px;
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,22 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
export function getJsConf(data){
|
||||||
|
return request({
|
||||||
|
url:'/wxcp/getJsConf',
|
||||||
|
method: 'post',
|
||||||
|
data:data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function getAgentConf(data){
|
||||||
|
return request({
|
||||||
|
url:'/wxcp/getAgentConf',
|
||||||
|
method: 'post',
|
||||||
|
data:data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function getUserData(data){
|
||||||
|
return request({
|
||||||
|
url:'/wxcp/getExternalcontact',
|
||||||
|
method: 'post',
|
||||||
|
data:data
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
After Width: | Height: | Size: 496 B |
|
@ -0,0 +1,39 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
defineProps<{ msg: string }>()
|
||||||
|
|
||||||
|
const count = ref(0)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<button type="button" @click="count++">count is {{ count }}</button>
|
||||||
|
<p>
|
||||||
|
Edit
|
||||||
|
<code>components/HelloWorld.vue</code> to test HMR
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Check out
|
||||||
|
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
||||||
|
>create-vue</a
|
||||||
|
>, the official Vue + Vite starter
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Install
|
||||||
|
<a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
|
||||||
|
in your IDE for a better DX
|
||||||
|
</p>
|
||||||
|
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.read-the-docs {
|
||||||
|
color: #888;
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import { Search,List, Cell, CellGroup,Radio ,RadioGroup ,Tag,Button,Empty } from 'vant';
|
||||||
|
import './style.css'
|
||||||
|
import App from './App.vue'
|
||||||
|
import 'vant/lib/index.css';
|
||||||
|
const app = createApp(App);
|
||||||
|
app.use(Search)
|
||||||
|
app.use(List )
|
||||||
|
app.use(Cell);
|
||||||
|
app.use(Radio);
|
||||||
|
app.use(CellGroup);
|
||||||
|
app.use(RadioGroup);
|
||||||
|
app.use(Tag);
|
||||||
|
app.use(Empty);
|
||||||
|
app.use(Button);
|
||||||
|
app.mount('#app')
|
|
@ -0,0 +1,39 @@
|
||||||
|
:root {
|
||||||
|
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
color-scheme: light dark;
|
||||||
|
color: rgba(255, 255, 255, 0.87);
|
||||||
|
background-color: #242424;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #646cff;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #535bf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
color: #213547;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #747bff;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let downloadLoadingInstance;
|
||||||
|
// 是否显示重新登录
|
||||||
|
export let isRelogin = { show: false };
|
||||||
|
|
||||||
|
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
||||||
|
// 对应国际化资源文件后缀
|
||||||
|
axios.defaults.headers['Content-Language'] = 'zh_CN'
|
||||||
|
// 创建axios实例
|
||||||
|
const service = axios.create({
|
||||||
|
// axios中请求配置有baseURL选项,表示请求URL公共部分
|
||||||
|
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||||
|
// 超时
|
||||||
|
timeout: 10000
|
||||||
|
})
|
||||||
|
|
||||||
|
// request拦截器
|
||||||
|
service.interceptors.request.use(config => {
|
||||||
|
|
||||||
|
// 是否需要防止数据重复提交
|
||||||
|
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
|
||||||
|
|
||||||
|
// get请求映射params参数
|
||||||
|
if (config.method === 'get' && config.params) {
|
||||||
|
let url = config.url + '?' + tansParams(config.params);
|
||||||
|
url = url.slice(0, -1);
|
||||||
|
config.params = {};
|
||||||
|
config.url = url;
|
||||||
|
}
|
||||||
|
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
|
||||||
|
const requestObj = {
|
||||||
|
url: config.url,
|
||||||
|
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
|
||||||
|
time: new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
console.log(config)
|
||||||
|
return config
|
||||||
|
}, error => {
|
||||||
|
console.log(error)
|
||||||
|
Promise.reject(error)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 响应拦截器
|
||||||
|
service.interceptors.response.use(res => {
|
||||||
|
|
||||||
|
// 未设置状态码则默认成功状态
|
||||||
|
const code = res.data.code || 200;
|
||||||
|
// 获取错误信息
|
||||||
|
|
||||||
|
if (code == 200){
|
||||||
|
return Promise.resolve(res.data)
|
||||||
|
}else{
|
||||||
|
alert(res.data.msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
console.log('err' + error)
|
||||||
|
let { message } = error;
|
||||||
|
if (message == "Network Error") {
|
||||||
|
message = "后端接口连接异常";
|
||||||
|
} else if (message.includes("timeout")) {
|
||||||
|
message = "系统接口请求超时";
|
||||||
|
} else if (message.includes("Request failed with status code")) {
|
||||||
|
message = "系统接口" + message.substr(message.length - 3) + "异常";
|
||||||
|
}
|
||||||
|
alert(message)
|
||||||
|
return Promise.reject(error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default service
|
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="vite/client" />
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/main.js"],
|
||||||
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import path from 'path'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import legacy from "@vitejs/plugin-legacy";
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
legacy({
|
||||||
|
targets: [
|
||||||
|
|
||||||
|
"Safari >= 10.1",
|
||||||
|
"iOS >= 8",
|
||||||
|
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
// 设置别名
|
||||||
|
'@': path.resolve(__dirname, './src'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
port: 80,
|
||||||
|
host: true,
|
||||||
|
open: true,
|
||||||
|
proxy: {
|
||||||
|
// https://cn.vitejs.dev/config/#server-proxy
|
||||||
|
'/dev-api': {
|
||||||
|
target: 'http://water.lidinghb.com:9090/',
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
Loading…
Reference in New Issue