Browse Source

feat: 基础目录创建

sunxiao 11 months ago
parent
commit
1d1084baab

+ 1 - 1
README.md

@@ -1,4 +1,4 @@
-# temp-vue-3
+# slibra-module-web
 
 This template should help get you started developing with Vue 3 in Vite.
 

File diff suppressed because it is too large
+ 782 - 30
package-lock.json


+ 6 - 0
package.json

@@ -11,7 +11,10 @@
     "type-check": "vue-tsc --build --force"
   },
   "dependencies": {
+    "axios": "^1.6.8",
     "pinia": "^2.1.7",
+    "sass": "^1.77.1",
+    "sass-loader": "^14.2.1",
     "vue": "^3.4.21",
     "vue-router": "^4.3.0"
   },
@@ -21,7 +24,10 @@
     "@vitejs/plugin-vue": "^5.0.4",
     "@vitejs/plugin-vue-jsx": "^3.1.0",
     "@vue/tsconfig": "^0.5.1",
+    "autoprefixer": "^10.4.19",
     "npm-run-all2": "^6.1.2",
+    "postcss": "^8.4.38",
+    "tailwindcss": "^3.4.3",
     "typescript": "~5.4.0",
     "vite": "^5.2.8",
     "vite-plugin-vue-devtools": "^7.0.25",

+ 6 - 0
postcss.config.js

@@ -0,0 +1,6 @@
+export default {
+  plugins: {
+    tailwindcss: {},
+    autoprefixer: {},
+  },
+}

+ 7 - 3
src/App.vue

@@ -6,10 +6,9 @@ import HelloWorld from './components/HelloWorld.vue'
 <template>
   <header>
     <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />
-
+    <p class="mr-5 bg-black">hello</p>
     <div class="wrapper">
       <HelloWorld msg="You did it!" />
-
       <nav>
         <RouterLink to="/">Home</RouterLink>
         <RouterLink to="/about">About</RouterLink>
@@ -20,10 +19,15 @@ import HelloWorld from './components/HelloWorld.vue'
   <RouterView />
 </template>
 
-<style scoped>
+<style scoped lang="scss">
 header {
+  @include flex(x, center, cetner);
+  background: $el-bg-color;
   line-height: 1.5;
   max-height: 100vh;
+  img {
+    width: 200px;
+  }
 }
 
 .logo {

+ 61 - 0
src/api/home.ts

@@ -0,0 +1,61 @@
+import http from "@/utils/request";
+import type { Result } from "@/types/data";
+import type { ContractListParams, ContractListResult, SignBatchParams, ExtReqResult, TemplateStatusParams, TemplateContentParams, TemplateContentResult, TemplateConfirmParams, SendCaptchaParams, VerifyCaptchaParams } from "@/types/home";
+
+export const homeApi = {
+  /**
+   * 获取签署文件列表
+   * @param data
+   * @returns ContractListResult
+   */
+  getContractFile: (data: ContractListParams) => http.post<ContractListResult[]>('/auth/signgateway/sign/querySignData', data),
+
+  /**
+   * 提交批量签署合同
+   * @param data 
+   * @returns ExtReqResult or any
+   */
+  postBatchSign: (data: SignBatchParams) => http.post<Result<ExtReqResult>[]>('/auth/signgateway/sign/hdb/batchSignContract', data),
+
+  /**
+   * 协议签署状态
+   * @param data 
+   * @returns boolean
+   */
+  getTemplateStatus: (data: TemplateStatusParams) => http.post<boolean>('/basic/m/new/validate/sign', data),
+
+  /**
+   * 协议内容
+   * @param data 
+   * @returns TemplateContentResult
+   */
+  getTemplateContent: (params: TemplateContentParams) => http.get<TemplateContentResult>('/basic/n/find/agre/type', {params}),
+  
+  /**
+   * 确认协议
+   * @param data
+   * @returns boolean
+   */
+  postTemplateConfirm: (data:TemplateConfirmParams) => http.post<boolean>('/basic/m/sign/agrt', data),
+
+  /**
+   * 获取登录人手机号
+   * @param data
+   * @returns boolean
+   */
+  getPhoneCode: () => http.get<string>('/auth/getInfoBeforeSendSms'),
+
+  /**
+   * 发送验证码
+   * @param data
+   * @return null
+   */
+  getCaptcha: (data: SendCaptchaParams) => http.post<null>('/auth/sendVerificationMessageSms', data),
+  
+  /**
+   * 短信验证码验证结果
+   * @param data
+   * @returns boolean
+   */
+  postVerifyCaptcha: (data: VerifyCaptchaParams) => http.post<null>('/auth/submitVerifyMessageCode', data),
+}

+ 16 - 0
src/assets/styles/common.scss

@@ -0,0 +1,16 @@
+.carbon-desc-container {
+  font-size: 18px;
+  text-align: center;
+  line-height: 26px;
+  color: $t-color-sub;
+}
+
+@font-face {
+  font-display: swap;
+  font-family: 'AlimamaShuHeiTi';
+  src: url('/fonts/AlimamaShuHeiTi-Bold.woff2') format('woff2'),
+  url('/fonts/AlimamaShuHeiTi-Bold.woff') format('woff'),
+  url('/fonts/AlimamaShuHeiTi-Bold.ttf') format('ttf');
+  font-weight: normal;
+  font-style: normal;
+}

+ 4 - 0
src/assets/styles/index.scss

@@ -0,0 +1,4 @@
+// @import "./mixins.scss";
+@import "./variables.scss";
+@import "common.scss";
+@import "reset.css";

+ 25 - 0
src/assets/styles/mixins.scss

@@ -0,0 +1,25 @@
+$flex-params: (
+  x: row,
+  y: column,
+  start: flex-start,
+  end: flex-end,
+  center: center,
+  around: space-around,
+  between: space-between,
+);
+
+@mixin flex($coor: null, $alignItems: null, $justify: null, ) {
+  display: flex;
+
+  @if $coor {
+    flex-direction: map-get($flex-params, $coor);
+  }
+
+  @if $alignItems {
+    align-items: map-get($flex-params, $alignItems);
+  }
+
+  @if $justify {
+    justify-content: map-get($flex-params, $justify);
+  }
+}

+ 140 - 0
src/assets/styles/reset.css

@@ -0,0 +1,140 @@
+body {
+  height: 100%;
+  -moz-osx-font-smoothing: grayscale;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+  font-family: PingFang SC, Noto Sans SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+  overflow-x: hidden;
+}
+
+/* Helvetica Neue, Helvetica, */
+label {
+  font-weight: 700;
+}
+
+html {
+  /* height: 100%; */
+  box-sizing: border-box;
+}
+
+#app {
+  height: 100%;
+}
+
+*,
+*:before,
+*:after {
+  box-sizing: inherit;
+}
+
+body,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+p,
+blockquote,
+dl,
+dt,
+dd,
+ul,
+ol,
+li,
+pre,
+form,
+fieldset,
+legend,
+button,
+input,
+textarea,
+th,
+td {
+  margin: 0;
+  padding: 0;
+}
+
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-size: 100%;
+  background: red;
+}
+
+address,
+cite,
+dfn,
+em,
+var {
+  font-style: normal;
+}
+
+ul,
+ol {
+  list-style: none;
+}
+
+a {
+  text-decoration: none;
+}
+
+a:hover {
+  text-decoration: underline;
+}
+
+sup {
+  vertical-align: text-top;
+}
+
+sub {
+  vertical-align: text-bottom;
+}
+
+legend {
+  color: #000;
+}
+
+fieldset,
+img {
+  border: 0;
+}
+
+i {
+  font-style: normal;
+}
+
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+video:focus {
+  outline: none;
+}
+
+::-webkit-scrollbar {
+  width: 5px;
+}
+
+::-webkit-scrollbar-track {
+  background-color: #f1f1f1;
+}
+
+::-webkit-scrollbar-thumb {
+  background-color: rgba(0, 0, 0, .25);
+  border-radius: 5px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+  background-color: rgba(0, 0, 0, 0.4);
+}
+
+::-webkit-scrollbar-button {
+  display: none;
+}

+ 3 - 0
src/assets/styles/tailwind.css

@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;

+ 11 - 0
src/assets/styles/variables.scss

@@ -0,0 +1,11 @@
+/* 背景色 */
+$el-bg-color: #f2f4f6;
+
+$primary: #0092FF;
+
+/* 文字颜色 */
+$t-color-primary    : #020F1C; 
+$t-color-sub        : #666666;
+$t-color-active     : #0092FF;
+$t-color-hover      : #0092FF;
+$t-color-sub-text   : #565F83;

+ 4 - 2
src/main.ts

@@ -1,14 +1,16 @@
 import './assets/main.css'
+import './assets/styles/tailwind.css'
+import './assets/styles/index.scss'
 
 import { createApp } from 'vue'
-import { createPinia } from 'pinia'
 
 import App from './App.vue'
 import router from './router'
+import pinia from './stores'
 
 const app = createApp(App)
 
-app.use(createPinia())
+app.use(pinia)
 app.use(router)
 
 app.mount('#app')

+ 5 - 0
src/stores/index.ts

@@ -0,0 +1,5 @@
+import { createPinia } from "pinia";
+
+const pinia = createPinia();
+
+export default pinia;

+ 11 - 0
src/types/data.d.ts

@@ -0,0 +1,11 @@
+/** 基础数据结构 - 子类选项 */
+export type Result<T = any> = {
+  code: number | null,
+  data: T,
+  message: string | null,
+  pageCount: number,
+  pageNum: number,
+  pageSize: number,
+  success: boolean,
+  total: number
+}

+ 158 - 0
src/types/home.d.ts

@@ -0,0 +1,158 @@
+export interface ApifoxModel {
+  code?: null | string;
+  data?: SignPrepareResult[] | null;
+  message?: null | string;
+  pageCount?: number | null;
+  pageNum?: number | null;
+  pageSize?: number | null;
+  success?: boolean | null;
+  total?: number | null;
+}
+
+/** params - 获取签署合同信息 */
+export interface ContractListParams {
+  /**
+   * 多个合同号用逗号拼接
+   */
+  contractNoArr?: string;
+  signOrPreview: string | number;
+}
+
+/** res - 获取签署合同信息 */
+export interface ContractListResult {
+  /**
+   * 合同文件地址
+   */
+  contractFileObjectKey?: null | string;
+  /**
+   * 合同号
+   */
+  contractNo: string;
+  /**
+   * 关键字
+   */
+  keyWord: string;
+  /**
+   * 印章集合
+   */
+  stampResultList: StampResult[];
+}
+
+/** res - 印章信息 */
+export interface StampResult {
+  /**
+   * 是否启用
+   */
+  enable?: null | string;
+  /**
+   * 印章顺序(0是默认章,从1开始)
+   */
+  order?: number | null;
+  /**
+   * 印章地址
+   */
+  stampAddress?: string;
+  /**
+   * 印章ID
+   */
+  stampId?: null | string;
+  /**
+   * 印章名称
+   */
+  stampName?: null | string;
+  /**
+   * 印章用途
+   */
+  stampType?: null | string;
+}
+
+/** params - 签章批量签署 */
+export interface SignBatchChildParams {
+  /**
+   * 合同号
+   */
+  contractNo?: null | string;
+  /**
+   * 签章信息
+   */
+  stampDTOList?: StampDTO[] | null;
+}
+export interface SignBatchParams {
+  /**
+   * 合同信息key
+   */
+  signContractVOList: SignBatchChildParams[]
+}
+
+/** params - 印章信息 */
+export interface StampDTO {
+  /**
+   * 企业ID
+   */
+  memberId?: null | string;
+  /**
+   * 印章ID,如无指定, 用默认印章
+   */
+  stampId?: null | string;
+}
+
+/** params - 印章信息 */
+export interface ExtReqResult {
+  contractContent?: null | string;
+  contractId?: null | string;
+  extReqLogId?: null | string;
+}
+// /** params - 印章信息 */
+// export interface ExtReqChildResult {
+//   contractContent?: null | string;
+//   contractId?: null | string;
+//   extReqLogId?: null | string;
+// }
+
+
+//** ----------------------------------------------------- */
+
+/** params - 云签状态 */
+export interface TemplateStatusParams {
+  /**
+   * 云签模版ID
+   */
+  agreementType: string;
+}
+
+/** params - 云签模版 */
+export interface TemplateContentParams {
+  /**
+   * 云签模版ID
+   */
+  type?: null | string;
+}
+
+/** res - 云签模版 */
+export interface TemplateContentResult {
+  agreementName: string;
+  templateHtml: string;
+  agreementType: string;
+  templateId: string;
+}
+
+//** ----------------------------------------------------- */
+
+/** params - 云签确认 */
+export interface TemplateConfirmParams {
+  isflag: number;
+  templateId: string;
+  agreementType: string;
+}
+
+/** params - 发送验证码 */
+export interface SendCaptchaParams {
+  businessNo?: string;
+  businessType?: string;
+  billType?: string;
+}
+
+/** params - 验证验证码 */
+export interface VerifyCaptchaParams extends SendCaptchaParams {
+  captcha: string;
+}

+ 13 - 0
src/types/modules.d.ts

@@ -0,0 +1,13 @@
+/// <reference path="node_modules/@tybys/jweixin/typings/jweixin.d.ts" />
+declare module "vue3-pdfjs" {
+  import type { VuePdf } from "vue3-pdfjs/components"
+  export type { VuePdf }
+}
+
+// declare module 'wx' {
+//   class wx {
+//     static miniProgram: any;
+//   }
+//   export default wx;
+// }
+

+ 117 - 0
src/utils/request.ts

@@ -0,0 +1,117 @@
+import axios from 'axios';
+// import { createDiscreteApi } from 'naive-ui';
+
+import { tansParams, LocalCache, getQueryParamsAsObject } from "@/utils/tools";
+
+import type { Result } from '@/types/data';
+import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig, AxiosError } from 'axios';
+
+// import type { NotificationApi } from "naive-ui";
+
+// const { notification } = createDiscreteApi(["notification"]);
+
+const CACHE_KEY = 'userInfo';
+const url = import.meta.env.VITE_BASE_URL;
+const prefix = import.meta.env.VITE_BASE_PREFIX;
+const baseURL = url + prefix;
+
+enum errorCode {
+  '请求错误'          = 400,
+  '未授权,请重新登录' = 401,
+  '拒绝访问'          = 403,
+  '请求出错'          = 404,
+  '请求超时'          = 408,
+  '服务器错误'        = 500,
+  '服务未实现'        = 501,
+  '网络错误'          = 502,
+  '服务不可用'        = 503,
+  '网络超时'          = 504,
+  'HTTP版本不受支持'   = 505
+}
+
+// const showNotification = (type: keyof NotificationApi = 'error', meta: string) => {
+//   notification[type]({
+//     content: '提示',
+//     meta,
+//     duration: 3 * 1000,
+//     keepAliveOnHover: true
+//   })
+// }
+
+export class Request {
+
+  private instance: AxiosInstance;
+
+  private baseConfig: AxiosRequestConfig = { baseURL, timeout: 30 * 1000 };
+
+  constructor(config: AxiosRequestConfig = {}) {
+    this.instance = axios.create({ ...this.baseConfig, ...config });
+
+    this.instance.interceptors.request.use((config: InternalAxiosRequestConfig<Result>) => {
+      if (config.method === "get" && config.params) {
+        let url = config.url + '?' + tansParams(config.params);
+        url = url.slice(0, -1);
+        config.params = {};
+        config.url = url;
+      }
+      const urlParams = getQueryParamsAsObject();
+
+      const userInfo = LocalCache.getCache(CACHE_KEY);
+
+      config.headers.Authorization = urlParams.token || userInfo?.token ;
+
+      return config;
+    }, (err: any) => {
+      return Promise.reject(err)
+    });
+
+    this.instance.interceptors.response.use(res => {
+      const { success, message } = res.data;
+      // !success && showNotification("error", message);
+      return success ? res.data : Promise.reject(res);
+    }, (error: AxiosError) => {
+      const errorMessage = errorCode[error.response?.status as number] || '未知错误';
+      // showNotification("error", errorMessage);
+      return error;
+    })
+  }
+
+  public request(config: AxiosRequestConfig): Promise<AxiosResponse> {
+    return this.instance.request(config);
+  }
+
+  public get<T = any>(
+    url: string,
+    config?: AxiosRequestConfig
+  ): Promise<Result<T>> {
+    return this.instance.get(url, config);
+  }
+
+  public post<T = any>(
+    url: string,
+    data?: any,
+    config?: AxiosRequestConfig
+  ): Promise<Result<T>> {
+    return this.instance.post(url, data, config);
+  }
+
+  public put<T = any>(
+    url: string,
+    data?: any,
+    config?: AxiosRequestConfig
+  ): Promise<Result<T>> {
+    return this.instance.put(url, data, config);
+  }
+
+  public delete<T = any>(
+    url: string,
+    config?: AxiosRequestConfig
+  ): Promise<Result<T>> {
+    return this.instance.delete(url, config);
+  }
+}
+
+export default new Request({
+  baseURL,
+  timeout: 10 * 1000
+});

+ 74 - 0
src/utils/tools.ts

@@ -0,0 +1,74 @@
+const baseUrl = import.meta.env.VITE_BASE_URL;
+const basePrefix = import.meta.env.VITE_BASE_PREFIX;
+
+interface IUrlParams {
+  [propsName: string]: any
+}
+
+/** 统一 - get和post请求书写方式 */
+export function tansParams(params: any): string {
+  let result = ''
+  for (const propName of Object.keys(params)) {
+    const value = params[propName];
+    const part = encodeURIComponent(propName) + "=";
+    if (value !== null && typeof (value) !== "undefined") {
+      if (typeof value === 'object') {
+        for (const key of Object.keys(value)) {
+          if (value[key] !== null && typeof (value[key]) !== 'undefined') {
+            const params = propName + '[' + key + ']';
+            const subPart = encodeURIComponent(params) + "=";
+            result += subPart + encodeURIComponent(value[key]) + "&";
+          }
+        }
+      } else {
+        result += part + encodeURIComponent(value) + "&";
+      }
+    }
+  }
+  return result;
+}
+
+/** localhost - methods */
+export class LocalCache {
+  static setCath(key: string, value: any) {
+    window.localStorage.setItem(key, JSON.stringify(value));
+  }
+  static getCache(key: string) {
+    const value = window.localStorage.getItem(key);
+    return value ? JSON.parse(value) : {};
+  }
+  static deleteCatch(key: string) {
+    window.localStorage.removeItem(key);
+  }
+  static clearCache() {
+    window.localStorage.clear();
+  }
+}
+
+// get file path
+export const getPreviewPath = (fileObjectKey = '') => {
+  return baseUrl + basePrefix + "/auth/t/queryFiles?fileName=" + new Date().getTime() + ".pdf&fileObjectKey=" + fileObjectKey;
+}
+
+export const getQueryParamsAsObject = (url?: string) => {
+  url = url || window.location.href;
+
+  const queryString = url.split('?')[1];
+
+  if (!queryString) {
+    return {};
+  }
+
+  const queryParams = queryString.split('&');
+
+  const paramsObj:IUrlParams = {};
+
+  queryParams.forEach(function(param) {
+    const parts = param.split('=');
+    const key = decodeURIComponent(parts[0]);
+    const value = decodeURIComponent(parts[1]);
+    paramsObj[key] = value;
+  });
+
+  return paramsObj;
+}

+ 11 - 0
tailwind.config.js

@@ -0,0 +1,11 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+  content: [],
+  purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
+  darkMode: false,
+  theme: {
+    extend: {},
+  },
+  plugins: [],
+}
+

+ 9 - 0
vite.config.ts

@@ -16,5 +16,14 @@ export default defineConfig({
     alias: {
       '@': fileURLToPath(new URL('./src', import.meta.url))
     }
+  },
+  css: {
+    preprocessorOptions: {
+      scss: {
+        additionalData: `
+          @import "@/assets/styles/mixins.scss"; 
+          @import "@/assets/styles/variables.scss";`
+      }
+    }
   }
 })

Some files were not shown because too many files changed in this diff