This commit is contained in:
2023-11-07 17:11:57 +08:00
commit 1358e52fdb
643 changed files with 84924 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
/.hbuilderx
/node_modules
/unpackage
+55
View File
@@ -0,0 +1,55 @@
<script>
import config from '@/app.config.js'
import { version } from './package.json'
export default {
methods: {
},
// 监听 - 页面404
onPageNotFound:function(e) {
uni.redirectTo({
url: config.error.url
})
},
onLaunch: function(options) {
// 注意:config.debug 在正式环境时,值为false,故此{}内的代码只有开发环境才会执行
if (config.debug) {
// #ifndef APP-PLUS
console.log(
`%c vk-client %c v${version} `,
'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px; color: #fff',
'background:#007aff ;padding: 1px; border-radius: 0 3px 3px 0; color: #fff; font-weight: bold;'
);
// #endif
console.log('App Launch');
}
// 注意:以下代码正式和开发环境都会执行
// #ifdef MP
uni.vk.updateManager.updateReady(); // 此代码可以让小程序自动检测最新版本
// #endif
},
onShow: function() {
if (config.debug) console.log("App Show");
// #ifdef MP-WEIXIN
// 检测如果当前是体验版,但没有点HBX的【发行】菜单发布,则提示开发者请点【发行】按钮
try {
console.log('当前运行模式: ', process.env.NODE_ENV);
const info = uni.getAccountInfoSync();
if (info.miniProgram.envVersion === "trial" && process.env.NODE_ENV !== 'production') {
// 如果不想要alert弹窗提示,可以将vk.alert改成console.log
uni.vk.alert('检测到您当前发布的【体验版】是通过【运行】按钮打包发布的,请重新点击HBX上方菜单的【发行】按钮进行打包发布小程序(如果确定是【发行】按钮打包的,请删除手机上的体验版小程序并重新扫码进入)', '重要提示', '好的');
}
} catch(err){}
// #endif
},
onHide: function() {
if(config.debug) console.log('App Hide');
}
}
</script>
<style lang="scss">
/*每个页面公共css */
// @import "./uni_modules/vk-uview-ui/index.scss";
@import "./common/css/app.scss";
</style>
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 VK
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+498
View File
@@ -0,0 +1,498 @@
### uniCloud云函数路由框架研究Q群:22466457 如有问题或建议可以在群内讨论。
### 插件名称:`vk-unicloud-router`
### 作者:VK
## 序
##### 如果你热爱编程,想快速入门云开发,欢迎使用`vk-unicloud`系列开发框架
##### 无需转变开发习惯,0成本上手云开发。
##### 框架内置了众多API、工具包,为你的业务扫平障碍。使你的项目刚起步进度就是50%(微信登录、短信、验证码、缓存、生成小程序码等等)
##### 从此你又get一个新技能,只需用js,轻松搞定前后台整体业务。
##### 完整框架项目地址:
##### `client端`框架地址: [https://ext.dcloud.net.cn/plugin?id=2204](https://ext.dcloud.net.cn/plugin?id=2204)
##### `admin端`框架地址:[https://ext.dcloud.net.cn/plugin?id=5043](https://ext.dcloud.net.cn/plugin?name=vk-unicloud-admin)
##### `client端`框架文档:[点击查看](https://vkdoc.fsq.pub/client/)
##### `admin端`框架文档:[点击查看](https://vkdoc.fsq.pub/admin/)
##### 框架学习Q群:`22466457` 欢迎萌新和大佬来使用和共同改进框架
## 主要功能 以及 对开发者的价值
#### 1、实现云函数路由模式(同时支持对云对象的路由)
* 1.1、路由模式不使用任何第三方包,兼容性强,运行稳定
* 1.2、减少云函数数量,云函数有个数限制(用一个云函数即可实现多个云函数效果)
* 1.3、部分通用的代码块可以放在公共区执行,具有公共函数的效果,增加代码复用率,便于维护。
* 1.4、可以在开发环境和生产环境中任意切换,开发时,用开发环境,开发过程中不会影响到线上环境。(具体切换方法在文档最后)
* 1.5、美化云函数请求过程中的日志排版,使请求日志一目了然。(再也不用为日志分散,难找而头疼)
* 1.6、可以强制关闭云端服务(适用于需要临时关闭后端服务的情况,如腾讯云迁移数据到阿里云时需要先关闭服务,否则迁移过程中会有新数据产生)
#### 2、实现 `全局过滤器`,过滤非法请求。您无需关心用户角色权限问题。
#### 3、众多现成的 `JS API`,让您无需重复造轮子。(持续增加中)
#### 4、众多现成的 `云函数 API`,为您的业务扫平障碍,让您可以专注于自身业务开发。(微信登录、短信、验证码、缓存、生成小程序码等等)(持续增加中)
#### 5、全面支持 `url化` 的云函数请求,您无需关心url化后参数的获取问题
#### 6、已集成 `uni-id` 当前版本: `3.3.28`(已支持真实发送邮箱验证码和短信验证码)
* 6.1、由于每个应用基本都会用上用户系统,官方建议所有 `uniCloud` 应用均使用 `uni-id` 作为用户体系,
有了统一的账户规范,并且围绕这套账户规范,有各种各样插件,那么开发者可以随意整合这些插件,让数据连同。
* 6.2、同时方便其他用户使用 `unicloud` 插件发布者发布的前后端一体插件,只需要导入一个云函数即可。
(如导入一个社区插件,可能要导入几十个云函数,而使用此云函数路由后,只需导入一个云函数,且已集成 `uni-id`,打通账号体系)。
#### 7、在 `uni-id` 基础上升级为 `vk.userCenter` 用户中心API 通过this.vk.userCenter 即可调用 [传送门](https://vkdoc.fsq.pub/client/vk.userCenter.html)
#### 8、封装 `uni.callFunction` 和 `uni.request` 使之合二为一 通过this.vk.callFunction 调用
#### 9、`vk.baseDao` 数据库API,使小白也能轻松上手对数据库的调用。 [传送门](https://vkdoc.fsq.pub/client/uniCloud/db/api.html)
#### 10、`vk.baseDao.selects` 数据库万能连表查询API [传送门](https://vkdoc.fsq.pub/client/uniCloud/db/selects.html)
#### 11、`商品SKU选择器组件`(打造uni插件市场功能最全的SKU选择器组件)[传送门](https://ext.dcloud.net.cn/plugin?id=2848)
#### 12、对 `Vuex` 进行了深度封装(支持持久化),现在可以很方便的使用Vuex进行读取和储存。[传送门](https://vkdoc.fsq.pub/client/pages/vuex.html)
#### 13、自定义过滤器(在业务云函数执行之前(或之后),统一拦截,进行过滤后再放行,支持设置多个过滤器,并按指定顺序执行)[传送门](https://vkdoc.fsq.pub/client/uniCloud/middleware/filter.html)
#### 14、支持设置需要登录的页面列表或不需要登录的页面列表(通过本地token检测,无网络请求,支持通配符写法)[传送门](https://vkdoc.fsq.pub/client/pages/config.html)
#### 15、支持设置可以被分享的页面列表或禁止分享的页面列表(支持通配符写法)[传送门](https://vkdoc.fsq.pub/client/pages/config.html)
#### 16、`vk.localStorage` 封装本地缓存的curd,同时具有监听缓存被更新和被删除的功能。[传送门](https://vkdoc.fsq.pub/client/pages/localStorage.html)
#### 17、美化云函数请求过程中的日志排版,使请求日志一目了然。
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-cf0c5e69-620c-4f3c-84ab-f4619262939f/4a44fbf8-6b5e-43a6-b443-51a108dec125.png)
#### 18、可以 `强制关闭` 云端服务(适用于需要临时关闭后端服务的情况,如腾讯云迁移数据到阿里云时需要先关闭服务,否则迁移过程中会有新数据产生)
#### 19、全局数据缓存API,现在可以很方便的在云函数中使用缓存。 [传送门](https://vkdoc.fsq.pub/client/uniCloud/cache/cache.html)
#### 20【全网首家】云函数URL化之URL重写 [传送门](https://vkdoc.fsq.pub/client/uniCloud/cloudfunctions/urlrewrite.html)
#### 21、千人群交流开发心得,助你避坑,作者亲自在群内解答框架使用问题,让你轻松上手 `uniCloud云开发`。
#### 22、其他好处…
### 目前已集成的服务端API
#### 1、微信小程序服务端API [传送门](https://vkdoc.fsq.pub/client/uniCloud/plus/weixin.html)
#### 2、微信公众号服务端API [传送门](https://vkdoc.fsq.pub/client/uniCloud/plus/weixin-h5.html)
#### 3、百度开放平台服务端API [传送门](https://vkdoc.fsq.pub/client/uniCloud/plus/baidu.html)
#### 4、短信发送 [传送门](https://vkdoc.fsq.pub/client/uniCloud/plus/sms.html)
#### 5、邮箱发送 [传送门](https://vkdoc.fsq.pub/client/uniCloud/plus/mail.html)
#### 6、Redis [传送门](https://vkdoc.fsq.pub/vk-redis/)
##### 插件部分API功能体验地址
![插件首页体验地址](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-vk-cloud-router-test/51de83e0-e9ae-11ea-81ea-f115fe74321c.png?x-oss-process=image/resize,h_250 "插件首页体验地址")
## 快速上手 - 安装步骤
## 后端(云函数端)安装步骤
打开 `uniCloud/cloudfunctions` 目录
#### 前置工作:修改云函数全局配置文件(用到微信登录的必须要配置)[微信小程序配置详细教程](https://vkdoc.fsq.pub/client/question/q12.html)
#### 注意:
* 1、开发微信小程序和APP微信登录需要额外配置 manifest.json 以及 uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json 这2个配置文件,且改动配置后需要重新上传 公共模块 和 router 函数。
* 2、若你的电脑没有安装 Node.js,则无法使用 npm 命令。
* 3、Node.js 安装包及源码下载地址为:[https://nodejs.org/en/download/](https://nodejs.org/en/download/)
* 4、Node.js 安装教程:[https://www.runoob.com/nodejs/nodejs-install-setup.html](https://www.runoob.com/nodejs/nodejs-install-setup.html)
查看 `uni-id/config.json` 代码格式 [点击查看](https://vkdoc.fsq.pub/client/uniCloud/config/uni-id.html)
#### 正式安装
直接右键`uniCloud`目录 点击 `运行云服务空间初始化向导` 即可
## 前端(页面端)安装步骤
### 自 `client` 端框架 `2.6.0` 起,不再内置任何 UI 框架,你可以选择自己喜欢的 UI 组件库进行开发。
### 集成 `vk-uview-ui`(vue2.0版)
___若不想集成 `vk-uview-ui` 可跳过此处___
适合开发:H5、App(vue版本)、微信小程序、支付宝小程序(其他小程序未验证)
> 插件市场导入 `vk-uview-ui` 框架:[点击前往](https://ext.dcloud.net.cn/plugin?id=6692)
* 1、main.js 引入 vk-uview-ui
```js
import uView from './uni_modules/vk-uview-ui';
Vue.use(uView);
```
* 2、App.vue 引入基础样式(注意style标签需声明scss属性支持)
```html
<style lang="scss">
@import "./uni_modules/vk-uview-ui/index.scss";
</style>
```
* 3、uni.scss 引入全局 scss 变量文件
```css
@import "@/uni_modules/vk-uview-ui/theme.scss";
```
### 集成 `vk-uview-ui`(vue3.0版)
___若不想集成 `vk-uview-ui` 可跳过此处___
适合开发:H5、App(vue版本)、微信小程序(其他小程序未验证)
> 插件市场导入 `vk-uview-ui` 框架:[点击前往](https://ext.dcloud.net.cn/plugin?id=6692)
不建议把老项目 升级到 Vue3.0 (升级非常麻烦,建议新项目才考虑是否使用Vue3.0)
___注意:目前(2020-11-18) `uniapp` 的 `Vue3.0` 版本只兼容:H5、App、微信小程序___
* 1、前置步骤:修改 `manifest.json` 内的 `vue` 版本为 `vue3`
* 2、项目根目录新增 `index.html` 文件,文件代码为
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
<title></title>
<!--preload-links-->
<!--app-context-->
<!-- 配置H5的 web图标static/logo.png -->
<link rel="icon" href="./static/logo.png" />
</head>
<body>
<div id="app">
<!--app-html-->
</div>
<script type="module" src="/main.js"></script>
</body>
</html>
```
* 3、main.js 引入 vk-uview-ui
```js
// 引入 uView UI
import uView from './uni_modules/vk-uview-ui';
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
// 使用 uView UI
app.use(uView)
return { app }
}
```
* 4、App.vue 引入基础样式(注意style标签需声明scss属性支持)
```html
<style lang="scss">
@import "./uni_modules/vk-uview-ui/index.scss";
</style>
```
* 5、uni.scss 引入全局 scss 变量文件
```css
@import "@/uni_modules/vk-uview-ui/theme.scss";
```
### 集成 `uview-ui`(nvue2.0版)
___若不想集成 `uview-ui` 可跳过此处___
适合开发:App(nvue版本),如果你只开发App,推荐用这个UI
> 插件市场导入 `uview-ui` 框架:[点击前往](https://ext.dcloud.net.cn/plugin?id=1593)
* 1、main.js 引入 uview-ui
```js
import uView from './uni_modules/uview-ui';
Vue.use(uView);
```
* 2、App.vue 引入基础样式(注意style标签需声明scss属性支持)
```html
<style lang="scss">
@import "./uni_modules/uview-ui/index.scss";
</style>
```
* 3、uni.scss 引入全局 scss 变量文件
```css
@import "@/uni_modules/uview-ui/theme.scss";
```
### 集成 `uview-ui`(nvue3.0版)
别想了,uniapp官方也还没支持。
### 组件库并不限制只能从以上选择,理论上支持任何UI组件库进行开发。
### 卸载 `uView1` 的步骤
* 1、main.js 删除 uView1
```js
import uView from 'uview-ui'
Vue.use(uView);
```
* 2、App.vue 删除基础样式
```html
<style lang="scss">
@import "uview-ui/index.scss";
</style>
```
* 3、uni.scss 删除全局 scss 变量文件
```css
@import "uview-ui/theme.scss";
```
* 4、pages.json 删除 easycom 规则
```js
"easycom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue",
},
```
* 5、package.json 删除 uview-ui 依赖
```js
"dependencies": {
"uview-ui": "^1.8.3"
},
```
* 6、package-lock.json 删除 uview-ui 依赖
```js
"dependencies": {
"uview-ui": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/uview-ui/-/uview-ui-1.8.3.tgz",
"integrity": "sha512-DqKc+qRrOZLPcyfWv4b0HspSS9n1Cd6BbgKiYEv9rjTAnWoqJV7rXsvWqZdr5iKGP5EMNbNS741GLNw4sIHbpw=="
}
}
```
### 完整安装文档:[查看完整安装文档](https://vkdoc.fsq.pub/client/quickstart.html)
## 云函数框架目录结构
```
.
├── common─────────────────# 自定义官方公共模块包
│ └── config──────────────────# 全局配置公共模块
│ └── uni-id──────────────────# uni-id官方公共模块
│ └── vk-unicloud─────────────# vk-unicloud公共模块
├── router─────────────────# 正式环境云函数主入口(函数路由器)
│ └── dao──────────────────# dao层(数据库交互公共API)
│ └── middleware───────────# 中间层(过滤器、拦截器)
│ └── node_modules─────────# npm包
│ └── service──────────────# 逻辑层(用于写业务逻辑)
│ ── └── 逻辑层目录结构在下方单独展示
│ └── util─────────────────# 工具包
│ ── └── pubFunction.js───────# 公共函数包
│ ── └── smsUtil.js───────────# 全局过滤器
│ └── config.js────────────# 入口函数初始化配置
│ └── index.js─────────────# 入口函数
│ └── package.json─────────# 第三方依赖配置文件(若使用npm,自动生成)
└─└── package-lock.json────# 第三方依赖配置文件(若使用npm,自动生成)
.
├── router-test───────────────# 函数路由(开发测试环境)
│ └── ...─────────# ...
│ └── ...─────────# ...
└── └── ...─────────# ...
```
### 逻辑层目录结构
#### `router/service` 目录为逻辑层
#### 以下的目录并非强制性,只是建议,便于统一开发规范。
```
.
├── service──────────────────────# 逻辑层(用于写业务逻辑)
│ └── admin────────────────# 后台管理端逻辑(admin框架开发中。。。)
│ ── └── xxxxxxxxxxxxxxx──────#
│ ── └── xxxxxxxxxxxxxxx──────#
│ ── └── xxxxxxxxxxxxxxx──────#
│ ── └── xxxxxxxxxxxxxxx──────#
│ └── client───────────────# 客户端逻辑(H5、小程序、APP)
│ ── └── user─────────────────# 用户服务(自己系统的逻辑)
│ ──── └── kh───────────────────# kh函数为必须登录后才能访问的函数
│ ──── └── pub──────────────────# pub函数为所有人都可以访问,不限制
│ ──── └── util─────────────────# 用户服务专用的工具包
│ ── └── order────────────────# 订单服务(自己系统的逻辑)
│ ──── └── kh───────────────────# kh函数为必须登录后才能访问的函数
│ ──── └── pub──────────────────# pub函数为所有人都可以访问,不限制
│ ──── └── util─────────────────# 订单服务专用的工具包
│ ── └── xxxxxxxxxxxxxxx──────#
│ ── └── xxxxxxxxxxxxxxx──────#
│ └── common───────────────# 公共逻辑(公共接口)
│ ── └── xxxxxxxxxxxxxxxx─────#
│ ── └── xxxxxxxxxxxxxxxx─────#
│ ── └── xxxxxxxxxxxxxxxx─────#
│ └── user─────────────────# 统一用户中心服务(已集成uniID)(用户中心作为核心,且为了方便插件升级,故与admin和client平级)
│ ── └── kh───────────────────# kh函数为必须登录后才能访问的函数(客户端用户)
│ ── └── pub──────────────────# pub函数为所有人都可以访问,不限制
│ ── └── sys──────────────────# sys函数为后端管理人员才能访问的函数(商家后台工作人员)
│ ── └── util─────────────────# 统一用户中心服务专用的工具包
│ └── plugs───────────────# 插件逻辑(插件专用)(会陆续新增一些实用性插件给开发者使用,如微信小程序发送订阅消息等等)
│ ──└── plugs-A───────────────────# 插件A
│ ────└── admin───────────────────# 插件A admin端
│ ────└── client──────────────────# 插件A client端
│ ──└── plugs-B───────────────────# 插件B
│ ────└── admin───────────────────# 插件B admin端
│ ────└── client──────────────────# 插件B client端
│ └── template─────────────# 云函数模板(插件内的云函数写法模板)
│ ── └── db_api───────────────# 数据库接口调用模板
│ └── muban.js─────────────# 云函数模板(新建一个云函数应复制粘贴这个文件)
│ └── muban_easy.js────────# 云函数模板(简易版)
└─────────────────────────────────
```
## 云函数service模板文件示例
```js
module.exports = {
/**
* 此函数名称
* @url user/sys/test1 前端调用的url参数地址
* @description 此函数描述
* @params {Object} data 请求参数
* @params {String} uniIdToken 用户token
* @params {String} userInfo 当前登录用户信息(同理,是可信任的)(只有kh函数才带此参数)
* @params {Object} util 公共工具包
* @params {Object} filterResponse 过滤器返回的数据
* @params {Object} originalParam 原始请求参数(包含了原始event和context)
* data 请求参数 说明
* @params {String} uid 当前登录用户id,若用户已登录且token有效,则data中会带uid参数
* (此参数是后端过滤器通过token获取并添加到data中的,是可信任的)(只有kh函数才带此参数)
* res 返回参数说明
* @params {Number} code 错误码,0表示成功
* @params {String} msg 详细信息
*/
main: async (event) => {
let { data = {}, userInfo, util, filterResponse, originalParam } = event;
let { customUtil, uniID, config, pubFun, vk , db, _ } = util;
let { uid } = data;
let res = { code : 0, msg : '' };
// 业务逻辑开始-----------------------------------------------------------
// 可写与数据库的交互逻辑等等
// 业务逻辑结束-----------------------------------------------------------
return res;
}
}
```
#### 成功时返回
```js
// 注意:所有成功请求必须返回code:0 code为其他值,代表失败,如兑换失败,您的积分不足!
// 如成功时返回 res.code = 0 表示执行成功;
return {
code : 0,
msg : '兑换成功!'
}
```
#### 失败时返回
```js
return {
code : -1,
msg : '兑换失败,您的积分不足!'
}
```
## this.vk.callFunction函数的参数说明
```js
/**
* 云函数请求封装 - 统一入口
* @description 通过云函数路由,1个云函数实现多个云函数的效果。
* @params {String} url 请求路径,该路径实为router云函数的service目录下的路径
* @params {Object} data 请求参数
* @params {String} title 遮罩层提示语,为空或不传则代表不显示遮罩层。
* @params {Boolean} isRequest 是否使用云函数url化地址访问云函数,默认false
* @params {Boolean} needAlert 为true代表请求错误时,会有alert弹窗提示。默认为true
* @params {Function} success 请求成功时,执行的回调函数
* @params {Function} fail 请求失败时,执行的回调函数
* @params {Function} complete 无论请求成功与否,都会执行的回调函数
*/
```
## 前端调用云函数示例
```js
this.vk.callFunction({
url: 'user/kh/setAvatar',
title:'请求中...',
data:{
avatar: "https://xxxxxxx.jpg"
},
success(data) {
// 修改成功
}
});
```
## 云函数url化方式调用云函数示例
[点击查看『云函数url化』方式调用云函数示例](https://vkdoc.fsq.pub/client/pages/callFunctionForUrl.html)
## 前端非法token拦截器
[点击查看『前端非法token拦截器』](https://vkdoc.fsq.pub/client/pages/interceptor1.html)
## vk.baseDao数据库API
[点击查看『vk.baseDao』数据库API](https://vkdoc.fsq.pub/client/uniCloud/db/api.html)
## 设置全局请求参数
[点击查看『设置全局请求参数』](https://vkdoc.fsq.pub/client/pages/updateRequestGlobalParam.html)
## 列表渲染前后端一体模板
[点击查看『列表渲染』前后端一体模板](https://vkdoc.fsq.pub/client/pages/list.html)
## 商品SKU选择器组件
[点击查看『商品SKU选择器组件』](https://gitee.com/vk-uni/vk-uni-cloud-router/wikis/pages?sort_id=2912199&doc_id=975983)
## 如何切换 正式环境 和 开发环境
[点击查看如何『切换正式环境和开发环境』](https://vkdoc.fsq.pub/client/question/q1.html)
## 本插件更新步骤
[点击查看本插件『更新步骤』](https://vkdoc.fsq.pub/client/changeGuide.html)
## uniCloud云函数路由框架研究Q群:`22466457` 如有问题或建议可以在群内讨论。
### 如果你觉得框架对你有用,可以在下方进行评论,也可以进行赞赏。
+136
View File
@@ -0,0 +1,136 @@
// 引入自定义公共函数
import myPubFunction from '@/common/function/myPubFunction.js'
export default {
// 开发模式启用调式模式(请求时会打印日志)
debug: process.env.NODE_ENV !== 'production',
// 主云函数名称
functionName: "router",
// 登录页面路径
login: {
url: '/pages/auth/login/login'
},
// 首页页面路径
index: {
url: '/pages/index/index'
},
// 404 Not Found 错误页面路径
error: {
url: '/pages/error/404/404'
},
// 前端默认时区(中国为8)
targetTimezone:8,
// 日志风格
logger: {
colorArr: [
"#0095f8",
"#67C23A"
]
},
/**
* app主题颜色
* vk.getVuex('$app.color.main')
* vk.getVuex('$app.color.secondary')
*/
color: {
main: "#ff4444",
secondary: "#555555"
},
// 需要检查是否登录的页面列表
checkTokenPages: {
/**
* 如果 mode = 0 则代表自动检测
* 如果 mode = 1 则代表list内的页面需要登录,不在list内的页面不需要登录
* 如果 mode = 2 则代表list内的页面不需要登录,不在list内的页面需要登录
* 注意1: list内是通配符表达式,非正则表达式
* 注意2: 需要使用 vk.navigateTo 代替 uni.navigateTo 进行页面跳转才会生效
* 注意3: 想要让 tabbar 页面必须登录才能访问,则需要手动在页面的onLoad里加 vk.pubfn.checkLogin();
* 在无需登录的页面上执行kh或sys函数,也会自动判断是否登录,未登录会自动跳登录页面,登录成功后会自动返回本来要跳转的页面。
*/
mode: 2,
list: [
"/pages_template/*",
"/pages/auth/*",
"/pages/index/*",
"/pages/error/*"
]
},
// 需要检查是否可以分享的页面列表(仅小程序有效)
checkSharePages: {
/**
* 如果 mode = 0 则不做处理
* 如果 mode = 1 则代表list内的页面可以被分享,不在list内的页面不可以被分享
* 如果 mode = 2 则代表list内的页面不可以被分享,不在list内的页面可以被分享
* 注意: list内是通配符表达式,非正则表达式
*/
mode: 0,
// ['shareAppMessage', 'shareTimeline'],
menus: ['shareAppMessage'],
list: [
"/pages/index/*",
"/pages/goods/*",
"/pages_template/*",
]
},
// 静态文件的资源URL地址
staticUrl: {
// Logo
logo: '/static/logo.png',
},
// 自定义公共函数,myPubFunction内的函数可通过vk.myfn.xxx() 调用
myfn: myPubFunction,
// 第三方服务配置
service: {
// 密钥和签名信息 (由于签名的获取比较麻烦,建议初学者使用上传到unicloud的方案,上传到阿里云OSS是给有特殊需求的用户使用)
// 相关文档 : https://help.aliyun.com/document_detail/31925.html?spm=a2c4g.11186623.6.1757.b7987d9czoFCVu
aliyunOSS: {
// 密钥和签名信息
uploadData: {
OSSAccessKeyId: "",
policy: "",
signature: "",
},
// oss上传地址
action: "https://xxx.oss-cn-hangzhou.aliyuncs.com",
// 根目录名称
dirname: "test",
// oss外网访问地址,也可以是阿里云cdn地址
host: "https://xxx.xxx.com",
// 上传时,是否按用户id进行分组储存
groupUserId: true,
// 是否默认上传到阿里云OSS
isDefault: false
}
},
// 全局异常码,可以自定义提示结果
globalErrorCode: {
// 阿里云10秒非正常超时,其实请求还在执行(且一般已经成功了,但前端接受不到成功结果)
"cloudfunction-unusual-timeout": "请求超时,但请求还在执行,请重新进入页面。",
// 请求超时(真正的请求超时)
"cloudfunction-timeout": "请求超时,请重试!",
// 不在预期内的异常(如数据库异常、云函数编译异常等)
"cloudfunction-system-error": "网络开小差了!"
},
// 自定义拦截器
interceptor: {
// login:function(obj){
// let { vk, params, res } = obj;
// //console.log("params:",params);
// //console.log("res:",res);
// if(!params.noAlert){
// vk.alert(res.msg);
// }
// console.log("跳自己的登录页面");
// // 上方代码可自己修改,写成你自己的逻辑处理。
// },
// fail:function(obj){
// let { vk, params, res } = obj;
// //console.log("params:",params);
// //console.log("res:",res);
// return false;// 返回false则取消框架内置fail的逻辑,返回true则会继续执行框架内置fail的逻辑
// // 上方代码可自己修改,写成你自己的逻辑处理。
// }
}
}
+1548
View File
File diff suppressed because it is too large Load Diff
+8
View File
@@ -0,0 +1,8 @@
* 【修复】`短信发送` 接口当uni-id配置成多端隔离(数组形式)会报错的bug
* 【修复】`vk.importObject` 部分情况下会报错的问题
* 【优化】如果当前运行的微信小程序是体验版,但没有点HBX的【发行】菜单发布,则提示开发者请点【发行】按钮
* 【优化】`$hasRole`函数的功能 [传送门](https://vkdoc.fsq.pub/client/jsapi.html#hasrole)
* 【优化】`vk.pubfn.timeFormat` 支持显示时区,完整格式为 `yyyy-MM-ddThh:mm:ssZ`
* 【优化】其他细节
##### 框架学习Q群:`22466457` 欢迎萌新和大佬来使用和共同改进框架
+28
View File
@@ -0,0 +1,28 @@
/* 这里是你自己写的全局css样式 */
@import "@/common/css/common.css";
/* #ifdef H5 */
.uni-mask,
.uni-modal,
uni-toast,
uni-modal,
.uni-actionsheet {
z-index: 999999 !important;
}
/* #endif */
/* 改变主题色变量 */
$--color-primary: #A92924;
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
.el-input.is-disabled .el-input__inner {
color: #333333 !important;
}
.vk-data-form .bar-title{
display: block;
}
File diff suppressed because it is too large Load Diff
+73
View File
@@ -0,0 +1,73 @@
// 这里是uni-app内置的常用样式变量
// uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
// 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
// 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
// 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
// 颜色变量
// 行为相关颜色
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
// 文字基本颜色
$uni-text-color:#333; // 基本色
$uni-text-color-inverse:#fff; // 反色
$uni-text-color-grey:#999; // 辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
// 背景颜色
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1; //点 击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4); // 遮罩颜色
// 边框颜色
$uni-border-color:#e4e7ed;
// 尺寸变量
// 文字尺寸
$uni-font-size-sm:24rpx;
$uni-font-size-base:28rpx;
$uni-font-size-lg:32rpx;
// 图片尺寸
$uni-img-size-sm:40rpx;
$uni-img-size-base:52rpx;
$uni-img-size-lg:80rpx;
// Border Radius
$uni-border-radius-sm: 4rpx;
$uni-border-radius-base: 6rpx;
$uni-border-radius-lg: 12rpx;
$uni-border-radius-circle: 50%;
// 水平间距
$uni-spacing-row-sm: 10px;
$uni-spacing-row-base: 20rpx;
$uni-spacing-row-lg: 30rpx;
// 垂直间距
$uni-spacing-col-sm: 8rpx;
$uni-spacing-col-base: 16rpx;
$uni-spacing-col-lg: 24rpx;
// 透明度
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
// 文章场景相关
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:40rpx;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:36rpx;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:30rpx;
+15
View File
@@ -0,0 +1,15 @@
/**
* 自定义公共函数
*/
var myfn = {};
/**
* 测试函数test1
* vk.myfn.test1();
*/
myfn.test1 = function(obj = {}) {
let vk = uni.vk;
console.log("执行了自定义公共函数test1");
return obj;
};
export default myfn;
+320
View File
@@ -0,0 +1,320 @@
<template>
<view>
<div class="group-nav">
<div class="mod-nav clearfix">
<div class="first-level-nav ">
<div class="clearfix navigation-bottom">
<div class="classification" id="bannerAllPro">
<div class="classification-text">
<i class="icon-nav icon-nav-menu"></i> 全部商品分类
</div>
<!--全部商品分类开始-->
<div class="banner-left zghome-nav-disnone" style="display: none;">
<div class="mod-category">
<div class="part-category">
<div class="cate-menu" psa="a156">
<ul id="nav-sub" class="">
<li class="clearfix menuliselected">
<i class="cate-menu-icon cate-icon-1"></i>
<h2>
<a href="/market/index.html?name2=螺纹钢、高线">螺纹钢、高线</a>
</h2>
<div class="cate-item clearfix">
<a href="/market/index.html?name2=螺纹钢">螺纹钢</a>
<a href="/market/index.html?name2=盘螺">盘螺</a>
<a href="/market/index.html?name2=盘圆">盘圆</a>
</div>
</li>
</ul>
</div>
<div class="cate-cont" psa="a157" style="display: none;">
<div class="item-main" style="display: none;">
<div class="part-hot-word">
<div class="item">
<div class="title">
<h2>
<a href="/market/index.html?name2=螺纹钢、高线">螺纹钢</a>
</h2>
<a href="/market/index.html" class="more">更多
<i>&gt;</i></a>
</div>
<div class="cont">
</div>
</div>
</div>
<div class="part-logo-cont">
</div>
</div>
</div>
</div>
</div>
</div>
<!--全部商品分类结束-->
</div>
<div class="linkNav">
<ul>
<li class="nav ">
<a href="/">首页</a>
</li>
<li class="nav ">
<a href="/support/index.html">金久信自营</a>
</li>
<li class="nav ">
<a href="javascript:;" @click="navTo('/pages/spot/goods/goods')" class="navigator">
现货市场
</a>
</li>
<li class="nav ">
<a href="javascript:;" @click="navTo('/pages/enquiry/list')" class="navigator">
下询价单
</a>
</li>
<li class="nav ">
<a href="/process/index.html">找加工</a>
</li>
<li class="nav ">
<a href="/hezuo/index.html">找合作</a>
</li>
<li class="nav ">
<a href="/junk/index.html">旧货交易</a>
</li>
<li class="nav ">
<a href="/yellowpage/index.html">金久信黄页</a>
</li>
<li class="nav ">
<a href="/school/index.html">金久信学堂</a>
</li>
<li class="nav ">
<a href="/shop/index.html">特产商城</a>
</li>
</ul>
</div>
<div class="classification">
<div class="entry">
<div class="entry-link">
<img src="@/static/images/logo-left2.png">
</div>
</div>
<!--全部商品分类开始-->
<div class="zghome-nav-display">
<div class="mod-manage" style="height: 500px;display: none">
<div class="me-login">
<div class="login-not">
<div class="login-head">
<img src="/public/index/images/logo-small.png" alt="">
</div>
<div class="login-action">
<a href="/user/login.html" class="login"
id="banner_right_login">会员登录</a>
</div>
<div class="runlings"><span
style="display: inline-block;color: #a92924">免费</span>入驻通道
</div>
</div>
</div>
<div class="me-tab">
<div class="me-tab-text">
<ul>
<li class="tab-left active">
<a href="/buyer/index.html">买家入口 </a>
</li>
<li class="">
<a href="/seller/index.html">卖家入口</a>
</li>
</ul>
</div>
<div class="me-tab-content">
<div class="tab-inner">
<div class="me-step clearfix">
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg1.png"></i>
<i class="iconNew iconNew-step-arrow"><img
src="/public/index/images/lg13.png"></i>
</dt>
<dd>免费注册</dd>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg2.png"></i>
<i class="iconNew iconNew-step-arrow"><img
src="/public/index/images/lg13.png"></i>
</dt>
<dd>发布需求</dd>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg3.png"></i>
</dt>
<dd>管理采购</dd>
</dl>
<dl class="dowslf3">
<dt class="clearfix">
<i class="iconNew iconNew-step-arrow2"><img
src="/public/index/images/lg14.png"></i>
</dt>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg6.png"></i>
<i class="iconNew iconNew-step-arrow"><img
src="/public/index/images/lg15.png"></i>
</dt>
<dd>达成交易</dd>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg5.png"></i>
<i class="iconNew iconNew-step-arrow"><img
src="/public/index/images/lg15.png"></i>
</dt>
<dd>验收</dd>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg4.png"></i>
</dt>
<dd> 我的订单</dd>
</dl>
</div>
<p style="width: 100%;margin:10px 0px;">
<a href="/buyer/index.html"
style="text-align: center;color: #a92924;font-size: 13px;line-height: 2">进入买家中心
&gt;</a>
</p>
</div>
<div class="tab-inner" style="display: none;">
<div class="me-step clearfix">
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg7.png"></i>
<i class="iconNew iconNew-step-arrow"><img
src="/public/index/images/lg13.png"></i>
</dt>
<dd>企业注册</dd>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg8.png"></i>
<i class="iconNew iconNew-step-arrow"><img
src="/public/index/images/lg13.png"></i>
</dt>
<dd>商品管理</dd>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg9.png"></i>
</dt>
<dd>匹配需求</dd>
</dl>
<dl class="dowslf3">
<dt class="clearfix">
<i class="iconNew iconNew-step-arrow2"><img
src="/public/index/images/lg14.png"></i>
</dt>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg12.png"></i>
<i class="iconNew iconNew-step-arrow"><img
src="/public/index/images/lg15.png"></i>
</dt>
<dd>完成订单</dd>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg11.png"></i>
<i class="iconNew iconNew-step-arrow"><img
src="/public/index/images/lg15.png"></i>
</dt>
<dd>卖出货品</dd>
</dl>
<dl>
<dt>
<i class="iconNew"><img
src="/public/index/images/lg10.png"></i>
</dt>
<dd> 报价</dd>
</dl>
</div>
<p style="width: 100%;margin:10px 0px;">
<a href="/seller/index.html"
style="text-align: center;color: #a92924;font-size: 13px;line-height: 2">进入卖家中心
&gt;</a>
</p>
</div>
</div>
</div>
<div class="clearfix wartchar">
<div class="wartcharlist"><img src="/public/index/images/wx.png"
style="height: 38px;margin-top: 5px;">
<p style="padding-top: 5px;line-height: 2">金久信</p>
<p>微信公众号</p>
</div>
<div class="wartcharlist">
<img src="/public/upload/image/20210220/80705c8b12d05d0ff67a2758749ef09c.jpg"
style="height: 100px;width: 100px;">
</div>
</div>
</div>
</div>
</div>
<!---->
</div>
</div>
</div>
</div>
</view>
</template>
<script>
export default {
name: "category-bar",
data() {
return {
};
},
methods: {
navTo(url) {
vk.navigateTo(url);
}
}
}
</script>
<style lang="scss">
.navigator {
cursor: pointer;
}
</style>
@@ -0,0 +1,20 @@
<template>
<view>
</view>
</template>
<script>
export default {
name:"common-footer",
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>
+117
View File
@@ -0,0 +1,117 @@
<template>
<view>
<div class="group-head clearfix">
<div class="group-inner clearfix">
<div class="mod-logo">
<a href="/" class="logo"><img src="@/static/images/logo.png"></a>
</div>
<div class="mod-mini-search">
<div class="navigation-top clearfix">
<div class="searchBar">
<ul class="searchBar-tab clearfix">
<li @click="searchTypeChange(0)" :class="{'active': searchType == 0}" class="_goods" >商品</li>
<li @click="searchTypeChange(1)" :class="{'active': searchType == 1}" class="_shop">商户</li>
</ul>
<div class="clearfix">
<div class="searchBar-input">
<div class="searchBar-input-inner">
<input type="text" :placeholder="searchList[searchType].placeholder"
maxlength="100" autocomplete="off">
</div>
<div class="searchBar-input-list" style="display: none;"></div>
</div>
<div class="preventButton button" desc=""></div>
<div class="button" @click="search">搜索</div>
</div>
</div>
<div class="mod-hot-query">
<ul class="clearfix">
<li>
<a href="/market/index.html?product_name=直缝焊管">直缝焊管</a>
</li>
<li>
<a href="/market/index.html?product_name=架子管">架子管</a>
</li>
<li>
<a href="/market/index.html?product_name=无缝管">无缝管</a>
</li>
<li>
<a href="/market/index.html?product_name=方矩管">方矩管</a>
</li>
<li>
<a href="/market/index.html?product_name=钢板">钢板</a>
</li>
<li>
<a href="/market/index.html?product_name=螺纹钢">螺纹钢</a>
</li>
<li>
<a href="/market/index.html?product_name=H型钢">H型钢</a>
</li>
<li>
<a href="/market/index.html?product_name=工字钢">工字钢</a>
</li>
<li>
<a href="/market/index.html?product_name=槽钢">槽钢</a>
</li>
<li>
<a href="/market/index.html?product_name=镀锌钢管">镀锌钢管</a>
</li>
</ul>
</div>
</div>
</div>
<div class="mod-menu">
<div class="hrd">
<a href="/support/index.html" class="hrd-landing">
<img src="@/static/images/logo-left.png">
</a>
</div>
</div>
<div class="mod-download-icon js-download">
<a class="download clearfix" href="" target="_blank">
<span style="float: left;font-size: 13px;padding-top: 27px;padding-right: 10px;">金久信<br>
手机站</span>
<img src="/public/upload/image/20210220/80705c8b12d05d0ff67a2758749ef09c.jpg"
style="height: 90px;width: 90px;float: left;">
</a>
</div>
</div>
</div>
</view>
</template>
<script>
export default {
name: "common-header",
data() {
return {
searchType: 0,
searchList: [
{
type: 0,
name: '商品',
placeholder:'请输入品名 材质 规格 钢厂等搜索'
},
{
type: 1,
name: '商户',
placeholder:'请输入商户名或公司名进行搜索'
}
]
};
},
methods: {
searchTypeChange(e) {
this.searchType = e
},
search() {
this.$message('这是一条消息提示');
}
}
}
</script>
<style lang="scss">
</style>
@@ -0,0 +1,68 @@
<template>
<!-- 万能表单 -->
<view v-if="scene === 'form'">
<el-divider content-position="left">{{column.title}}</el-divider>
<!-- <el-input :value="value" @input="_input"></el-input> -->
</view>
<!-- 万能表格 -->
<view v-else-if="scene === 'table'">
<text>{{ value }}</text>
</view>
<!-- 万能表格详情 -->
<view v-else-if="scene === 'detail'">
<text>{{ value }}</text>
</view>
</template>
<script>
export default {
props: {
// 双向绑定的值
value: {
type: String,
default: ""
},
// 字段规则
column: {
type: Object,
default: function() {
return {};
}
},
// 当前场景 form 万能表单 table 万能表格 detail 表格详情页
scene: {
type: String,
default: "form"
}
},
data() {
return {
};
},
// 组件加载完成时触发
mounted() {
},
// 组件函数
methods: {
_input(value){
// 固定顺序,先input,再change
// this.$emit("input", value);
// this.$emit("change", value);
}
},
// 监听器
watch: {
},
// 计算属性
computed: {
},
};
</script>
<style lang="scss" scoped>
</style>
+20
View File
@@ -0,0 +1,20 @@
<template>
<view>
</view>
</template>
<script>
export default {
name:"page-nav",
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>
+180
View File
@@ -0,0 +1,180 @@
<template>
<view>
<div class="layout layout-fix-tab-narrow" style="right: 0px;">
<div class="mod-fix-tab-narrow" style="display: block; ">
<div class="fix-tab-main">
<ul>
<li class="side-hrd">
<a rel="nofollow" href="/enquiry/add.html" class="DeliveryMyCard">
<div class="item">
<i class="wag-icon"><img src="@/static/images/cl1.png"></i>
</div>
<span>下询价单</span>
</a>
</li>
<!-- <li class="side-ruzhu">-->
<!-- <a rel="nofollow" href="" target="_blank">-->
<!-- <div class="item">-->
<!-- <i class="wag-icon"><img src="@/static/images/cl2.png"></i>-->
<!-- </div>-->
<!-- <span>我要入驻</span>-->
<!-- </a>-->
<!-- </li>-->
<li class="side-add-cart"><a rel="nofollow" href="/support/shopping.html" target="_blank">
<div class="item">
<i class="wag-icon"><img src="@/static/images/cl3.png"></i>
</div>
<span class="txt"> 进货单 </span>
</a>
</li>
<li class="side-steel-kefu">
<a rel="nofollow"
href="http://wpa.qq.com/msgrd?v=3&amp;uin=949419497&amp;site=qq&amp;menu=yes"
target="_blank">
<div class="item">
<i class="wag-icon"><img src="@/static/images/cl4.png"></i>
</div>
<span>在线客服</span>
</a>
</li>
<li class="side-steel-counter">
<a rel="nofollow" href="/counter/index.html">
<div class="item">
<i class="wag-icon"><img src="@/static/images/cl5.png"></i>
</div>
<span>钢材计算器</span>
</a>
</li>
<li class="side-steel-search">
<a rel="nofollow" href="/yellowpage/index.html" target="_blank">
<div class="item">
<i class="wag-icon"><img src="@/static/images/cl6.png"></i>
</div>
<span>金久信黄页</span>
</a>
</li>
<li class="actGotop" style="display: none;">
<div class="item">
<i class="wag-icon"><img src="@/static/images/cc-top.png"></i>
</div>
<span>返回顶部</span>
</li>
</ul>
</div>
</div>
</div>
</view>
</template>
<script>
export default {
name: "right-bar",
data() {
return {
};
}
}
</script>
<style lang="scss">
.layout-fix-tab-narrow {
border-left: 1px solid #f1f1f1;
position: fixed;
right: -40px;
top: 0;
width: 40px;
height: 100%;
background: #fff;
z-index: 9999999;
-webkit-transition: right .5s ease;
-moz-transition: right .5s ease;
-ms-transition: right .5s ease;
-o-transition: right .5s ease;
transition: right .5s ease;
line-height: 1.5;
color: #656565;
font-size: 12px;
font-family: -apple-system, BlinkMacSystemFont, Hiragino Sans GB, Microsoft YaHei, sans-serif;
}
.mod-fix-tab-narrow li {
width: 40px;
position: relative;
margin: 3px 0;
}
.mod-fix-tab-narrow li {
padding: 4px 0;
cursor: pointer;
line-height: 16px;
}
.layout-fix-tab-narrow a {
color: #656565;
text-decoration: none;
padding: 5px 0px;
}
.mod-fix-tab-narrow li .item {
display: block;
position: relative;
z-index: 99;
text-align: center;
height: 23px;
}
.mod-fix-tab-narrow li span {
display: block;
right: 0;
width: 16px;
white-space: inherit;
text-align: center;
word-wrap: break-word;
word-break: break-all;
padding: 0 12px;
line-height: 14px;
z-index: 10;
top: 32px;
transition: inherit;
}
.wag-icon {
font-size: 16px;
height: 30px;
width: 30px;
font-style: normal;
color: #353535;
}
.mod-fix-tab-narrow li:hover {
box-shadow: 0 0;
color: #a92924
}
.mod-fix-tab-narrow li:hover {
box-shadow: 0 0 16px 0 hsla(0, 0%, 77%, .5)
}
.mod-fix-tab-narrow li:hover span {
box-shadow: 0 0;
color: #a92924
}
.mod-fix-tab-narrow {
margin-top: 50px;
}
.a-fadeinL {
margin-top: 50px;
-webkit-transition: right .5s ease;
-moz-transition: right .5s ease;
-ms-transition: right .5s ease;
-o-transition: right .5s ease;
transition: right .5s ease;
}
</style>
+138
View File
@@ -0,0 +1,138 @@
<template>
<view>
<view class="group-wagbar">
<div class="group-inner">
<div class="mod-welcome">
<h5 class="welcome-item slogan js-slogan">欢迎来到金久信钢城首页!</h5>
<div class="welcome-item login-register">
<navigator v-if="!vk.getVuex('$user.userInfo.nickname')" class="login js-top-bar-login"
url="/pages/auth/login/login" rel="nofollow" target="_self" style="display: inline-block;">
请登录</navigator>
<navigator v-if="!vk.getVuex('$user.userInfo.nickname')" class="register "
url="/pages/auth/register/register" rel="nofollow" target="_blank"
style="display: inline-block;">免费注册</navigator>
<el-dropdown @command="handleCommand" size="mini" v-if="vk.getVuex('$user.userInfo.nickname')">
<span class="register">
{{vk.getVuex('$user.userInfo.nickname')}}<i
class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<navigator url="/pages/user/user">个人中心</navigator>
</el-dropdown-item>
<el-dropdown-item>买家中心</el-dropdown-item>
<el-dropdown-item>卖家中心</el-dropdown-item>
<el-dropdown-item>我的加工</el-dropdown-item>
<el-dropdown-item>金久信学堂</el-dropdown-item>
<el-dropdown-item>合同管理</el-dropdown-item>
<el-dropdown-item>订单管理</el-dropdown-item>
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
<div class="mod-tools">
<ul>
<li class="tool-item buyer-item">
<a rel="nofollow" href="/buyer/index.html" class="bar-title">买家中心<i></i></a>
<div class="bar-content">
<dl>
<dd>
<a rel="nofollow" href="/buyer/index.html">询价管理</a>
</dd>
<dd>
<a rel="nofollow" href="/buyer/deal.html">订单管理</a>
</dd>
<dd>
<a rel="nofollow" href="/buyer/contract.html">合同管理</a>
</dd>
</dl>
</div>
</li>
<li class="tool-item service-item">
<a rel="nofollow" href="" class="bar-title" target="_blank">客户服务<i></i></a>
<div class="bar-content">
<dl>
<dd>
<a rel="nofollow" href="/article/lists/id/12.html">常见问题</a>
</dd>
<dd>
<a rel="nofollow" href="/article/lists/id/12.html">买家指南</a>
</dd>
<dd>
<a rel="nofollow" href="/article/lists/id/14.html">卖家指南</a>
</dd>
<!-- <dd>-->
<!-- <a rel="nofollow" target="_self" id="wagbar-im"-->
<!-- class="im data-tracelog">在线咨询</a>-->
<!-- </dd>-->
</dl>
</div>
</li>
<li class="tool-item">
<a rel="nofollow" href="/member/message.html" class="bar-title" target="_blank">我的消息</a>
</li>
<li class="tool-item2">
<a rel="nofollow" href="" class="bar-title" target="_blank"><span>客服服务热线:+86
0771-3923001</span></a>
</li>
</ul>
</div>
</div>
</view>
</view>
</template>
<script>
export default {
name: "top-bar",
data() {
return {};
},
created() {
},
methods: {
handleCommand(e) {
if (e == 'logout') {
this.logout()
}
},
logout() {
this.$confirm('确认退出登录?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then( () => {
vk.userCenter.logout({
success: (data) => {
// 退出登录成功后的逻辑
uni.reLaunch({
url: '/'
})
}
});
})
}
}
}
</script>
<style lang="scss">
.register {
cursor: pointer;
&:hover {
color: #a92924;
}
}
</style>
File diff suppressed because one or more lines are too long
+22
View File
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
<!-- 配置H5的 web图标static/logo.png -->
<link rel="icon" href="./static/logo.png"/>
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
+60
View File
@@ -0,0 +1,60 @@
import Vue from 'vue'
import App from './App'
import store from './store'
import config from '@/app.config.js'
// 引入 elementUI
import elementUI from "element-ui";
// import 'element-ui/lib/theme-chalk/index.css';
Vue.use(elementUI);
// 引入 高性能表格UI 组件
import UmyUi from 'umy-ui'
import 'umy-ui/lib/theme-chalk/index.css';
Vue.use(UmyUi);
// 引入 vk 实例
import vk from 'uni_modules/vk-unicloud';
Vue.use(vk);
// 初始化 vk框架
Vue.prototype.vk.init({
Vue, // Vue实例
config, // 配置
});
// 引入 vkAdminUI 组件
import vkAdminUI from 'vk-unicloud-admin-ui';
import 'vk-unicloud-admin-ui/theme/index.css';
Vue.use(vkAdminUI);
// 自动注册全局组件(必须加在Vue.use(vkAdminUI);的后面)
const modulesFiles = require.context('./components', true, /\.vue$/);
modulesFiles.keys().map((modulePath, index) => {
const moduleNames = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
const moduleSplit = moduleNames.split("/");
const moduleName = moduleSplit[0];
if (moduleSplit.length === 2 && moduleName === moduleSplit[1]) {
const value = modulesFiles(modulePath);
let moduleItem = value.default;
Vue.component(moduleName, moduleItem);
}
});
// 引入 自定义全局css 样式
import '@/common/css/app.scss';
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
store,
...App
})
app.$mount()
+105
View File
@@ -0,0 +1,105 @@
{
"name" : "jinjiuxin-mobile",
"appid" : "__UNI__8BFD66E",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"nvueCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {},
"distribute" : {
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
"sdkConfigs" : {}
}
},
"quickapp" : {},
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false,
"es6" : false,
"postcss" : true,
"minified" : true,
"checkSiteMap" : false
},
"usingComponents" : true,
"lazyCodeLoading" : "requiredComponents",
"permission" : {
"scope.userLocation" : {
"desc" : "方便自动填写地址"
}
}
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true,
"setting" : {
"urlCheck" : false
}
},
"mp-toutiao" : {
"usingComponents" : true,
"setting" : {
"urlCheck" : false,
"minified" : true,
"postcss" : true,
"es6" : false
}
},
"uniStatistics" : {
"enable" : false
},
"h5" : {
"title" : "",
"template" : "template.h5.html",
"devServer" : {
"disableHostCheck" : true
}
},
"vueVersion" : "2",
"mp-qq" : {
"setting" : {
"urlCheck" : false,
"minified" : true,
"postcss" : true,
"es6" : false
}
}
}
+464
View File
@@ -0,0 +1,464 @@
{
"name": "vk-unicloud-router",
"version": "2.15.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "vk-unicloud-router",
"version": "2.15.3",
"license": "MIT",
"dependencies": {
"element-ui": "2.15.13",
"lodash": "^4.17.21",
"umy-ui": "1.1.6",
"vk-unicloud-admin-ui": "^1.17.45"
},
"engines": {
"HBuilderX": "^3.1.2"
}
},
"node_modules/@babel/parser": {
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"peer": true,
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "2.7.15",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.15.tgz",
"integrity": "sha512-FCvIEevPmgCgqFBH7wD+3B97y7u7oj/Wr69zADBf403Tui377bThTjBvekaZvlRr4IwUAu3M6hYZeULZFJbdYg==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.18.4",
"postcss": "^8.4.14",
"source-map": "^0.6.1"
}
},
"node_modules/async-validator": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.8.5.tgz",
"integrity": "sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==",
"dependencies": {
"babel-runtime": "6.x"
}
},
"node_modules/babel-helper-vue-jsx-merge-props": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
"integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
},
"node_modules/babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
"integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
"dependencies": {
"core-js": "^2.4.0",
"regenerator-runtime": "^0.11.0"
}
},
"node_modules/core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
"hasInstallScript": true
},
"node_modules/csstype": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
"peer": true
},
"node_modules/deepmerge": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
"integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/element-ui": {
"version": "2.15.13",
"resolved": "https://registry.npmjs.org/element-ui/-/element-ui-2.15.13.tgz",
"integrity": "sha512-LJoatEYX6WV74FqXBss8Xfho9fh9rjDSzrDrTyREdGb1h1R3uRvmLh5jqp2JU137aj4/BgqA3K06RQpQBX33Bg==",
"dependencies": {
"async-validator": "~1.8.1",
"babel-helper-vue-jsx-merge-props": "^2.0.0",
"deepmerge": "^1.2.0",
"normalize-wheel": "^1.0.1",
"resize-observer-polyfill": "^1.5.0",
"throttle-debounce": "^1.0.1"
},
"peerDependencies": {
"vue": "^2.5.17"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/normalize-wheel": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
"integrity": "sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA=="
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"peer": true
},
"node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"peer": true,
"dependencies": {
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/regenerator-runtime": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
},
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"node_modules/sortablejs": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
"integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/throttle-debounce": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
"integrity": "sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg==",
"engines": {
"node": ">=4"
}
},
"node_modules/umy-table": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/umy-table/-/umy-table-1.1.8.tgz",
"integrity": "sha512-yqPMFwZ6MUNqI73KamsNKBTbHRA7VuVZDEWobaySghtf4n/s7INuTNQoADB/ROVK57WOXr99Xpnol0aMqGlASA==",
"dependencies": {
"async-validator": "~1.8.1",
"deepmerge": "^1.2.0",
"normalize-wheel": "^1.0.1",
"resize-observer-polyfill": "^1.5.0",
"throttle-debounce": "^1.0.1",
"vuedraggable": "^2.23.2",
"xe-utils": "^3.0.0-beta.12"
},
"peerDependencies": {
"vue": ">= 2.6.0 < 3",
"xe-utils": ">= 3"
}
},
"node_modules/umy-ui": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/umy-ui/-/umy-ui-1.1.6.tgz",
"integrity": "sha512-wX0S29B5sFn8q0MvU9PEl8DGZeQmZXOJlLrwaCJ2UHiIQZCANWgXMBjjQgpaequ1gRZ8BekEu7Sn7hJccm9YMQ==",
"dependencies": {
"async-validator": "~1.8.1",
"deepmerge": "^1.2.0",
"normalize-wheel": "^1.0.1",
"resize-observer-polyfill": "^1.5.0",
"throttle-debounce": "^1.0.1",
"umy-table": "1.1.8",
"vuedraggable": "^2.23.2",
"xe-utils": "^3.0.0-beta.12"
},
"peerDependencies": {
"vue": ">= 2.6.0 < 3",
"xe-utils": ">= 3"
}
},
"node_modules/vk-unicloud-admin-ui": {
"version": "1.17.46",
"resolved": "https://registry.npmjs.org/vk-unicloud-admin-ui/-/vk-unicloud-admin-ui-1.17.46.tgz",
"integrity": "sha512-VJvi8Gm3mfZOFEilIrZ1bSoi192ov9hPzSFzkR6l62pqJ3UEwgjTr5L2gQqxw4twb+y5qDmWZPS4dQMwya+iiQ=="
},
"node_modules/vue": {
"version": "2.7.15",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.7.15.tgz",
"integrity": "sha512-a29fsXd2G0KMRqIFTpRgpSbWaNBK3lpCTOLuGLEDnlHWdjB8fwl6zyYZ8xCrqkJdatwZb4mGHiEfJjnw0Q6AwQ==",
"peer": true,
"dependencies": {
"@vue/compiler-sfc": "2.7.15",
"csstype": "^3.1.0"
}
},
"node_modules/vuedraggable": {
"version": "2.24.3",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
"integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
"dependencies": {
"sortablejs": "1.10.2"
}
},
"node_modules/xe-utils": {
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/xe-utils/-/xe-utils-3.5.13.tgz",
"integrity": "sha512-ORT6ghCRk0mUVavMBxetcPzUPskS6NGfntzpWazJ86e+XU0uK4HwHfDhN/jKATiyInrOH5RwQo9SO/+DB8XeBw=="
}
},
"dependencies": {
"@babel/parser": {
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"peer": true
},
"@vue/compiler-sfc": {
"version": "2.7.15",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.15.tgz",
"integrity": "sha512-FCvIEevPmgCgqFBH7wD+3B97y7u7oj/Wr69zADBf403Tui377bThTjBvekaZvlRr4IwUAu3M6hYZeULZFJbdYg==",
"peer": true,
"requires": {
"@babel/parser": "^7.18.4",
"postcss": "^8.4.14",
"source-map": "^0.6.1"
}
},
"async-validator": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.8.5.tgz",
"integrity": "sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==",
"requires": {
"babel-runtime": "6.x"
}
},
"babel-helper-vue-jsx-merge-props": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
"integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
},
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
"integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
"requires": {
"core-js": "^2.4.0",
"regenerator-runtime": "^0.11.0"
}
},
"core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
},
"csstype": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
"peer": true
},
"deepmerge": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
"integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ=="
},
"element-ui": {
"version": "2.15.13",
"resolved": "https://registry.npmjs.org/element-ui/-/element-ui-2.15.13.tgz",
"integrity": "sha512-LJoatEYX6WV74FqXBss8Xfho9fh9rjDSzrDrTyREdGb1h1R3uRvmLh5jqp2JU137aj4/BgqA3K06RQpQBX33Bg==",
"requires": {
"async-validator": "~1.8.1",
"babel-helper-vue-jsx-merge-props": "^2.0.0",
"deepmerge": "^1.2.0",
"normalize-wheel": "^1.0.1",
"resize-observer-polyfill": "^1.5.0",
"throttle-debounce": "^1.0.1"
}
},
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"peer": true
},
"normalize-wheel": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
"integrity": "sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA=="
},
"picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"peer": true
},
"postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"peer": true,
"requires": {
"nanoid": "^3.3.6",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
}
},
"regenerator-runtime": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
},
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"sortablejs": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
"integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"peer": true
},
"source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"peer": true
},
"throttle-debounce": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
"integrity": "sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg=="
},
"umy-table": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/umy-table/-/umy-table-1.1.8.tgz",
"integrity": "sha512-yqPMFwZ6MUNqI73KamsNKBTbHRA7VuVZDEWobaySghtf4n/s7INuTNQoADB/ROVK57WOXr99Xpnol0aMqGlASA==",
"requires": {
"async-validator": "~1.8.1",
"deepmerge": "^1.2.0",
"normalize-wheel": "^1.0.1",
"resize-observer-polyfill": "^1.5.0",
"throttle-debounce": "^1.0.1",
"vuedraggable": "^2.23.2",
"xe-utils": "^3.0.0-beta.12"
}
},
"umy-ui": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/umy-ui/-/umy-ui-1.1.6.tgz",
"integrity": "sha512-wX0S29B5sFn8q0MvU9PEl8DGZeQmZXOJlLrwaCJ2UHiIQZCANWgXMBjjQgpaequ1gRZ8BekEu7Sn7hJccm9YMQ==",
"requires": {
"async-validator": "~1.8.1",
"deepmerge": "^1.2.0",
"normalize-wheel": "^1.0.1",
"resize-observer-polyfill": "^1.5.0",
"throttle-debounce": "^1.0.1",
"umy-table": "1.1.8",
"vuedraggable": "^2.23.2",
"xe-utils": "^3.0.0-beta.12"
}
},
"vk-unicloud-admin-ui": {
"version": "1.17.46",
"resolved": "https://registry.npmjs.org/vk-unicloud-admin-ui/-/vk-unicloud-admin-ui-1.17.46.tgz",
"integrity": "sha512-VJvi8Gm3mfZOFEilIrZ1bSoi192ov9hPzSFzkR6l62pqJ3UEwgjTr5L2gQqxw4twb+y5qDmWZPS4dQMwya+iiQ=="
},
"vue": {
"version": "2.7.15",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.7.15.tgz",
"integrity": "sha512-a29fsXd2G0KMRqIFTpRgpSbWaNBK3lpCTOLuGLEDnlHWdjB8fwl6zyYZ8xCrqkJdatwZb4mGHiEfJjnw0Q6AwQ==",
"peer": true,
"requires": {
"@vue/compiler-sfc": "2.7.15",
"csstype": "^3.1.0"
}
},
"vuedraggable": {
"version": "2.24.3",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
"integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
"requires": {
"sortablejs": "1.10.2"
}
},
"xe-utils": {
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/xe-utils/-/xe-utils-3.5.13.tgz",
"integrity": "sha512-ORT6ghCRk0mUVavMBxetcPzUPskS6NGfntzpWazJ86e+XU0uK4HwHfDhN/jKATiyInrOH5RwQo9SO/+DB8XeBw=="
}
}
}
+96
View File
@@ -0,0 +1,96 @@
{
"id": "vk-cloud-router",
"displayName": "【开箱即用】vk-unicloud-router - 云函数路由模式开发框架 - 已集成uni-id 框架内置了众多API、工具包,为你的业务扫平障碍。",
"version": "2.15.3",
"description": "这是一个unicloud快速开发框架+项目模板(已包含核心库)支持URL化,众多现成API供你使用(登录、注册、短信、微信百度服务端API等等)为你的业务扫平障碍。内置小白也能轻松上手的数据库API。",
"keywords": [
"vk-unicloud-router",
"云函数路由、云对象路由",
"vk云开发",
"内置uni-id、uview、数据库baseDao",
"内置众多API、工具包、支持微信公众号登录、微信小程序、app登录等"
],
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "VK",
"license": "MIT",
"repository": "https://gitee.com/vk-uni/vk-uni-cloud-router",
"name": "vk-unicloud-router",
"dependencies": {
"element-ui": "2.15.13",
"lodash": "^4.17.21",
"umy-ui": "1.1.6",
"vk-unicloud-admin-ui": "^1.17.45"
},
"engines": {
"HBuilderX": "^3.1.2"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": "370725567"
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": "https://vkdoc.fsq.pub/client/",
"type": "unicloud-template-project"
},
"uni_modules": {
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "u",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "y",
"快手": "y",
"飞书": "y",
"京东": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
+102
View File
@@ -0,0 +1,102 @@
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "金久信钢城"
}
},
{
"path": "pages/error/404/404",
"style": {
"navigationBarTitleText": "404"
}
}
,{
"path" : "pages/auth/register/register",
"style" :
{
"navigationBarTitleText": "注册",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/auth/login/login",
"style" :
{
"navigationBarTitleText": "登录",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/spot/release/release",
"style" :
{
"navigationBarTitleText": "发布现货",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/spot/goods/goods",
"style" :
{
"navigationBarTitleText": "现货市场",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/user/user",
"style" :
{
"navigationBarTitleText": "个人中心",
"enablePullDownRefresh": false
}
},
{
"path" : "pages/spot/goods/detail",
"style" :
{
"navigationBarTitleText" : "",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/company/company",
"style" :
{
"navigationBarTitleText" : "黄页",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/enquiry/release",
"style" :
{
"navigationBarTitleText" : "发布询价",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/enquiry/list",
"style" :
{
"navigationBarTitleText" : "询价",
"enablePullDownRefresh" : false
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "金久信钢城",
"navigationStyle": "custom",
// #ifndef MP-ALIPAY
"navigationBarBackgroundColor": "#F8F8F8",
// #endif
"backgroundColor": "#F8F8F8"
}
}
+612
View File
@@ -0,0 +1,612 @@
<template>
<view>
<div class="outter-wrapper">
<div class="login-page">
<div class="header w-1180 flex-h-ac">
<a href="" class="zg-logo fl nuxt-link-active">
<img src="@/static/images/logo-small.png" alt="买卖钢材,上金久信">
</a>
</div>
<div class="main-container">
<div class="w-1180 flex-h-e">
<div class="login-container">
<h2 style="margin-bottom: 15px;">会员登录</h2>
<div id="from" action="">
<div class="input-grouptabs clear">
<span @click="memberType = 'personal'"
:class="{'tab-active': memberType == 'personal'}" class="normal" data-id="0"
id="normal"><i></i>个人用户</span>
<span @click="memberType = 'business'"
:class="{'tab-active': memberType == 'business'}" class="nopassword" data-id="1"
id="nopw"><i></i>企业用户</span>
</div>
<!-- 账号密码登录 -->
<view class="login-method">
<view @click="loginMethod = 'username'" class="login-method-item">账号密码登录</view>
<view @click="loginMethod = 'mobile'" class="login-method-item">验证码登录</view>
</view>
<div class="tabContent">
<!--企业用户登录-->
<div class="login-con active" id="rc">
<div v-if="loginMethod == 'username'" class="input-group clear">
<div class="input-group-addon">
<i class="icon_user"></i>
</div>
<input type="text" class="form-control" v-model="form1.username"
placeholder="请输入手机号/邮箱/用户名" autocomplete="off">
</div>
<div v-if="loginMethod == 'username'" class="input-group clear">
<div class="input-group-addon">
<i class="icon_password"></i>
</div>
<input type="password" class="form-control" v-model="form1.password"
placeholder="请输入登录密码" autocomplete="off">
</div>
<div v-if="loginMethod == 'mobile'" class="input-group clear">
<div class="input-group-addon">
<i class="icon_user"></i>
</div>
<input type="text" class="form-control" v-model="form1.mobile"
placeholder="请输入手机号" autocomplete="off">
</div>
<div v-if="loginMethod == 'mobile'" class="input-group clear">
<div class="input-group-addon">
<i class="icon_phone"></i>
</div>
<input type="text" class="form-control" v-model="form1.smsCode"
placeholder="请输入短信验证码" autocomplete="off" />
<view @click="sendSmsCode" id="btnSendCode1" type="button"
class="btn-default" value="">{{smsTips}}</view>
</div>
</div>
</div>
<div class="input-groupp clear">
<button @click="handleSubmit" type="submit" id="login" class="btnMarymt"
style="width: 100%;">立即登录</button>
</div>
</div>
<div class="input-groupwp clear">
<navigator url="/pages/auth/register/register" style="float: left;text-align: left;">免费注册新账号</navigator>
<a href="/user/find_pwd.html" style="float: right;text-align: right;">找回密码</a>
</div>
<div class=" threeBorder"><span>第三方登录</span></div>
<div class="input-groupwpg clear">
<!-- <a href="" class="dsf-wetChat" title="微信"><i></i></a>-->
<a href="/user/qq_login.html" class="dsf-qq" title="QQ"><i></i></a>
<!-- <a href="" class="dsf-dx" title="短信"><i></i></a>-->
</div>
</div>
</div>
</div>
</div>
</div>
</view>
</template>
<script>
var vk = uni.vk
let timer = null
let timeS = 60
export default {
data() {
return {
memberType: 'personal', // business 企业 、、personal个人
loginMethod: 'username', // username 用户名 + 密码 、、mobile 手机号 + 验证码
smsTips: '获取验证码',
form1: {
mobile: '',
password: '',
smsCode: '',
username: ''
}
};
},
methods: {
handleSubmit() {
let data = {}
const {
username,
password,
mobile,
smsCode
} = this.form1
if (this.loginMethod == 'username') {
data = {
username,
password
}
vk.userCenter.login({
loading: false,
data,
success: (data) => {
this.loginSuccess()
}
});
} else {
vk.userCenter.loginBySms({
loading: false,
data: {
mobile: mobile,
code: smsCode,
},
success: (data) => {
this.loginSuccess()
}
});
}
},
sendSmsCode() {
if (timer != null) {
return
}
vk.userCenter.sendSmsCode({
loading: false,
data: {
mobile: this.form1.mobile,
type: 'login',
},
success: (data) => {
this.$message({
message: "验证码已发送",
type: 'success'
})
timeS = 60
timer = setInterval(() => {
timeS--
if (timeS == 0) {
this.stopTimer()
this.smsTips = "重新发送"
} else {
this.smsTips = timeS + "秒"
}
}, 1000)
}
});
},
stopTimer() {
if (timer != null) {
clearInterval(timer)
timer = null
}
},
loginSuccess() {
uni.reLaunch({
url: '/'
})
}
},
onUnload() {
this.stopTimer()
}
}
</script>
<style lang="scss" scoped>
@charset "utf-8";
.login-method {
display: flex;
justify-content: space-between;
font-size: 14px;
margin-bottom: 2px;
&-item {
color: #d0111a;
cursor: pointer;
}
}
.outter-wrapper {
background-color: #fff;
}
.zg-logo img {
width: 230px;
border: none;
}
.layout-common-footer {
text-align: center;
margin: 15px 0px 10px;
}
.layout-common-footer .copyright .link>a {
color: #666;
padding: 0 10px;
display: inline-block;
line-height: 2
}
.w-1180 {
width: 1200px;
margin: 0px auto;
box-sizing: border-box;
}
.flex-h-ac {
display: flex;
align-items: center;
}
.header {
height: 90px;
}
.main-container {
min-width: 1200px;
padding: 60px 0;
background: #e8f5fd url(/static/images/login-bg.jpg)50% no-repeat;
}
.flex-h-e,
.flex-h-e-ac {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.main-container .login-container {
width: 350px;
box-sizing: border-box;
padding: 30px 35px 30px;
background-color: #fff;
}
.login-container h2 {
text-align: center;
line-height: 2;
color: #000;
font-size: 25px;
margin-bottom: 25px;
}
.btnMarymt {
height: 48px;
line-height: 48px;
background: #a92924;
color: #fff !important;
text-align: center;
width: 100%;
background: linear-gradient(90deg, #f0242e, #d0111a);
font-size: 16px;
cursor: pointer;
text-align: center;
}
.btnMarymt:hover {
background: #f12d36
}
.input-group {
width: 100%;
height: 46px;
}
.input-group-addon {}
.input-group .form-control {
flex: 1;
height: 100%;
border: none;
background: none;
margin-left: 12px;
outline: none;
font-size: 13px;
color: #333;
}
.input-group {
display: flex;
align-items: center;
border: 1px solid #d4d4d4;
margin-bottom: 15px;
position: relative;
}
.input-group-addon i {
background: url(/static/images/iconsmall.png)no-repeat center center;
width: 38px;
border-right: 1px solid #d4d4d4;
height: 26px;
overflow: hidden;
display: inline-block
}
.input-group-addon .icon_user {
background-position: -212px -35px;
}
.input-group-addon .icon_phone {
background-position: -212px -67px;
}
.input-group-addon .icon_password {
background-position: -212px -100px;
}
.input-group-addon .icon_yaoqingma {
background-position: -209px -318px;
}
.input-groupp {
width: 100%;
}
#btnSendCode1 {
position: absolute;
right: 1px;
top: 8px;
line-height: 31px;
color: #d0111a;
width: 79px;
text-align: center;
cursor: pointer;
border-left: 1px solid;
background: none;
font-size: 14px;
}
.input-group.focus {
background-color: #fff;
box-shadow: 0 2px 11px 0 rgba(0, 0, 0, .04)
}
.input-groupwp {
width: 100%;
text-align: center;
height: 60px;
line-height: 60px;
font-size: 14px;
margin-bottom: 10px;
}
.input-groupwpg a {
display: inline-block;
}
.input-groupwpg .dsf-wetChat i {
background: url(/static/images/iconsmall.png)no-repeat;
width: 50px;
height: 40px;
display: block;
background-position: -218px -132px;
}
.input-groupwpg .dsf-qq i {
background: url(/static/images/iconsmall.png)no-repeat;
width: 50px;
height: 40px;
display: block;
background-position: -216px -178px;
margin: 0px 24px;
}
.input-groupwpg .dsf-dx i {
background: url(/static/images/iconsmall.png)no-repeat;
width: 50px;
height: 40px;
display: block;
background-position: -215px -224px;
}
.threeBorder {
position: relative;
text-align: center;
}
.threeBorder:after {
content: '';
position: absolute;
z-index: 0;
bottom: 10px;
left: 10px;
width: 95%;
height: 1px;
border-bottom: 1px solid #CCCCCC;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
}
.threeBorder span {
color: #888888;
background: #fff;
width: 90px;
margin: 0 auto;
z-index: 1002;
position: relative;
display: block;
}
.input-groupwpg {
width: 100%;
text-align: center;
height: 48px;
font-size: 14px;
margin-top: 22px;
}
.login-con {
display: none;
}
.input-grouptabs span {
color: #666;
cursor: pointer;
font-size: 16px;
line-height: 23px;
font-weight: normal;
display: inline-block;
padding: 0px 18px;
text-align: center;
margin: 0px auto;
}
.input-grouptabs {
text-align: center;
margin: 0px auto 30px;
width: 100%;
}
.input-grouptabs i {
background: url(/static/images/iconsmall.png)no-repeat;
width: 25px;
height: 25px;
float: left;
margin-right: 5px;
}
.input-grouptabs .tab-active#normal i {
background-position: -218px -269px;
}
.input-grouptabs .tab-active#nopw i {
background-position: -218px -269px;
}
.input-grouptabs #normal i {
background-position: -218px -293px;
}
.input-grouptabs #nopw i {
background-position: -218px -293px;
}
.input-grouptabs span.tab-active {
color: #a92924
}
.active {
display: block;
}
.input-groupread {
height: 40px;
line-height: 30px;
width: 100%;
text-align: left;
}
.agreement_dialogs {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
width: 100%;
height: 100%;
z-index: 99999;
text-align: center;
display: none;
background-color: rgba(35, 35, 35, 0.4);
-webkit-transition: all 0.5s linear;
transition: all 0.5s linear;
}
.agreement_dialogs .dialog_lay_1syd {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: inline-block;
width: 750px;
color: #656565;
font-size: 12px;
line-height: 20px;
background-color: #fff;
text-align: left;
vertical-align: middle;
-webkit-transition: all 0.2s linear;
transition: all 0.2s linear;
}
.agreement_dialogs .dialog_foot_1hHfr {
height: 80px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
border-top: 1px solid #d5d5d5;
margin: 0;
text-align: center;
}
.agreement_dialogs .dialog_minorBtn_1u8nf {
display: inline-block;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border: 1px #316ccb solid;
padding: 0 30px;
height: 40px;
background: #a92924;
background: linear-gradient(90deg, #f0242e, #d0111a);
line-height: 40px;
cursor: pointer;
font-size: 16px;
vertical-align: top;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
color: #fff;
border-color: #fff;
}
.agreement_titley {
height: 55px;
line-height: 55px;
font-size: 16px;
color: #666;
text-align: center;
border-bottom: 1px solid #d5d5d5;
font-weight: 400;
}
.agreement_content {
margin: 23px 32px;
}
.con-subhead {
font-size: 14px;
font-weight: 500;
color: #333;
margin-bottom: 16px;
}
.con-content {
height: 240px;
overflow-y: scroll;
line-height: 2;
font-size: 13px;
}
</style>
+629
View File
@@ -0,0 +1,629 @@
<template>
<view>
<top-bar></top-bar>
<common-header></common-header>
<category-bar></category-bar>
<div class="outter-wrapper">
<div class="login-page">
<div class="main-container">
<div class="w-1180 flex-h-e">
<div class="login-container">
<h2 style="margin-bottom: 15px;">免费注册会员</h2>
<view id="from" action="">
<div class="input-grouptabs clear">
<span @click="form1.accountType = 1"
:class="{'tab-active': form1.accountType == 1}" class="normal" data-id="0"
id="normal"><i></i>个人用户</span>
<span @click="form1.accountType = 2"
:class="{'tab-active': form1.accountType == 2}" class="nopassword" data-id="1"
id="nopw"><i></i>企业用户</span>
</div>
<div class="tabContent">
<div class="login-con active" id="rc">
<div class="input-group clear">
<div class="input-group-addon">
<i class="icon_user"></i>
</div>
<input v-model="form1.mobile" type="text" class="form-control" name="mobile"
placeholder="请输入手机号" autocomplete="off">
</div>
<div class="input-group clear">
<div class="input-group-addon">
<i class="icon_phone"></i>
</div>
<input type="text" class="form-control" v-model="form1.smsCode" name="smsCode"
placeholder="请输入短信验证码" autocomplete="off" />
<view @click="sendSmsCode" id="btnSendCode1" type="button"
class="btn-default" value="">{{smsTips}}</view>
</div>
<div class="input-group clear">
<div class="input-group-addon">
<i class="icon_password"></i>
</div>
<input type="password" class="form-control" v-model="form1.password" name="password"
placeholder="设置登录密码" autocomplete="off">
</div>
<div class="input-group clear">
<div class="input-group-addon">
<i class="icon_password"></i>
</div>
<input type="password" class="form-control" v-model="form1.repassword"
placeholder="确认登录密码" autocomplete="off">
</div>
<div class="input-group clear">
<div class="input-group-addon">
<i class="icon_yaoqingma"></i>
</div>
<input type="text" class="form-control" v-model="form1.inviteCode"
placeholder="请输入邀请码,选填" autocomplete="off">
</div>
</div>
</div>
<div class="input-groupread clear">
<input id="check" type="checkbox" class="check" name="is_read">
<label>阅读并同意<a href="javascript:;" style="display: inline-block;"
id="register-xieyi">
<span style="color: #3288b2">《金久信注册协议》</span></a></label>
</div>
<div class="input-groupp clear">
<button @click="handleSubmit" type="button" class="btnMarymt"
style="width: 100%;">立即免费注册</button>
</div>
</view>
<div class="input-groupwp clear">
<navigator url="/pages/auth/login/login">已有账号?<span style="color: #a92924">去登录</span></navigator>
</div>
</div>
</div>
</div>
</div>
</div>
</view>
</template>
<script>
let timer = null
let timeS = 60
var vk = uni.vk;
export default {
data() {
return {
smsTips: '点击获取',
form1: {
accountType: 1, // business 企业 、、personal个人
mobile: '',
smsCode: '',
password: '',
repassword: '',
inviteCode: '',
}
};
},
methods: {
sendSmsCode() {
if (timer != null) {
return
}
vk.userCenter.sendSmsCode({
loading: false,
data: {
mobile: this.form1.mobile,
type: 'register',
},
success: (data) => {
this.$message({
message: "验证码已发送",
type: 'success'
})
timeS = 60
timer = setInterval(() => {
timeS--
if (timeS == 0) {
this.stopTimer()
this.smsTips = "重新发送"
} else {
this.smsTips = timeS + "秒"
}
}, 1000)
}
});
},
handleSubmit() {
if (this.testForm()) {
const {
mobile, // 手机号
smsCode, // 短信验证码4-8位
password, // 密码 6-20位
repassword, // 重复输入密码
inviteCode, // 邀请码
accountType
} = this.form1
vk.userCenter.loginBySms({
data: {
type: 'register',
mobile: mobile,
code: smsCode,
password,
inviteCode,
accountType
},
success: (data) => {
uni.reLaunch({
url: '/'
})
}
});
}
},
testForm() {
const {
mobile, // 手机号
smsCode, // 短信验证码4-8位
password, // 密码 6-20位
repassword, // 重复输入密码
inviteCode, // 邀请码
} = this.form1;
// 手机号验证
if (!mobile || !/^1[3456789]\d{9}$/.test(mobile)) {
this.$message({
message: '手机号为空或格式不正确',
type: 'error'
})
return false
}
// 短信验证码验证
if (!smsCode || !/^\d{4,8}$/.test(smsCode)) {
// 短信验证码为空或格式不正确
// 处理错误逻辑
this.$message({
message: '短信验证码为空或格式不正确',
type: 'error'
})
return false
}
// 密码验证
if (!password || password.length < 6 || password.length > 20) {
// 密码为空或长度不符合要求
this.$message({
message: '密码长度不符合要求',
type: 'error'
})
return false
// 处理错误逻辑
}
// 重复输入密码验证
if (password !== repassword) {
// 两次输入的密码不一致
this.$message({
message: '两次输入的密码不一致',
type: 'error'
})
return false
// 处理错误逻辑
}
return true
}
},
onUnload() {
if (timer != null) {
clearInterval(timer)
}
}
}
</script>
<style lang="scss">
@charset "utf-8";
.zg-logo img {
width: 230px;
border: none;
}
.layout-common-footer {
text-align: center;
margin: 15px 0px 10px;
}
.layout-common-footer .copyright .link>a {
color: #666;
padding: 0 10px;
display: inline-block;
line-height: 2
}
.w-1180 {
width: 1200px;
margin: 0px auto;
box-sizing: border-box;
}
.flex-h-ac {
display: flex;
align-items: center;
}
.header {
height: 90px;
}
.main-container {
min-width: 1200px;
padding: 60px 0;
background: #e8f5fd url(/static/images/login-bg.jpg)50% no-repeat;
}
.flex-h-e,
.flex-h-e-ac {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.main-container .login-container {
width: 350px;
box-sizing: border-box;
padding: 30px 35px 30px;
background-color: #fff;
}
.login-container h2 {
text-align: center;
line-height: 2;
color: #000;
font-size: 25px;
margin-bottom: 25px;
}
.btnMarymt {
height: 48px;
line-height: 48px;
background: #a92924;
color: #fff !important;
text-align: center;
width: 100%;
background: linear-gradient(90deg, #f0242e, #d0111a);
font-size: 16px;
cursor: pointer;
text-align: center;
}
.btnMarymt:hover {
background: #f12d36
}
.input-group {
width: 100%;
height: 46px;
}
.input-group-addon {}
.input-group .form-control {
flex: 1;
height: 100%;
border: none;
background: none;
margin-left: 12px;
outline: none;
font-size: 13px;
color: #333;
}
.input-group {
display: flex;
align-items: center;
border: 1px solid #d4d4d4;
margin-bottom: 15px;
position: relative;
}
.input-group-addon i {
background: url(/static/images/iconsmall.png)no-repeat center center;
width: 38px;
border-right: 1px solid #d4d4d4;
height: 26px;
overflow: hidden;
display: inline-block
}
.input-group-addon .icon_user {
background-position: -212px -35px;
}
.input-group-addon .icon_phone {
background-position: -212px -67px;
}
.input-group-addon .icon_password {
background-position: -212px -100px;
}
.input-group-addon .icon_yaoqingma {
background-position: -209px -318px;
}
.input-groupp {
width: 100%;
}
#btnSendCode1 {
position: absolute;
right: 1px;
top: 8px;
line-height: 31px;
color: #d0111a;
width: 79px;
text-align: center;
cursor: pointer;
border-left: 1px solid;
background: none;
font-size: 14px;
}
.input-group.focus {
background-color: #fff;
box-shadow: 0 2px 11px 0 rgba(0, 0, 0, .04)
}
.input-groupwp {
width: 100%;
text-align: center;
height: 60px;
line-height: 60px;
font-size: 14px;
margin-bottom: 10px;
}
.input-groupwpg a {
display: inline-block;
}
.input-groupwpg .dsf-wetChat i {
background: url(/static/images/iconsmall.png)no-repeat;
width: 50px;
height: 40px;
display: block;
background-position: -218px -132px;
}
.input-groupwpg .dsf-qq i {
background: url(/static/images/iconsmall.png)no-repeat;
width: 50px;
height: 40px;
display: block;
background-position: -216px -178px;
margin: 0px 24px;
}
.input-groupwpg .dsf-dx i {
background: url(/static/images/iconsmall.png)no-repeat;
width: 50px;
height: 40px;
display: block;
background-position: -215px -224px;
}
.threeBorder {
position: relative;
text-align: center;
}
.threeBorder:after {
content: '';
position: absolute;
z-index: 0;
bottom: 10px;
left: 10px;
width: 95%;
height: 1px;
border-bottom: 1px solid #CCCCCC;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
}
.threeBorder span {
color: #888888;
background: #fff;
width: 90px;
margin: 0 auto;
z-index: 1002;
position: relative;
display: block;
}
.input-groupwpg {
width: 100%;
text-align: center;
height: 48px;
font-size: 14px;
margin-top: 22px;
}
.login-con {
display: none;
}
.input-grouptabs span {
color: #666;
cursor: pointer;
font-size: 16px;
line-height: 23px;
font-weight: normal;
display: inline-block;
padding: 0px 18px;
text-align: center;
margin: 0px auto;
}
.input-grouptabs {
text-align: center;
margin: 0px auto 30px;
width: 100%;
}
.input-grouptabs i {
background: url(/static/images/iconsmall.png)no-repeat;
width: 25px;
height: 25px;
float: left;
margin-right: 5px;
}
.input-grouptabs .tab-active#normal i {
background-position: -218px -269px;
}
.input-grouptabs .tab-active#nopw i {
background-position: -218px -269px;
}
.input-grouptabs #normal i {
background-position: -218px -293px;
}
.input-grouptabs #nopw i {
background-position: -218px -293px;
}
.input-grouptabs span.tab-active {
color: #a92924
}
.active {
display: block;
}
.input-groupread {
height: 40px;
line-height: 30px;
width: 100%;
text-align: left;
}
.agreement_dialogs {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
width: 100%;
height: 100%;
z-index: 99999;
text-align: center;
display: none;
background-color: rgba(35, 35, 35, 0.4);
-webkit-transition: all 0.5s linear;
transition: all 0.5s linear;
}
.agreement_dialogs .dialog_lay_1syd {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: inline-block;
width: 750px;
color: #656565;
font-size: 12px;
line-height: 20px;
background-color: #fff;
text-align: left;
vertical-align: middle;
-webkit-transition: all 0.2s linear;
transition: all 0.2s linear;
}
.agreement_dialogs .dialog_foot_1hHfr {
height: 80px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
border-top: 1px solid #d5d5d5;
margin: 0;
text-align: center;
}
.agreement_dialogs .dialog_minorBtn_1u8nf {
display: inline-block;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border: 1px #316ccb solid;
padding: 0 30px;
height: 40px;
background: #a92924;
background: linear-gradient(90deg, #f0242e, #d0111a);
line-height: 40px;
cursor: pointer;
font-size: 16px;
vertical-align: top;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
color: #fff;
border-color: #fff;
}
.agreement_titley {
height: 55px;
line-height: 55px;
font-size: 16px;
color: #666;
text-align: center;
border-bottom: 1px solid #d5d5d5;
font-weight: 400;
}
.agreement_content {
margin: 23px 32px;
}
.con-subhead {
font-size: 14px;
font-weight: 500;
color: #333;
margin-bottom: 16px;
}
.con-content {
height: 240px;
overflow-y: scroll;
line-height: 2;
font-size: 13px;
}
#btnSendCode1 {
cursor: pointer;
}
</style>
+34
View File
@@ -0,0 +1,34 @@
<template>
<view>
<top-bar></top-bar>
<common-header></common-header>
<category-bar></category-bar>
<view class="page-nav">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>
<navigator style="display: inline-block;" url="/pages/spot/goods/goods">现货市场</navigator>
</el-breadcrumb-item>
<el-breadcrumb-item>{{product.name}}</el-breadcrumb-item>
</el-breadcrumb>
</view>
</view>
</template>
<script>
export default {
data() {
return {
};
},
onLoad() {
}
}
</script>
<style lang="scss">
</style>
+184
View File
@@ -0,0 +1,184 @@
<template>
<view>
<!-- <view class="product-title">{{title}}</view> -->
<vk-data-form ref="form1" v-model="form1.data" :action="form1.props.action" :columns="form1.props.columns"
:rules="form1.props.rules" :form-type="form1.props.formType" :loading.sync="form1.props.loading"
:before-action="form1.props.beforeAction" :auto-close="true" label-width="140px" :footer-show="false"
@success="onFormSuccess">
</vk-data-form>
</view>
</template>
<script>
import Vue from 'vue'
export default {
props: {
value: {
type: Object,
default: () => {
return {}
}
},
baseAttributes: {
type: Array,
default: () => {
return []
}
},
productIndex: {
type: Number,
default: 0
}
},
data() {
return {
title: '商品',
// 表单相关开始-----------------------------------------------------------
form1: {
// 表单请求数据,此处可以设置默认值
data: {
extraAttributes: {},
attributes: {},
},
// 表单属性
props: {
// 表单请求地址
action: "client/enquiry/kh/add",
// 表单字段显示规则
columns: [
{key: "", title: "商品1", type: "bar-title", component: 'custom-form-section'},
{
key: "name",
title: "模板",
type: "remote-select",
action: "client/enquiry/template/pub/getList",
showAll: true,
actionData: {
pageSize: 1000
},
props: {
list: "rows",
value: "_id",
label: "name"
},
watch: (res) => {
const {
option
} = res
this.form1.props.columns[2].columns = option.extraAttributes.map((item, index) => {
return {
key: index,
title: item.lable,
type: "select",
data: item.values.map(citem => {
return {
value: JSON.stringify({keyName: item.lable,keyValue: citem}),
label: citem
}
})
}
})
}
},
{
key: "extraAttributes",
title: "额外属性",
type: "object",
justify: "start",
showLabel: false,
columns: [
],
},
{
key: "attributes",
title: "固定属性",
type: "object",
// justify: "start",
showLabel: false,
columns: [
],
},
{
key: "",title: "",type: 'group',showLabel: false, justify: "start",columns:
[
{key: "procureNumber", title: "采购数量", type: "number",},
{
key: "procureUnit",
title: "单位",
type: "remote-select",
showAll: true,
action: "client/enquiry/attributes/pub/getOne",
actionData: {
label: '单位',
},
},
]
},
{key: "deliveryTime", title: "交货时限", type: "date",},
{
key: "address",
title: "交货地点",
type: "object",
// justify: "start",
showLabel: false,
columns: [
{key: "region", title: "交货地点", type: "address",},
{key: "detail", title: "详细交货地址", type: "textarea",},
],
},
],
// 表单验证规则
rules: {
name:[
{ required:true, message:'商品不能为空', trigger: ["change","blur"] }
],
},
// add 代表添加 update 代表修改
formType: "add",
// 表单是否在请求中
loading: false,
// 是否显示表单1 的弹窗
show: false,
beforeAction: (formData)=> {
return false
}
}
},
// 表单相关结束-----------------------------------------------------------
}
},
created() {
this.form1.props.columns[0].title = '商品' + (this.productIndex + 1)
},
methods: {
},
watch: {
"form1.data"(val){
this.$emit('input', val)
console.log("this.$emit('input', val.data)");
},
value(val) {
this.form1.data = val
console.log("this.form1.data = val", val);
}
}
}
</script>
<style scoped lang="scss">
.product-title {
margin: 10px;
text-align: center;
font-size: 14px;
}
</style>
+254
View File
@@ -0,0 +1,254 @@
<template>
<view>
<top-bar></top-bar>
<common-header></common-header>
<category-bar></category-bar>
<!-- <view class="page-nav">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item><navigator url="/pages/spot/goods/goods">现货市场</navigator></el-breadcrumb-item>
</el-breadcrumb>
</view> -->
<view class="carousel">
<el-carousel height="170px">
<el-carousel-item v-for="item in 4" :key="item">
<image class="carousel-img"
src="http://jyx.gxwebsoft.com/uploads/20210506/600fc93e6b85324b3ea1373ee264290d.jpg"
mode="aspectFill"></image>
</el-carousel-item>
</el-carousel>
<view class="goods-options">
<el-row class="">
<el-button @click="toRelease" type="primary" round>发布询价单</el-button>
<el-button type="primary" round plain>我发布的询价单</el-button>
</el-row>
</view>
</view>
<!-- 筛选表单 -->
<view class="filter-outer">
<el-form @submit.native.prevent label-width="80px">
<el-form-item label="关键词">
<el-input @keyup.enter.native="search" clearable placeholder="输入关键字搜索" v-model="keyword">
<el-button @click="search(1)" type="primary" slot="append" icon="el-icon-search"></el-button>
</el-input>
</el-form-item>
<el-form-item label="分类">
<el-tabs>
<el-tab-pane v-for="(item, index) in categoryTreeData" :label="item.name" :key="item._id">
<el-checkbox-group v-model="checkCategoryList[index]">
<el-checkbox v-for="(citem, cindex) in item.children" :label="citem"
:key="cindex">{{citem.name}}</el-checkbox>
</el-checkbox-group>
</el-tab-pane>
</el-tabs>
</el-form-item>
<el-form-item label="城市">
<el-checkbox-group v-model="checkProvinceList">
<!-- <el-checkbox :label="{code:0,name: '全国'}">全国</el-checkbox> -->
<el-checkbox :checked="cindex == 0" v-for="(citem, cindex) in provinceData" :label="citem"
:key="cindex">{{citem.name}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="已选">
<view class="tags">
<el-tag v-for="(item, index) in checkCategoryArr" :key="index">{{item.name}}</el-tag>
</view>
</el-form-item>
</el-form>
</view>
<!-- 商品列表 -->
<view class="goods-list">
</view>
<view class="paginatio">
<el-pagination
@current-change="search"
background
layout="prev, pager, next"
:total="goodsData.total">
</el-pagination>
</view>
</view>
</template>
<script>
import provinces from "@/uni_modules/vk-uview-ui/libs/address/provinces.json";
provinces.unshift({
code: 9999,
name: '全国'
})
export default {
data() {
return {
categoryTreeData: [],
provinceData: provinces,
checkCategoryList: [],
checkProvinceList: [],
keyword: '',
goodsData: {
total: 0,
rows: []
}
};
},
onLoad() {
this.search(1)
vk.callFunction({
url: 'client/spot/category/pub/getTree',
title: '请求中...',
data: {
},
success: (data) => {
this.categoryTreeData = data.rows
for (var i = 0; i < data.rows.length; i++) {
this.checkCategoryList.push([])
}
}
});
},
methods: {
toRelease() {
if (!vk.getVuex('$user.userInfo.fadadaConfirm')) {
this.$confirm('您尚未认证, 是否前往认证?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.getCertUrl()
})
}else if(vk.pubfn.isNull(vk.getVuex('$user.userInfo.businessCard'))) {
this.$confirm('请完善名片信息', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
vk.navigateTo('/pages/user/user?menu=business-card');
})
}else {
uni.navigateTo({
url: '/pages/enquiry/release'
})
}
},
search(pageIndex) {
const categoryIds = []
this.checkCategoryList.forEach(item => {
item.forEach(sitem => {
categoryIds.push(sitem._id)
})
})
let provinceCodes = this.checkProvinceList.map(item => item.code)
if (provinceCodes.includes(9999)) {
provinceCodes = []
}
vk.callFunction({
url: 'client/spot/goods/pub/getList',
data: {
pageIndex: pageIndex,
pageSize: 20,
keyword: this.keyword,
categoryIds: categoryIds,
provinceCodes: provinceCodes
},
success: (data) => {
console.log('data: ',data);
data.rows.forEach(item => {
try {
item.addressStr = item.address.province.name + "-" + item.address.city.name + "-" + item.address.area.name
} catch(err){
item.addressStr = ""
}
})
this.goodsData = data
}
});
},
},
computed: {
checkCategoryArr() {
let arr = []
this.checkCategoryList.forEach(item => {
arr.push(...item)
})
this.checkProvinceList.forEach(item => {
arr.push({
...item
})
})
return arr
}
}
}
</script>
<style lang="scss" scoped>
.carousel {
width: 1200px;
margin: 20px auto;
}
.carousel-img {
width: 100%;
height: 100%;
}
.goods-options {
background-color: #FFFFFF;
padding: 20px;
}
.filter-outer {
width: 1200px;
margin: 20px auto;
background-color: #FFFFFF;
padding: 20px;
}
.tags {
display: flex;
.el-tag {
margin-right: 10px;
}
}
.goods-list {
width: 1200px;
margin: 20px auto;
display: flex;
}
.paginatio{
float: none;
width: 1200px;
margin: 20px auto;
display: flex;
justify-content: center;
}
</style>
+234
View File
@@ -0,0 +1,234 @@
<template>
<view>
<top-bar></top-bar>
<common-header></common-header>
<category-bar></category-bar>
<view class="page-nav">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>
<navigator style="display: inline-block;" url="/pages/enquiry/list">询价单</navigator>
</el-breadcrumb-item>
<el-breadcrumb-item>发布询价单</el-breadcrumb-item>
</el-breadcrumb>
</view>
<view class="form-view">
<view class="m-20">
<view class="title-main">请填写询价单</view>
<view class="title-sub">询价信息越完整,供应商报价越精准</view>
</view>
<view v-for="(item, index) in productList" :key="index">
<enquiry-template :ref="'product' + index" v-model="productList[index]" :base-attributes="baseAttributes" :productIndex="index"></enquiry-template>
</view>
<view class="btn-add-outer">
<el-button @click="addProduct" type="primary" size="small">添加商品</el-button>
<el-button @click="removeProduct" type="warning" size="small">删除商品</el-button>
</view>
<vk-data-form ref="form1" v-model="form1.data" :action="form1.props.action" :columns="form1.props.columns"
:rules="form1.props.rules" :form-type="form1.props.formType" :loading.sync="form1.props.loading"
:before-action="form1.props.beforeAction" label-width="140px" cancel-text="保存草稿" submit-text="提交询价单"
@success="onFormSuccess">
</vk-data-form>
<!-- <el-divider content-position="left">其他设置</el-divider> -->
</view>
</view>
</template>
<script>
import EnquiryTemplate from './components/template.vue'
export default {
components: {EnquiryTemplate},
data() {
return {
// 表单相关开始-----------------------------------------------------------
productList: [{}],
baseAttributes: [],
form1: {
// 表单请求数据,此处可以设置默认值
data: {
// extraAttributes: {},
// attributes: {},
invoice: false
},
// 表单属性
props: {
// 表单请求地址
action: "client/enquiry/sheet/kh/add",
// 表单字段显示规则
columns: [
{key: "", title: "采购商其他要求", type: "bar-title"},
{key: "remark", title: "其他要求", type: "textarea",},
{key: "", title: "发票要求", type: "bar-title"},
{key: "invoice", title: "发票要求", type: "radio",
data: [
{ value: true, label: "含税" },
{ value: false, label: "不含税" }
],
},
{key: "writeInvoiceTime",
title: "开票时间",
type: "radio",
data: [
{ value: '付款当月(限20号之前付款,20号之后付款次月开票)', label: "付款当月(限20号之前付款,20号之后付款次月开票)" },
{ value: '付款后次月', label: "付款后次月" },
{ value: '付款前', label: "付款前" },
],
showRule: 'invoice == true'
},
{key: "nvoiceType",
title: "发票种类",
type: "radio",
data: [
{ value: '增值税专用发票13%', label: "增值税专用发票13%" },
{ value: '增值税普通发票', label: "增值税普通发票" },
{ value: '普通发票', label: "普通发票" },
],
showRule: 'invoice == true'
},
{key: "", title: "运输要求", type: "bar-title"},
{key: "transportDocuments",
title: "随货资料",
type: "checkbox",
data: [
{ value: '合格证', label: "合格证" },
{ value: '检测报告', label: "检测报告" },
{ value: '销售清单', label: "销售清单" },
{ value: '磅重', label: "磅重" },
],
},
{key: "otherTransportDocuments", title: "其他资料", type: "text"},
{key: "transportLimit",
title: "运输限制",
type: "text",
},
{key: "", title: "交易模式", type: "bar-title", component: 'custom-form-section'},
{key: "tradeMethod",
title: "交易模式",
type: "radio",
data: [
{ value: '自主交易', label: "自主交易" },
{ value: '金久信公证', label: "金久信公证" },
],
},
{key: "", title: "交易说明", type: "bar-title"},
{
key: "payMethod",
title: "付款方式",
type: "radio",
data: [
{ value: 1, label: "预付x%货到付全款" },
{ value: 2, label: "货到验收后付款" },
{ value: 3, label: "提货付全款" },
{ value: 4, label: "信誉采购" },
{ value: 5, label: "其他付款方式" },
],
},
{
key: "",title: "",type: 'group',showLabel: false, justify: "start",columns:[
{key: "advancePayRate", title: "预付百分比", type: "percentage",showRule: "payMethod==1"},
{key: "otherPayMethod", title: "其他付款方式", type: "text",showRule: "payMethod==5"},
{key: "reputationPayDay", title: "货到签单后账期天数", type: "number",showRule: "payMethod==4",rightText: '天'},
]
},
{key: "answerTime", title: "报价时限", type: "date",dateType: "datetime"},
{key: "earnestMoney", title: "保证金要求", type: "text"},
// {key: "", title: "采购商信息", type: "bar-title"},
{
key: "files",
title: "附件文档",
type: "file",
buttonText: "点击上传",
limit: 9,
accept: ".jpg,.png,.xlsx,.doc,.docx",
tips: '上传自有采购单图片或文档,支持jpg/png/word/excel'
},
],
// 表单验证规则
rules: {
// name:[
// { required:true, message:'商品不能为空', trigger: ["change","blur"] }
// ],
},
// add 代表添加 update 代表修改
formType: "add",
// 表单是否在请求中
loading: false,
// 是否显示表单1 的弹窗
show: false,
beforeAction: (formData)=> {
// console.log('formData: ',JSON.parse(JSON.stringify(formData)));
// console.log('product: ',JSON.parse(JSON.stringify(this.productList)));
formData.productList = JSON.parse(JSON.stringify(this.productList))
return formData
}
}
},
// 表单相关结束-----------------------------------------------------------
};
},
onLoad() {
this.getAttributes()
},
methods: {
getAttributes() {
// vk.callFunction({
// url: 'client/enquiry/attributes/pub/getList',
// title: '请求中...',
// data: {
// pageSize: 1000
// },
// success: (res) => {
// this.baseAttributes = res.rows
// }
// });
},
addProduct() {
this.productList.push({})
}
}
}
</script>
<style lang="scss">
.form-view {
width: 1200px;
margin: 0 auto;
background-color: #FFFFFF;
padding: 20rpx;
}
.m-20 {
margin: 20px;
}
.title-main{
font-size: 18px;
font-weight: bold;
text-align: center;
}
.title-sub{
font-size: 14px;
text-align: center;
}
.btn-add-outer{
padding-left: 140px;
margin: 0 0 20px 0;
}
</style>
+49
View File
@@ -0,0 +1,49 @@
<template>
<view class="app">
<!-- 页面内容开始 -->
这里是404页面
<!-- 页面内容结束 -->
</view>
</template>
<script>
var vk = uni.vk;
export default {
data() {
// 页面数据变量
return {
}
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
vk = uni.vk;
this.options = options;
this.init(options);
},
// 函数
methods: {
// 页面数据初始化函数
init(options){
console.log("init: ",options);
},
pageTo(path){
vk.navigateTo(path);
}
},
// 监听器
watch:{
},
// 计算属性
computed:{
}
}
</script>
<style lang="scss" scoped>
</style>
+76
View File
@@ -0,0 +1,76 @@
<template>
<view>
<top-bar></top-bar>
<common-header></common-header>
<category-bar></category-bar>
这是首页
</view>
</template>
<script>
var vk = uni.vk;
export default {
data() {
// 页面数据变量
return {
// init请求返回的数据
data:{
},
// 表单请求数据
form1:{
},
scrollTop:0,
}
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
},
// 监听 - 页面每次【加载时】执行(如:前进)
onLoad(options = {}) {
vk = uni.vk;
this.options = options;
this.init(options);
},
// 监听 - 页面【首次渲染完成时】执行。注意如果渲染速度快,会在页面进入动画完成前触发
onReady(){
},
// 监听 - 页面每次【显示时】执行(如:前进和返回) (页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面)
onShow() {
},
// 监听 - 页面每次【隐藏时】执行(如:返回)
onHide() {
},
// 监听 - 点击右上角转发时
onShareAppMessage(options) {
},
// 函数
methods: {
// 页面数据初始化函数
init(options){
},
pageTo(path){
vk.navigateTo(path);
}
},
// 监听器
watch:{
},
// 计算属性
computed:{
}
}
</script>
<style lang="scss" scoped>
</style>
+497
View File
@@ -0,0 +1,497 @@
<template>
<view>
<top-bar></top-bar>
<common-header></common-header>
<category-bar></category-bar>
<view class="page-nav">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>
<navigator style="display: inline-block;" url="/pages/spot/goods/goods">现货市场</navigator>
</el-breadcrumb-item>
<el-breadcrumb-item>{{product.name}}</el-breadcrumb-item>
</el-breadcrumb>
</view>
<view class="card">
<div class="card-header">
<view class="card-header-left">
<image class="logo" :src="product.user.businessCard.logo" mode="aspectFit"></image>
<view class="info">
<view v-if="product.user.accountType == 1" class="info-name">{{product.user.person.personName}}
</view>
<view v-if="product.user.accountType == 2" class="info-name">
{{product.user.company.companyName}}
</view>
<view class="info-update">
<view class="info-update-time">
{{product._add_time_str}}
</view>
<view class="info-update-business">
主营业务:{{product.user.businessCard.mainBusiness}}
</view>
</view>
</view>
</view>
<view class="card-header-right">
<el-button v-if="vk.getVuex('$user.userInfo._id') != product.userId" @click="toCooperate"
type="primary" round>申请合作</el-button>
</view>
</div>
<view class="card-body">
<div class="part-head">
<h3>现货详情</h3>
</div>
<view v-if="product.user.accountType == 1" class="card-body-name">{{product.user.person.personName}}
</view>
<view v-if="product.user.accountType == 2" class="card-body-name">{{product.user.company.companyName}}
</view>
<view class="card-body-stock">库存:{{product.stock}}吨</view>
<view class="card-body-address">
供货地:{{product.address.province.name + "-" + product.address.city.name + "-" + product.address.area.name}}
</view>
</view>
<view class="card-body">
<div class="part-head">
<h3>附件</h3>
</div>
<ul class="el-upload-list el-upload-list--text">
<li @click="downloadFile(item)" v-for="(item,index) in product.files" :key="index" tabindex="0"
class="el-upload-list__item is-success">
<a class="el-upload-list__item-name">
<i class="el-icon-document"></i>
{{item | getFileName}}
</a>
</li>
</ul>
</view>
<view class="card-body">
<div class="part-head">
<h3>已收到的合作申请</h3>
</div>
<vk-data-table :data="product.cooperateList" :columns="table1.columns"
:customRightBtns="table1.customRightBtns"></vk-data-table>
</view>
</view>
<!-- 申请合作 -->
<el-dialog :visible.sync="form1.props.show" title="申请合作" width="600px" mode="form">
<vk-data-form ref="form1" v-model="form1.data" :action="form1.props.action" :columns="form1.props.columns"
:rules="form1.props.rules" :form-type="form1.props.formType" :loading.sync="form1.props.loading"
:beforeAction="form1.props.beforeAction" :auto-close="true" label-width="140px"
@success="onFormSuccess"></vk-data-form>
</el-dialog>
</view>
</template>
<script>
export default {
data() {
return {
product: {
name: '现货详情',
address: {
province: {},
city: {},
area: {},
},
user: {
businessCard: {},
},
cooperateList: []
},
// 表单相关开始-----------------------------------------------------------
form1: {
// 表单请求数据,此处可以设置默认值
data: {
},
// 表单属性
props: {
// 表单请求地址
action: "client/spot/goods/kh/addCooperate",
// 表单字段显示规则
columns: [{
key: "person",
title: "个人",
type: "object",
showLabel: false,
showRule: (formData) => {
return formData.person.personName != null
},
columns: [{
key: "personName",
title: "姓名",
type: "text",
readonly: true,
disabled: true
},
// {
// key: "idCard",
// title: "身份证号",
// type: "text",
// readonly: true,
// disabled: true
// },
{
key: "mobile",
title: "电话",
type: "text",
readonly: true,
disabled: true
},
]
},
{
key: "company",
title: "企业信息",
type: "object",
showLabel: false,
showRule: (formData) => {
return formData.company.companyName != null
},
columns: [{
key: "companyName",
title: "企业名称",
type: "text",
readonly: true,
disabled: true
},
{
key: "organization",
title: "统一社会信用代码",
type: "text",
readonly: true,
disabled: true
},
{
key: "legalName",
title: "法人",
type: "text",
readonly: true,
disabled: true
},
{
key: "legalMobile",
title: "法人电话",
type: "text",
readonly: true,
disabled: true
},
]
},
{
key: "manager",
title: "代理人",
type: "object",
showLabel: false,
showRule: (formData) => {
return formData.manager.personName != null
},
columns: [{
key: "personName",
title: "代理人",
type: "text",
readonly: true,
disabled: true
},
// {
// key: "idCard",
// title: "代理人身份证号",
// type: "text",
// readonly: true,
// disabled: true
// },
{
key: "mobile",
title: "代理人电话",
type: "text",
readonly: true,
disabled: true
},
]
},
{
key: "remark",
title: "备注",
type: "textarea",
maxlength: 200,
showWordLimit: true,
},
],
// 表单验证规则
rules: {
text: [{
required: true,
message: "text不能为空",
trigger: "change"
},
{
required: true,
message: "text不能为空",
trigger: "change"
},
]
},
// add 代表添加 update 代表修改
formType: "",
// 表单是否在请求中
loading: false,
// 是否显示表单1 的弹窗
show: false,
beforeAction: (formData) => {
formData.goodsId = this.product._id
formData.goodsUserId = this.product.userId
return formData
},
}
},
// 表单相关结束-----------------------------------------------------------
table1: {
// 表格数据
data: [],
// 表格字段显示规则
columns: [{
key: "subjectName",
title: "主体",
type: "text",
width: 400,
formatter: (val, row, column, index) => {
if (vk.getVuex('$user.userInfo._id') == this.product.userId) {
return val
}
if (row.accountType == 1) {
return vk.pubfn.hidden(val, 1, 1);
} else {
return vk.pubfn.hidden(val, 2, 4);
}
}
},
{
key: "subjectMobile",
title: "联系方式",
type: "text",
width: 120,
formatter: (val, row, column, index) => {
let str = val
if (row.managerMobile) {
str = row.managerMobile
}
if (vk.getVuex('$user.userInfo._id') == this.product.userId) {
return str
}
return vk.pubfn.hidden(str, 3, 4);
}
},
{
key: "remark",
title: "备注",
type: "textarea",
width: 280,
formatter: (val, row, column, index) => {
let str = val
if (row.managerMobile) {
str = row.managerMobile
}
if (vk.getVuex('$user.userInfo._id') == this.product.userId) {
return val
}
return "******";
}
},
{
key: "_add_time_str",
title: "申请时间",
type: "text",
width: 200
},
],
customRightBtns: [{
title: '查看',
type: 'primary',
icon: 'el-icon-search',
disabled: (item) => {
return vk.getVuex('$user.userInfo._id') != this.product.userId
},
onClick: (item) => {
vk.toast(`${item._id}-按钮1`);
}
}, ]
},
}
},
onLoad({
id
}) {
// 获取现货数据
vk.callFunction({
url: 'client/spot/goods/pub/getDetail',
title: '请求中...',
data: {
_id: id,
},
success: (data) => {
console.log(data);
this.product = data.data
}
});
// 获取用户数据
vk.userCenter.getCurrentUserInfo({
success: (data) => {
this.form1.data = _.pick(data.userInfo, [
'fadadaConfirm', 'person', 'company', 'manager', 'businessCard', 'accountType'
])
// 成功后的逻辑
console.log('form1: ', {
...this.form1.data
});
}
});
},
methods: {
downloadFile(url) {
location.href = url
},
showCooperate() {
this.table2.show = true
},
toCooperate() {
if (!this.form1.data.fadadaConfirm) {
this.$confirm('您尚未认证, 是否前往认证?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.getCertUrl()
})
} else {
this.form1.props.show = true
}
// vk.navigateTo('/pages/spot/goods/cooperate?id=' + this.product._id);
},
getCertUrl() {
vk.callFunction({
url: 'client/fadada.getVerifyUrl',
success: (res) => {
location.href = res.data.url
}
});
},
onFormSuccess() {
this.form1.props.show = false
}
},
filters: {
getFileName(url) {
const arr = url.split("/")
return arr[arr.length - 1]
}
}
}
</script>
<style scoped lang="scss">
.card {
width: 1200px;
margin: 20px auto;
background-color: #FFFFFF;
padding: 30px;
}
.card-body {
padding-top: 30px;
.card-body-name {
font-size: 18px;
font-weight: bold;
}
.card-body-stock {
font-size: 14px;
margin: 20px 0;
}
.card-body-address {
font-size: 14px;
}
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0 60rpx 0;
border-bottom: 1px solid rgba(187, 187, 187, 0.37);
&-left {
display: flex;
align-items: center;
}
.logo {
width: 80px;
height: 80px;
}
.info {
padding-left: 30px;
}
.info-name {
font-size: 24px;
}
.info-update {
margin-top: 10px;
display: flex;
color: #A7A7A7;
font-size: 14px;
}
.info-update-time {
margin-right: 30px;
}
}
.part-head {
margin-bottom: 12px;
}
.part-head h3 {
line-height: 28px;
color: #a92924;
font-size: 20px;
text-indent: 15px;
position: relative;
}
.part-head h3:before {
content: " ";
width: 4px;
height: 16px;
background: #a92924;
display: inline-block;
position: absolute;
top: 6px;
left: 0;
}
</style>
+320
View File
@@ -0,0 +1,320 @@
<template>
<view>
<top-bar></top-bar>
<common-header></common-header>
<category-bar></category-bar>
<!-- <view class="page-nav">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item><navigator url="/pages/spot/goods/goods">现货市场</navigator></el-breadcrumb-item>
</el-breadcrumb>
</view> -->
<view class="carousel">
<el-carousel height="170px">
<el-carousel-item v-for="item in 4" :key="item">
<image class="carousel-img"
src="http://jyx.gxwebsoft.com/uploads/20210506/600fc93e6b85324b3ea1373ee264290d.jpg"
mode="aspectFill"></image>
</el-carousel-item>
</el-carousel>
<view class="goods-options">
<el-row class="">
<el-button @click="toRelease" type="primary" round>发布/编辑我的现货</el-button>
<!-- <el-button type="primary" round plain>我发布的现货</el-button> -->
</el-row>
</view>
</view>
<!-- 筛选表单 -->
<view class="filter-outer">
<el-form @submit.native.prevent label-width="80px">
<el-form-item label="关键词">
<el-input @keyup.enter.native="search" clearable placeholder="输入关键字搜索" v-model="keyword">
<el-button @click="search(1)" type="primary" slot="append" icon="el-icon-search"></el-button>
</el-input>
</el-form-item>
<el-form-item label="分类">
<el-tabs>
<el-tab-pane v-for="(item, index) in categoryTreeData" :label="item.name" :key="item._id">
<el-checkbox-group v-model="checkCategoryList[index]">
<el-checkbox v-for="(citem, cindex) in item.children" :label="citem"
:key="cindex">{{citem.name}}</el-checkbox>
</el-checkbox-group>
</el-tab-pane>
</el-tabs>
</el-form-item>
<el-form-item label="城市">
<el-checkbox-group v-model="checkProvinceList">
<!-- <el-checkbox :label="{code:0,name: '全国'}">全国</el-checkbox> -->
<el-checkbox :checked="cindex == 0" v-for="(citem, cindex) in provinceData" :label="citem"
:key="cindex">{{citem.name}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="已选">
<view class="tags">
<el-tag v-for="(item, index) in checkCategoryArr" :key="index">{{item.name}}</el-tag>
</view>
</el-form-item>
</el-form>
</view>
<!-- 商品列表 -->
<view class="goods-list">
<view v-for="(item, index) in goodsData.rows" :key="index" class="goods">
<view class="goods-title">{{item.name}}</view>
<view class="goods-stock">库存:{{item.stock}}吨</view>
<view class="goods-address">供货地:{{item.addressStr}}</view>
<view class="goods-image">
<image :src="item.user.businessCard.logo" mode="aspectFit"></image>
</view>
<view v-if="item.user.accountType == 1" class="goods-company">{{item.user.person.personName}}</view>
<view v-if="item.user.accountType == 2" class="goods-company">{{item.user.company.companyName}}</view>
<el-button @click="vk.navigateTo('/pages/spot/goods/detail?id=' + item._id);" type="primary" plain round size="small">立即查看</el-button>
</view>
</view>
<view class="paginatio">
<el-pagination
@current-change="search"
background
layout="prev, pager, next"
:total="goodsData.total">
</el-pagination>
</view>
</view>
</template>
<script>
import provinces from "@/uni_modules/vk-uview-ui/libs/address/provinces.json";
provinces.unshift({
code: 9999,
name: '全国'
})
export default {
data() {
return {
categoryTreeData: [],
provinceData: provinces,
checkCategoryList: [],
checkProvinceList: [],
keyword: '',
goodsData: {
total: 0,
rows: []
}
};
},
onLoad() {
this.search(1)
vk.callFunction({
url: 'client/spot/category/pub/getTree',
title: '请求中...',
data: {
},
success: (data) => {
this.categoryTreeData = data.rows
for (var i = 0; i < data.rows.length; i++) {
this.checkCategoryList.push([])
}
}
});
},
methods: {
toRelease() {
if (!vk.getVuex('$user.userInfo.fadadaConfirm')) {
this.$confirm('您尚未认证, 是否前往认证?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.getCertUrl()
})
}else if(vk.pubfn.isNull(vk.getVuex('$user.userInfo.businessCard'))) {
this.$confirm('请完善名片信息', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
vk.navigateTo('/pages/user/user?menu=business-card');
})
}else {
uni.navigateTo({
url: '/pages/spot/release/release'
})
}
},
search(pageIndex) {
const categoryIds = []
this.checkCategoryList.forEach(item => {
item.forEach(sitem => {
categoryIds.push(sitem._id)
})
})
let provinceCodes = this.checkProvinceList.map(item => item.code)
if (provinceCodes.includes(9999)) {
provinceCodes = []
}
vk.callFunction({
url: 'client/spot/goods/pub/getList',
data: {
pageIndex: pageIndex,
pageSize: 20,
keyword: this.keyword,
categoryIds: categoryIds,
provinceCodes: provinceCodes
},
success: (data) => {
console.log('data: ',data);
data.rows.forEach(item => {
try {
item.addressStr = item.address.province.name + "-" + item.address.city.name + "-" + item.address.area.name
} catch(err){
item.addressStr = ""
}
})
this.goodsData = data
}
});
},
},
computed: {
checkCategoryArr() {
let arr = []
this.checkCategoryList.forEach(item => {
arr.push(...item)
})
this.checkProvinceList.forEach(item => {
arr.push({
...item
})
})
return arr
}
}
}
</script>
<style lang="scss" scoped>
.carousel {
width: 1200px;
margin: 20px auto;
}
.carousel-img {
width: 100%;
height: 100%;
}
.goods-options {
background-color: #FFFFFF;
padding: 20px;
}
.filter-outer {
width: 1200px;
margin: 20px auto;
background-color: #FFFFFF;
padding: 20px;
}
.tags {
display: flex;
.el-tag {
margin-right: 10px;
}
}
.goods-list {
width: 1200px;
margin: 20px auto;
display: flex;
}
.goods {
width: 217px;
height: 280px;
background-color: #FFFFFF;
box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.05);
text-align: center;
margin-right: 20px;
margin-bottom: 25px;
&-title {
font-size: 15px;
color: #101010;
height: 62px;
padding-top: 20px;
font-weight: bold;
}
&-stock {
font-size: 12px;
color: #BD3124;
}
&-address {
font-size: 12px;
margin: 10px 0;
}
&-image {
width: 200px;
height: 70px;
margin: 0 auto;
image {
width: 100%;
height: 100%;
}
}
&-company {
color: #4F4F4F;
font-size: 14px;
margin: 10px 0;
}
&-buy {
width: 108px;
height: 30px;
line-height: 30px;
background-color: rgba(255, 255, 255, 1);
color: rgba(169, 41, 36, 1);
font-size: 13px;
text-align: center;
font-family: Roboto;
border: 1px solid rgba(169, 41, 36, 1);
margin: 0 auto;
cursor: pointer;
}
}
.paginatio{
float: none;
width: 1200px;
margin: 20px auto;
display: flex;
justify-content: center;
}
</style>
+175
View File
@@ -0,0 +1,175 @@
<template>
<view>
<top-bar></top-bar>
<common-header></common-header>
<category-bar></category-bar>
<view class="page-nav">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item><navigator style="display: inline-block;" url="/pages/spot/goods/goods">现货市场</navigator></el-breadcrumb-item>
<el-breadcrumb-item>发布现货</el-breadcrumb-item>
</el-breadcrumb>
</view>
<view class="form-view">
<vk-data-form ref="form1" v-model="form1.data" :action="form1.props.action" :columns="form1.props.columns"
:rules="form1.props.rules" :form-type="form1.props.formType" :loading.sync="form1.props.loading"
:before-action="form1.props.beforeAction" :auto-close="true" label-width="140px"
@success="onFormSuccess">
<template v-slot:name="{ form, keyName }">
<el-input v-model="productName" readonly placeholder="请添加现货分类"></el-input>
</template>
</vk-data-form>
</view>
</view>
</template>
<script>
export default {
data() {
return {
// 表单相关开始-----------------------------------------------------------
form1: {
// 表单请求数据,此处可以设置默认值
data: {
},
// 表单属性
props: {
// 表单请求地址
action: "client/spot/goods/kh/addUpdate",
// 表单字段显示规则
columns: [{
key: "name",
title: "现货名称",
type: "text",
},
{
key: "categoryIds",
title: "现货分类",
type: "checkbox",
action: "client/spot/category/pub/getList",
actionData: {
whereJson: {
level: 2
}
},
props: {
list: "data",
value: "_id",
label: "name"
},
watch: ({
option
}) => {
console.log('res: ', option)
this.form1.data.name = option.map(item => item.name).join('、')
this.productName = option.map(item => item.name).join('、')
console.log(this.form1);
}
},
{
key: "stock",
title: "库存(吨)",
type: "number"
},
{
key: "address",
title: "供货地",
type: "address"
},
{
key: "files",
title: "附件文档",
type: "file",
buttonText: "点击上传",
limit: 9,
accept: ".jpg,.png,.xlsx,.doc,.docx",
tips: '上传自有采购单图片或文档,支持jpg/png/word/excel'
},
],
// 表单验证规则
rules: {
categoryIds: [
{
required: true,
message: "现货名称不能为空",
trigger: ['blur', 'change']
},
{
validator: (rule, value, callback) => {
if (value.length > 5) {
callback(new Error('最多选择五个分类'));
} else {
callback()
}
},
trigger: ['blur', 'change']
},
],
stock: [
{
required: true,
message: "请填写库存",
trigger: ['blur', 'change']
},
{
min: 0,
type: 'number',
message: "库存不能小于0",
trigger: ['blur', 'change']
},
],
address: [
{
required: true,
message: "请填写地址",
trigger: ['blur', 'change']
}
]
},
// add 代表添加 update 代表修改
formType: "add",
// 表单是否在请求中
loading: false,
// 是否显示表单1 的弹窗
show: false
}
},
productName: ''
// 表单相关结束-----------------------------------------------------------
};
},
onLoad() {
vk.callFunction({
url: 'client/spot/goods/kh/getSelfOne',
success: (res) => {
if(res.data) {
this.$refs.form1.setResetFormData(res.data);
this.$refs.form1.resetForm();
this.productName = res.data.name
}
}
});
},
methods: {
onFormSuccess() {}
}
}
</script>
<style lang="scss">
.form-view {
width: 1200px;
margin: 0 auto;
background-color: #FFFFFF;
padding: 20rpx;
}
</style>
+211
View File
@@ -0,0 +1,211 @@
<template>
<el-card>
<div slot="header" class="clearfix">
<span>我的名片</span>
</div>
<!-- 表单开始 -->
<vk-data-form
ref="form1"
v-model="form1.data"
:rules="form1.props.rules"
:action="form1.props.action"
:form-type="form1.props.formType"
:columns='form1.props.columns'
:loading.sync="form1.props.loading"
label-width="140px"
input-width="400px"
:before-action="form1.props.beforeAction"
@success="onFormSuccess"
>
<!-- v-slot:editor 中的 editor 对应 columns中的 key, form对应 form1.data keyName 对应 columns中的 key -->
<!-- <template v-slot:editor="{ form, keyName }">
<vk-data-input-editor v-model="form[keyName]" placeholder="开始输入" width="750px"></vk-data-input-editor>
</template> -->
</vk-data-form>
</el-card>
</template>
<script>
export default {
data() {
return {
// 表单相关开始-----------------------------------------------------------
form1: {
// 表单请求数据,此处可以设置默认值
data: {
companyIntroduction: ''
},
// 表单属性
props: {
// 表单请求地址
action: "no",
// 表单字段显示规则
columns: [
{
key: "logo",
title: "Logo",
type: "image",
limit: 1
},
{
key: "personName",
title: "姓名",
type: "text"
},
{
key: "position",
title: "职位",
type: "text"
},
{
key: "address",
title: "地区",
type: "address"
},
{
key: "addressDetail",
title: "详细地址",
type: "text"
},
{
key: "email",
title: "邮箱",
type: "text"
},
{
key: "website",
title: "网址",
type: "text"
},
{
key: "mainBusiness",
title: "主营业务",
type: "textarea"
},
{
key: "mainSpotCategoryIds",
title: "主营商品",
type: "checkbox",
action: "client/spot/category/pub/getList",
actionData: {
whereJson: {
level: 2
}
},
props: {
list: "data",
value: "_id",
label: "name"
}
},
{
key: "companyIntroduction",
title: "企业简介",
type: "editor"
},
],
// 表单验证规则
rules: {
logo: [{
required: true,
message: "Logo不能为空",
trigger: ['blur', 'change']
}],
personName: [{
required: true,
message: "姓名不能为空",
trigger: ['blur', 'change']
}],
position: [{
required: true,
message: "职位不能为空",
trigger: ['blur', 'change']
}],
address: [{
required: true,
message: "地区不能为空",
trigger: ['blur', 'change']
}],
addressDetail: [{
required: true,
message: "详细地址不能为空",
trigger: ['blur', 'change']
}],
email: [{
required: true,
message: "邮箱不能为空",
trigger: ['blur', 'change']
}],
// website: [{
// required: true,
// message: "logo不能为空",
// trigger: ['blur', 'change']
// }],
mainBusiness: [{
required: true,
message: "主营业务不能为空",
trigger: ['blur', 'change']
}],
mainSpotCategoryIds: [{
required: true,
message: "主营商品不能为空",
trigger: ['blur', 'change']
}],
companyIntroduction: [{
required: true,
message: "企业简介不能为空",
trigger: ['blur', 'change']
}],
},
// add 代表添加 update 代表修改
formType: "update",
// 表单是否在请求中
loading: false,
// 是否显示表单1 的弹窗
show: false,
beforeAction: (formData) => {
vk.userCenter.updateUser({
data: {
businessCard: formData
},
success: (data) => {
// 成功后的逻辑
this.$message({
type: 'success',
message: '保存成功'
})
}
});
return false;
},
}
},
// 表单相关结束-----------------------------------------------------------
}
},
created() {
this.getUserInfo()
},
methods: {
getUserInfo() {
vk.userCenter.getCurrentUserInfo({
success: (data) => {
if(data.userInfo.businessCard) {
this.form1.data = data.userInfo.businessCard
}
// 成功后的逻辑
console.log('用户信息: ', data);
}
});
},
}
}
</script>
<style>
</style>
+309
View File
@@ -0,0 +1,309 @@
<template>
<view>
<el-card>
<div slot="header" class="clearfix">
<span v-if="vk.getVuex('$user.userInfo.accountType') === 1">个人认证</span>
<span v-if="vk.getVuex('$user.userInfo.accountType') === 2">企业认证</span>
</div>
<vk-data-form ref="form1" v-model="form1.data" :action="form1.props.action" :columns="form1.props.columns" :footer-show="false"
:before-action="form1.props.beforeAction" :rules="form1.props.rules" :form-type="form1.props.formType"
:loading.sync="form1.props.loading" :auto-close="true" label-width="140px" @success="onFormSuccess1">
<template v-slot:fadadaConfirm="{ form, keyName }">
<view style="display: flex;">
<el-tag type="primary" v-if="form[keyName]">已认证</el-tag>
<el-tag type="info" v-if="!form[keyName]">未认证</el-tag>
<view style="margin-left: 10px;" class="">
<el-button v-if="!form[keyName]" @click="getCertUrl" type="text"
size="small">去认证</el-button>
</view>
</view>
</template>
</vk-data-form>
</el-card>
</view>
</template>
<script>
var _ = require('lodash');
export default {
data() {
// 页面数据变量
return {
// 表单相关开始-----------------------------------------------------------
form1: {
// 表单请求数据,此处可以设置默认值
data: {
person: {},
company: {},
manager: {},
fadadaConfirm: false
},
// 表单属性
props: {
// 表单请求地址
action: "user/kh/setCertification",
// 表单字段显示规则
columns: [
{
key: "fadadaConfirm",
title: "认证状态",
type: "text",
},
{
key: "person",
title: "个人",
type: "object",
showLabel: false,
showRule: (formData) => {
return formData.person.personName != null
},
columns: [{
key: "personName",
title: "姓名",
type: "text",
readonly: true,
disabled: true
},
{
key: "idCard",
title: "身份证号",
type: "text",
readonly: true,
disabled: true
},
{
key: "mobile",
title: "电话",
type: "text",
readonly: true,
disabled: true
},
]
},
{
key: "company",
title: "企业信息",
type: "object",
showLabel: false,
showRule: (formData) => {
return formData.company.companyName != null
},
columns: [{
key: "companyName",
title: "企业名称",
type: "text",
readonly: true,
disabled: true
},
{
key: "organization",
title: "统一社会信用代码",
type: "text",
readonly: true,
disabled: true
},
{
key: "legalName",
title: "法人",
type: "text",
readonly: true,
disabled: true
},
{
key: "legalMobile",
title: "法人电话",
type: "text",
readonly: true,
disabled: true
},
]
},
{
key: "manager",
title: "代理人",
type: "object",
showLabel: false,
showRule: (formData) => {
return formData.manager.personName != null
},
columns: [{
key: "personName",
title: "代理人",
type: "text",
readonly: true,
disabled: true
},
{
key: "idCard",
title: "代理人身份证号",
type: "text",
readonly: true,
disabled: true
},
{
key: "mobile",
title: "代理人电话",
type: "text",
readonly: true,
disabled: true
},
]
},
// {
// key: "bankCardNo",
// title: "银行卡号",
// type: "text",
// disabled: true,
// // tips: `请用个人账户向以下账户转账0.10元。请备注:账号认证,平台将7个工作日内退回原账户。\r\n,
// // 户名:金久信开户行:中国广发银行南宁支行账号:622252 20151145678XX'`
// },
// {
// key: "mailAddress",
// title: "有效通讯地址",
// type: "text"
// },
// {
// key: "contactQq",
// title: "QQ号码",
// type: "text",
// },
// {
// key: "contactEmail",
// title: "邮箱",
// type: "text",
// },
// {
// key: "",
// title: "",
// type: "group",
// justify: "start",
// columns: [{
// key: "contactWechatImage",
// title: "微信二维码",
// type: "image",
// limit: 1
// },
// {
// key: "contactWechat",
// title: "微信号",
// type: "text",
// },
// ]
// },
// {
// key: "bank_name",
// title: "开户行",
// type: "text",
// },
// {
// key: "bank_account_name",
// title: "户名",
// type: "text",
// },
],
// 表单验证规则
rules: {
mailAddress: [{
required: true,
message: "通讯地址不能为空",
trigger: ['blur', 'change']
}],
contactQq: [{
required: true,
message: "QQ号码不能为空",
trigger: ['blur', 'change']
}],
contactWechat: [{
required: true,
message: "微信不能为空",
trigger: ['blur', 'change']
}],
contactWechatImage: [{
required: true,
message: "微信二维码不能为空",
trigger: ['blur', 'change']
}],
contactEmail: [{
required: true,
message: "邮箱不能为空",
trigger: ['blur', 'change']
}, {
validator: vk.pubfn.validator("email"),
message: '邮箱格式错误',
trigger: 'blur'
}],
},
// add 代表添加 update 代表修改
formType: "",
// 表单是否在请求中
loading: false,
// 是否显示表单1 的弹窗
show: false,
beforeAction: (formData) => {
const newFormData = _.pick(formData, ['contactWechat', 'contactEmail',
'contactWechatImage', 'contactQq', 'mailAddress'
])
vk.userCenter.updateUser({
data: newFormData,
success: (data) => {
// 成功后的逻辑
}
});
return false;
},
}
},
// 表单相关结束-----------------------------------------------------------
};
},
created() {
this.getUserInfo()
},
methods: {
getUserInfo() {
vk.userCenter.getCurrentUserInfo({
success: (data) => {
this.form1.data = _.pick(data.userInfo, [
'fadadaConfirm', 'person', 'company', 'manager', 'contactWechat',
'contactEmail', 'contactWechatImage', 'contactQq', 'mailAddress'
])
// 成功后的逻辑
console.log('data: ', data);
}
});
},
onFormSuccess1() {
console.log(123);
},
getCertUrl() {
vk.callFunction({
url: 'client/fadada.getVerifyUrl',
success: (res) => {
location.href = res.data.url
}
});
}
}
}
</script>
<style scoped>
</style>
+61
View File
@@ -0,0 +1,61 @@
<template>
<view>
<top-bar></top-bar>
<common-header></common-header>
<category-bar></category-bar>
<view class="w-1200">
<el-row :gutter="20">
<el-col :span="6">
<el-menu @select="menuSelect" default-active="fadada" class="el-menu-vertical-demo">
<el-menu-item index="fadada">
<i class="el-icon-menu"></i>
<span slot="title">实名认证</span>
</el-menu-item>
<el-menu-item index="business-card">
<i class="el-icon-setting"></i>
<span slot="title">我的名片</span>
</el-menu-item>
</el-menu>
</el-col>
<el-col :span="18">
<personal v-if="currMenu == 'fadada'"></personal>
<business-card v-else-if="currMenu == 'business-card'"></business-card>
</el-col>
</el-row>
</view>
</view>
</template>
<script>
import Personal from './components/personal'
import BusinessCard from './components/business-card'
export default {
components: {Personal, BusinessCard},
data() {
return {
currMenu: 'business-card',
// currMenu: 'fadada',
};
},
onLoad(options) {
console.log(options);
if(options && options.menu) {
this.currMenu = options.menu
}
},
methods: {
menuSelect(e) {
this.currMenu = e
}
}
}
</script>
<style lang="scss">
.w-1200 {
width: 1200px;
margin: 20px auto;
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+133
View File
@@ -0,0 +1,133 @@
// 定义不需要永久存储的目录,即下次APP启动数据会自动清空,值为在modules目录下的文件名
let notSaveStateKeys = ['$error'];
/* 以下代码请勿改动,除非你知道改动带来的效果 */
const modulesTemp = {};
let lifeData = uni.getStorageSync('lifeData') || {};
// #ifdef VUE2
const modulesFiles = require.context('./modules', true, /\.js$/);
modulesFiles.keys().map((modulePath, index) => {
let moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
modulesTemp[moduleName] = modulesFiles(modulePath).default;
});
// #endif
// #ifdef VUE3
const modulesFiles = import.meta.globEager('./modules/**/*.js');
for (const modulePath in modulesFiles) {
const moduleName = modulePath.replace(/^\.\/modules\/(.*)\.\w+$/, '$1')
modulesTemp[moduleName] = modulesFiles[modulePath].default;
}
// #endif
const modules = {};
for (let moduleName in modulesTemp) {
const moduleItem = modulesTemp[moduleName];
if (moduleItem && moduleItem.namespaced) {
let moduleNameArr = moduleName.split("/");
let lastName = moduleNameArr[moduleNameArr.length - 1];
if (lastName === "index") {
moduleName = moduleName.replace(/\/index$/, '');
}
modules[moduleName] = moduleItem;
}
}
for (let moduleName in modules) {
if (notSaveStateKeys.indexOf(moduleName) === -1) {
if (!lifeData[moduleName]) lifeData[moduleName] = {};
}
}
uni.setStorageSync('lifeData', lifeData);
// 保存变量到本地存储中
const saveLifeData = function(key, value) {
// 判断变量名是否在需要存储的数组中
if (notSaveStateKeys.indexOf(key) === -1) {
// 获取本地存储的lifeData对象,将变量添加到对象中
let tmp = uni.getStorageSync('lifeData');
// 第一次打开APP,不存在lifeData变量,故放一个{}空对象
tmp = tmp ? tmp : {};
tmp[key] = value;
// 执行这一步后,所有需要存储的变量,都挂载在本地的lifeData对象中
uni.setStorageSync('lifeData', tmp);
}
}
// #ifndef VUE3
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
modules,
// 如果是开发环境,则开启严格模式
strict: process.env.NODE_ENV === 'development',
// 公共 mutations
mutations: {
updateStore(state, payload) {
// 判断是否多层级调用,state中为对象存在的情况,诸如user.info.score = 1
if (typeof payload.value === "undefined") payload.value = "";
let nameArr = payload.name.split('.');
let saveKey = '';
let len = nameArr.length;
if (len >= 2) {
let obj = state[nameArr[0]];
for (let i = 1; i < len - 1; i++) {
let keyName = nameArr[i];
if (typeof obj[keyName] !== "object") obj[keyName] = {};
obj = obj[keyName];
}
obj[nameArr[len - 1]] = JSON.parse(JSON.stringify(payload.value));
saveKey = nameArr[0];
} else {
// 单层级变量,在state就是一个普通变量的情况
state[payload.name] = JSON.parse(JSON.stringify(payload.value));
saveKey = payload.name;
}
// 保存变量到本地,见顶部函数定义
saveLifeData(saveKey, state[saveKey])
}
}
})
// #endif
// #ifdef VUE3
import { createStore } from 'vuex'
const store = createStore({
modules,
// 如果是开发环境,则开启严格模式
strict: process.env.NODE_ENV === 'development',
// 公共 mutations
mutations: {
updateStore(state, payload) {
// 判断是否多层级调用,state中为对象存在的情况,诸如user.info.score = 1
if (typeof payload.value === "undefined") payload.value = "";
let nameArr = payload.name.split('.');
let saveKey = '';
let len = nameArr.length;
if (len >= 2) {
let obj = state[nameArr[0]];
for (let i = 1; i < len - 1; i++) {
let keyName = nameArr[i];
if (typeof obj[keyName] !== "object") obj[keyName] = {};
obj = obj[keyName];
}
obj[nameArr[len - 1]] = JSON.parse(JSON.stringify(payload.value));
saveKey = nameArr[0];
} else {
// 单层级变量,在state就是一个普通变量的情况
state[payload.name] = JSON.parse(JSON.stringify(payload.value));
saveKey = payload.name;
}
// 保存变量到本地,见顶部函数定义
saveLifeData(saveKey, state[saveKey])
}
}
})
// #endif
export default store
+60
View File
@@ -0,0 +1,60 @@
/**
* vuex 系统状态管理模块
*/
import config from '@/app.config.js'
let lifeData = uni.getStorageSync('lifeData') || {};
let $app = lifeData.$app || {};
export default {
// 通过添加 namespaced: true 的方式使其成为带命名空间的模块
namespaced: true,
/**
* vuex的基本数据,用来存储变量
*/
state: {
/**
* 是否已经初始化
* js调用示例
* vk.getVuex('$app.inited');
* 页面上直接使用示例
* {{ vk.getVuex('$app.inited') }}
* js更新示例
* vk.setVuex('$app.inited', true);
*/
inited: $app.inited || false,
config:{
...config
},
// 动态主题色 vk.getVuex('$app.color.main') vk.setVuex('$app.color.main','#ff4444')
color: $app.color || config.color,
/**
* vk.getVuex('$app.originalPage');
* vk.setVuex('$app.originalPage', originalPage);
*/
originalPage: $app.originalPage || null, // 跳登录前的页面
},
/**
* 从基本数据(state)派生的数据,相当于state的计算属性
*/
getters: {
},
/**
* 提交更新数据的方法,必须是同步的(如果需要异步使用action)。
* 每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
* 回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
*/
mutations: {
},
/**
* 和mutation的功能大致相同,不同之处在于 ==》
* 1. Action 提交的是 mutation,而不是直接变更状态。
* 2. Action 可以包含任意异步操作。
*/
actions: {
}
}
+50
View File
@@ -0,0 +1,50 @@
/**
* vuex 用户状态管理模块
*/
let lifeData = uni.getStorageSync('lifeData') || {};
let $user = lifeData.$user || {};
export default {
// 通过添加 namespaced: true 的方式使其成为带命名空间的模块
namespaced: true,
/**
* vuex的基本数据,用来存储变量
*/
state: {
/**
* 登录用户信息
* js调用示例
* (推荐) vk.getVuex('$user.userInfo');
* 或 vk.vuex.get('$user.userInfo');
* 页面上直接使用示例
* {{ vk.getVuex('$user.userInfo') }}
* js更新示例
* vk.setVuex('$user.userInfo.avatar', avatar);
*/
userInfo: $user.userInfo || {},
permission:$user.permission || [],
},
/**
* 从基本数据(state)派生的数据,相当于state的计算属性
*/
getters: {
},
/**
* 提交更新数据的方法,必须是同步的(如果需要异步使用action)。
* 每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
* 回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
*/
mutations: {
},
/**
* 和mutation的功能大致相同,不同之处在于 ==》
* 1. Action 提交的是 mutation,而不是直接变更状态。
* 2. Action 可以包含任意异步操作。
*/
actions: {
}
}
+32
View File
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
<!-- 配置H5的 web图标static/logo.png -->
<link rel="icon" href="<%= BASE_URL %>static/logo.png">
</head>
<body>
<!-- 该文件为 H5 平台的模板 HTML,并非应用入口。 -->
<!-- 请勿在此文件编写页面代码或直接运行此文件。 -->
<!-- 详见文档:https://uniapp.dcloud.io/collocation/manifest?id=h5-template -->
<noscript>
<strong>Please enable JavaScript to continue.</strong>
</noscript>
<div id="app"></div>
<script>
</script>
</body>
</html>
+2
View File
@@ -0,0 +1,2 @@
@import "@/common/css/uni.scss";
// @import "@/uni_modules/vk-uview-ui/theme.scss";
@@ -0,0 +1,23 @@
'use strict';
const querystring = require('querystring');
exports.main = async (event, context) => {
//event为客户端上传的参数
console.log('event : ', event)
const {
body
} = event
let obj = querystring.parse(body);
// 验证签名
// Base64(SHA1(app_id +MD5(timestamp)+SHA1(app_secret+authenticationType+certStatus+customerId+serialNo+status+statusDesc)))
let callFunctionRes = await uniCloud.callFunction({
name: "router",
data: {
$url: "client/fadada.pub_verifyNotify",
data: obj
}
});
return callFunctionRes
};
@@ -0,0 +1,7 @@
{
"name": "fadada_verify_notify",
"dependencies": {},
"extensions": {
"uni-cloud-jql": {}
}
}
@@ -0,0 +1,12 @@
const requireFn = function(path) {
return require(path);
}
const initConfig = {
baseDir: __dirname, // 云函数根目录地址
requireFn,
customUtil :{
// 你自己的工具包,写这里后即可听过customUtil.mynpm1调用
// mynpm1:mynpm1
}
};
module.exports = initConfig;
@@ -0,0 +1,7 @@
'use strict';
// 涉及的表名
const dbName = {
productCategory: "jjx-product-category", //商品-分类表
product: "jjx-product", //商品-现货表
};
module.exports = dbName;
@@ -0,0 +1,29 @@
// 加载模块 - 数据库dao层 API 请勿改动此文件-----------------------------------
const modulesPath = __dirname + "/modules";
const fs = require('fs');
const fileList = fs.readdirSync(modulesPath);
const moduleObj = {};
const modulesNames = [];
fileList.map((file, index) => {
if (file.indexOf("Dao.js") > -1) {
modulesNames.push(file.substring(0, file.length - 3));
}
});
modulesNames.map((modulesName, index) => {
try {
moduleObj[modulesName] = require(modulesPath + "/" + modulesName);
} catch (err) {
console.error(`【异常】加载【${modulesName}】异常,请检查!↓↓↓请查看下方的错误提示↓↓↓`);
console.error(err);
console.error(`【异常】加载【${modulesName}】异常,请检查!↑↑↑请查看上方的错误提示↑↑↑`);
}
});
moduleObj.init = function(obj) {
modulesNames.map((modulesName, index) => {
if (typeof moduleObj[modulesName] === "object" && typeof moduleObj[modulesName].init === "function") {
moduleObj[modulesName].init(obj);
}
});
}
module.exports = moduleObj;
// 加载模块 - 数据库dao层 API 请勿改动此文件-----------------------------------
@@ -0,0 +1,621 @@
// 涉及的表名
const dbName = {
user: "uni-id-users", // 用户
};
var dao = {};
var util = {};
// 初始化
dao.init = function(obj) {
util = obj;
}
/**
* 获取用户信息
* 调用示例
* await vk.daoCenter.userDao.findById(user_id);
* data 请求参数说明
* @param {String} user_id 用户ID
*/
dao.findById = async (user_id) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.findById({
dbName: dbName.user,
id: user_id,
fieldJson: { token: false, password: false },
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 查 - 根据whereJson获取单条记录
* @param {Object} whereJson 条件
* @param {Object} fieldJson 字段显示规则
* 调用示例
let userInfo = await vk.daoCenter.userDao.findByWhereJson({
});
*/
dao.findByWhereJson = async (whereJson, fieldJson={ token: false, password: false }) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.findByWhereJson({
dbName: dbName.user,
whereJson,
fieldJson
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 根据邀请码获取用户信息
* let inviterUserInfo = await vk.daoCenter.userDao.findByInviteCode(invite_code);
* @param {String} invite_code 邀请码
*/
dao.findByInviteCode = async (invite_code) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.findByWhereJson({
dbName: dbName.user,
whereJson: {
my_invite_code: invite_code
},
fieldJson: { token: false, password: false }
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 增 - 添加一条记录
* @param {Object} dataJson 添加的数据
* 调用示例
await vk.daoCenter.userDao.add({
});
或
* 调用示例
await vk.daoCenter.userDao.add({
db: transaction,
dataJson: {
}
});
*/
dao.add = async (obj) => {
let { vk, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
if (obj.db && obj.dataJson) {
// 支持事务
res = await vk.baseDao.add({
...obj,
cancelAddTime: true, // 因为user表使用了register_date作为创建时间
dbName: dbName.user,
});
} else {
// 不支持事务
res = await vk.baseDao.add({
dbName: dbName.user,
cancelAddTime: true, // 因为user表使用了register_date作为创建时间
dataJson: obj
});
}
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 增 - 添加多条记录
* @param {Object} dataJson 添加的数据
* 调用示例
await vk.daoCenter.userDao.adds(dataArr);
*/
dao.adds = async (dataArr) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.adds({
dbName: dbName.user,
cancelAddTime: true, // 因为user表使用了register_date作为创建时间
dataJson: dataArr
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 删 - 删除多条记录
* @param {Object} whereJson 条件
* 调用示例
await vk.daoCenter.userDao.del({
});
*/
dao.del = async (whereJson) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.del({
dbName: dbName.user,
whereJson
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 删 - 据ID删除单条数据
* @param {String} _id
* 调用示例
await vk.daoCenter.userDao.deleteById(_id);
或
await vk.daoCenter.userDao.deleteById(_id, transaction);
*/
dao.deleteById = async (_id, db) => {
let { vk, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.deleteById({
db,
dbName: dbName.user,
id: _id
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 改 - 批量修改
* @param {Object} whereJson 条件
* @param {Object} dataJson 修改的数据
* 调用示例
await vk.daoCenter.userDao.update({
whereJson:{
},
dataJson:{
}
});
*/
dao.update = async (obj = {}) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.update({
...obj,
dbName: dbName.user
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 改 - 根据id修改
* @param {Object} whereJson 条件
* @param {Object} dataJson 修改的数据
* 调用示例
await vk.daoCenter.userDao.updateById({
id: uid,
dataJson:{
}
});
*/
dao.updateById = async (obj = {}) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.updateById({
...obj,
dbName: dbName.user
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 改 - 更新并返回更新后的数据(无论条件匹配到多少条记录,只会修改第一条记录,同时返回修改后的数据)
* @param {Object} whereJson 条件
* @param {Object} dataJson 修改的数据
* 调用示例
await vk.daoCenter.userDao.updateAndReturn({
whereJson:{
},
dataJson:{
}
});
*/
dao.updateAndReturn = async (obj = {}) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.updateAndReturn({
...obj,
dbName: dbName.user
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 查 - 获取记录总条数
* @param {Object} whereJson 条件
* 调用示例
await vk.daoCenter.userDao.count(whereJson);
*/
dao.count = async (whereJson) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.count({
dbName: dbName.user,
whereJson
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 查 - 求和
* @param {String} fieldName 需要求和的字段名
* @param {Object} whereJson 筛选条件
* 调用示例
let userSum = await vk.daoCenter.userDao.sum({
fieldName: "",
whereJson: {
}
});
*/
dao.sum = async (obj) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.sum({
...obj,
dbName: dbName.user,
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 查 - 求最大值
* @param {String} fieldName 需要求最大值的字段名
* @param {Object} whereJson 筛选条件
* 调用示例
let userMax = await vk.daoCenter.userDao.max({
fieldName: "",
whereJson: {
}
});
*/
dao.max = async (obj) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.max({
...obj,
dbName: dbName.user,
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 查 - 求最小值
* @param {String} fieldName 需要求最小值的字段名
* @param {Object} whereJson 筛选条件
* 调用示例
let userMin = await vk.daoCenter.userDao.min({
fieldName: "",
whereJson: {
}
});
*/
dao.min = async (obj) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.min({
...obj,
dbName: dbName.user,
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 查 - 求最平均值
* @param {String} fieldName 需要求最平均值的字段名
* @param {Object} whereJson 筛选条件
* 调用示例
let userAvg = await vk.daoCenter.userDao.avg({
fieldName: "",
whereJson: {
}
});
*/
dao.avg = async (obj) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.avg({
...obj,
dbName: dbName.user,
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 查 - 获取数据列表
* 调用示例
let userList = await vk.daoCenter.userDao.select({
pageIndex:1,
pageSize:20,
getMain:false,
whereJson:{
},
fieldJson:{},
sortArr:[{ "name":"_id", "type":"desc" }],
});
*/
dao.select = async (obj = {}) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.select({
...obj,
dbName: dbName.user
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 查 - 获取数据列表
* 调用示例
let userList = await vk.daoCenter.userDao.selects({
pageIndex:1,
pageSize:20,
getMain:false,
whereJson:{
},
fieldJson:{},
sortArr:[{ "name":"_id", "type":"desc" }],
// 副表列表
foreignDB:[
{
dbName:"副表表名",
localKey:"主表外键名",
foreignKey:"副表外键名",
as:"副表as字段",
limit:1
}
]
});
*/
dao.selects = async (obj = {}) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.selects({
...obj,
dbName: dbName.user
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 查 - 获取数据列表
* 调用示例
res = await vk.daoCenter.userDao.getTableData({
data
});
*/
dao.getTableData = async (obj = {}) => {
let { vk, db, _ } = util;
let res = {};
// 数据库操作开始-----------------------------------------------------------
res = await vk.baseDao.getTableData({
...obj,
dbName: dbName.user
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 获取用户信息(旧版)
* _id
* username
* mobile
* email
* wx_openid.app-plus
* wx_openid.mp-weixin
* wx_unionid
* ali_openid
* my_invite_code
* 调用示例
await vk.daoCenter.userDao.findByUserInfo({
mobile:mobile
});
* data 请求参数说明
* @param {Object} userInfo 用户信息
*/
dao.findByUserInfo = async (userInfo) => {
let { vk, db, _ } = util;
let res;
// 数据库操作开始-----------------------------------------------------------
let whereJson = {};
let list = [
"_id",
"username",
"mobile",
"email",
"wx_openid.app-plus",
"wx_openid.mp-weixin",
"wx_unionid",
"ali_openid",
"my_invite_code"
];
let orArr = [];
for (let i = 0; i < list.length; i++) {
let keyName = list[i];
let orObj = {};
if (vk.pubfn.isNotNull(userInfo[keyName])) orObj[keyName] = userInfo[keyName];
if (vk.pubfn.isNotNull(orObj)) {
orArr.push(orObj);
}
}
if (orArr.length > 0) {
whereJson = _.or(orArr);
res = await vk.baseDao.findByWhereJson({
dbName: dbName.user,
fieldJson: { token: false, password: false },
whereJson: whereJson
});
}
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 根据ID数组获取用户列表 最多支持500个
* 调用示例
* await vk.daoCenter.userDao.listByIds(userIdArr);
* data 请求参数说明
* @param {Array} userIdArr 用户ID数组
*/
dao.listByIds = async (userIdArr) => {
let { vk, db, _ } = util;
let res = await vk.baseDao.select({
dbName: dbName.user,
pageIndex: 1,
pageSize: 500,
getMain: true,
fieldJson: { token: false, password: false },
whereJson: {
_id: _.in(userIdArr)
},
});
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 根据手机号直接注册账号并登录
* 若手机号已存在,则直接登录
* @param {Object} data 参数
* mobile 手机号 必填
* password 初始密码
* inviteCode 邀请人的邀请码
* myInviteCode 设置当前注册用户自己的邀请码
* needPermission 设置为true时会在checkToken时返回用户权限(permission),建议在管理控制台中使用
* 调用示例
await vk.daoCenter.userDao.registerUserByMobile({
mobile,
});
*/
dao.registerUserByMobile = async (data) => {
let { vk, db, _, uniID } = util;
let res = {};
let {
mobile,
password,
inviteCode,
myInviteCode,
needPermission
} = data;
// 数据库操作开始-----------------------------------------------------------
let code = vk.pubfn.random(6);
// 设置验证码
await uniID.setVerifyCode({
mobile,
code,
expiresIn: 60,
type: "login"
});
// 若手机号不存在,则注册并登录。存在,则直接登录。
res = await uniID.loginBySms({
mobile,
code,
password,
inviteCode,
myInviteCode,
needPermission
});
if (res.uid && vk.pubfn.isNull(res.userInfo)) {
res.userInfo = await vk.daoCenter.userDao.findById(res.uid);
}
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 重置用户密码
* data 请求参数说明
* @param {String} uid 用户ID
* @param {String} password 需要重置的密码
* 调用示例
await vk.daoCenter.userDao.resetPwd({
uid: uid,
password: "123456"
});
*/
dao.resetPwd = async (data) => {
let { vk, db, _, uniID } = util;
let res = {};
let {
uid,
password
} = data;
// 数据库操作开始-----------------------------------------------------------
res = await uniID.resetPwd({ uid, password });
// 数据库操作结束-----------------------------------------------------------
return res;
};
/**
* 获取一个未被使用的6位数分享码
* 调用示例
await vk.daoCenter.userDao.getValidInviteCode();
*/
dao.getValidInviteCode = async (data) => {
let { vk, db, _ } = util;
// 数据库操作开始-----------------------------------------------------------
let inviteCode = await vk.pubfn.randomAsync(6, "23456789ABCDEFGHJKLMNPQRSTUVWXYZ", async (val)=>{
let num = await vk.baseDao.count({
dbName: dbName.user,
whereJson:{
my_invite_code: val
}
}, 10); // 最大重试10次
return num === 0 ? true : false;
});
// 数据库操作结束-----------------------------------------------------------
return inviteCode;
};
module.exports = dao;
@@ -0,0 +1,7 @@
'use strict';
// 注意:此为云函数路由入口文件,请勿修改此文件代码,你自己的云函数逻辑应写在service目录下
const vkCloud = require('vk-unicloud'); // 引入 vk-unicloud
const vk = vkCloud.createInstance(require('./config.js')); // 通过 vkCloud.createInstance 创建 vk 实例
exports.main = async (event, context) => {
return await vk.router({ event, context, vk });
};
@@ -0,0 +1,29 @@
// 加载模块 - 中间件 请勿改动此文件-----------------------------------
const modulesPath = __dirname+"/modules";
const fs = require('fs');
const fileList = fs.readdirSync(modulesPath);
var moduleList = [];
var modulesNames = [];
fileList.map((file, index) => {
if(file.indexOf(".js") > -1){
modulesNames.push(file.substring(0,file.length-3));
}
});
modulesNames.map((modulesName, index) => {
try {
moduleList.push(require(modulesPath+"/"+modulesName));
} catch (err) {
console.error(`【异常】加载中间件【${modulesName}】异常,请检查!↓↓↓请查看下方的错误提示↓↓↓`);
console.error(err);
console.error(`【异常】加载中间件【${modulesName}】异常,请检查!↑↑↑请查看上方的错误提示↑↑↑`);
}
});
var middlewareList = [];
moduleList.map((moduleItem, index) => {
middlewareList = middlewareList.concat(moduleItem);
});
module.exports = middlewareList;
// 加载模块 - 中间件 请勿改动此文件-----------------------------------
@@ -0,0 +1,63 @@
/**
* 添加操作日志
*/
// 需要添加日志的云函数列表
const urlList = [
{ url: "admin/system/user/sys/add", title: "用户添加" },
{ url: "admin/system/user/sys/update", title: "用户修改" },
{ url: "admin/system/user/sys/delete", title: "用户删除" },
{ url: "admin/system/user/sys/batchUpdateStatus", title: "批量修改用户冻结状态" }
];
// 生成regExp规则
let regExp = urlList.map((item, index) => {
return `^${item.url}$`;
});
module.exports = [{
id: "addAdminLog",
// 需要添加操作日志的云函数列表
regExp,
description: "添加admin操作日志",
index: 999, // 确保最后执行即可
mode: "onActionExecuted", // 可选 onActionExecuting onActionExecuted
enable: true, // 通过设置enable=false可以关闭该中间件
main: async function(event, serviceRes) {
let { url, data = {}, uniIdToken, util, filterResponse, originalParam } = event;
let { uniID, config, vk, db, _ } = util;
let { userInfo = {} } = filterResponse;
let res = serviceRes;
try {
// 此处加 try catch 保证即使添加日志环节出错,不影响业务运行。
if (res.code === 0) {
// 只有请求成功的请求才添加日志
let item = vk.pubfn.getListItem(urlList, "url", url);
let title = item && item.title ? item.title : "未分类";
delete data.uid;
// 日志写入数据库
// 获取请求id(只有云端云函数才有请求id,本地运行的云函数无请求id)
let request_id;
if (typeof vk.pubfn.getUniCloudRequestId === "function") {
request_id = vk.pubfn.getUniCloudRequestId();
}
await vk.baseDao.add({
dbName: "opendb-admin-log",
dataJson: {
user_id: userInfo._id,
user_name: userInfo.nickname,
title,
ip: originalParam.context.CLIENTIP,
url: url,
request_param: data,
response: serviceRes,
request_id
}
});
}
} catch (err) {
console.error("添加日志异常", err);
}
return res;
}
}]
@@ -0,0 +1,22 @@
/**
* 自定义过滤器 - 前置
*/
module.exports = [
{
id: "xxxx1",
regExp: "^xxx1/kh", // 正则匹配规则,这个是以^xxx1/kh/开头的云函数会被拦截
description: "这里是你过滤器1号的描述",
index: 310,// 此处必须>300 因为检测用户是否登录的过滤器的index是200(sys是300,因此为了能通用,建议填大于300的值)(越小越先执行)
mode:"onActionExecuting", // 可选 onActionExecuting onActionExecuted
main: async function(event) {
// 这里是拦截规则,可以查数据库,最终code:0 代表通过,其他均为未通过,msg是被拦截的原因
let { data = {}, util } = event;
let { vk } = util;
return {
code: -1,
msg: "被自定义过滤器1号拦截了"
}
}
}
]
@@ -0,0 +1,19 @@
/**
* 自定义过滤器 - 后置
*/
module.exports = [
{
id: "xxxx2",
regExp: "^xxx2/kh", // 正则匹配规则,这个是以^xxx2/kh/开头的云函数会被拦截
description: "这里是你过滤器2号的描述",
index: 310,// 此处必须>300 因为检测用户是否登录的过滤器的index是200(sys是300,因此为了能通用,建议填大于300的值)(越小越先执行)
mode:"onActionExecuted", // 可选 onActionExecuting onActionExecuted
main: async function(event, serviceRes) {
let { data = {}, util } = event;
let { vk } = util;
serviceRes.msg = "被过滤器修改后的值";
return serviceRes;
}
}
]
@@ -0,0 +1,46 @@
/**
* 注册成功后,统一给用户初始化字段值
*/
module.exports = [{
id: "registerInit",
// 符合下方正则条件的云函数才会进入该中间件
regExp: [
"^user/pub/register(.*)",
"^user/pub/login(.*)",
"^admin/system/user/sys/add"
],
description: "注册成功后,统一给用户初始化字段值",
index: 301,
mode: "onActionExecuted", // 可选 onActionExecuting onActionExecuted
enable: true, // 通过设置enable=false可以关闭该中间件
main: async function(event, serviceRes) {
let { data = {}, util, filterResponse, originalParam } = event;
let { vk, config, db, _ } = util;
let res = serviceRes;
// 初始化用户信息(只在用户注册成功时才执行下面的代码)
if (res.code === 0 && res.type === "register" && res.uid) {
let uniIdConfig = vk.pubfn.getUniIdConfig(config); // 获取uniID的配置
// 你要初始化的字段数据
let initData = {
// 这里可以加你想要初始化的其他字段,如 status字段初始化为 0
status: 0, // 用户状态:0 正常 1 禁用 2 审核中 3 审核拒绝
};
// 如果开启了删除dcloud_appid功能,则初始化数据带上 dcloud_appid: _.remove()
if (uniIdConfig.removeDcloudAppid) {
// remove功能是删除该字段(代表关闭隔离不同端用户功能),该用户在其他项目中登录时就不会产生新的账号 详见:https://uniapp.dcloud.io/uniCloud/uni-id.html#isolate-user
initData["dcloud_appid"] = _.remove();
}
// 修改用户信息,并返回修改后的用户信息
res.userInfo = await vk.daoCenter.userDao.updateAndReturn({
whereJson: {
_id: res.uid,
},
dataJson: initData
});
}
return res;
}
}]

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