Browse Source

商城

devlop
mo-bai 4 years ago
parent
commit
39a9d5b733
51 changed files with 4506 additions and 35 deletions
  1. 19
      apis/commonApi.js
  2. 49
      apis/enterpriseInfoApi.js
  3. 16
      apis/forComparisonApi.js
  4. 68
      apis/mallApi.js
  5. 139
      apis/orderApi.js
  6. 37
      apis/paperDetailsApi.js
  7. 95
      components/qn-input-number/qn-input-number.vue
  8. 24
      enums/index.js
  9. 48
      pages.json
  10. 550
      pages/cart/index.vue
  11. 63
      pages/cart/no-data.vue
  12. 5
      pages/device-production-detail/index.vue
  13. 37
      pages/digital-workshops/index.vue
  14. 613
      pages/enterprise-info/index.vue
  15. 617
      pages/for-comparison/index.vue
  16. 283
      pages/mall/index.vue
  17. 505
      pages/order-make/index.vue
  18. 749
      pages/paper-details/index.vue
  19. 2
      pages/production-operation/index.vue
  20. 353
      pages/store/index.vue
  21. BIN
      static/imgs/cart/no-data-icon.png
  22. BIN
      static/imgs/cart/shopping-cart-not-select.png
  23. BIN
      static/imgs/cart/shopping-cart-select.png
  24. BIN
      static/imgs/digital-workshops/.DS_Store
  25. BIN
      static/imgs/digital-workshops/camera-tip-bg.png
  26. BIN
      static/imgs/mall/cart-icon.png
  27. BIN
      static/imgs/mall/top-bg.png
  28. BIN
      static/imgs/order/.DS_Store
  29. BIN
      static/imgs/order/address-icon.png
  30. BIN
      static/imgs/order/camera.png
  31. BIN
      static/imgs/order/customer-default.png
  32. BIN
      static/imgs/order/edit-address-icon.png
  33. BIN
      static/imgs/order/fs-pay-icon.png
  34. BIN
      static/imgs/order/location-icon.png
  35. BIN
      static/imgs/order/month-pay-icon.png
  36. BIN
      static/imgs/order/order-empty.png
  37. BIN
      static/imgs/order/paper-default-icon.png
  38. BIN
      static/imgs/order/right-arrow.png
  39. BIN
      static/imgs/order/select-icon.png
  40. BIN
      static/imgs/order/selected-icon.png
  41. BIN
      static/imgs/order/status-icon.png
  42. BIN
      static/imgs/order/wxpay-icon.png
  43. BIN
      static/imgs/paperDetails/add-shopping-trolley.png
  44. BIN
      static/imgs/paperDetails/shop-icon.png
  45. BIN
      static/imgs/paperDetails/shopping-trolley.png
  46. BIN
      static/imgs/store/address-icon.png
  47. BIN
      static/imgs/store/special-offe.png
  48. BIN
      static/imgs/store/store-icon.png
  49. 24
      store/index.js
  50. 16
      utils/http/index.js
  51. 229
      utils/md5.js

19
apis/commonApi.js

@ -117,6 +117,25 @@ export function transformFileToImg(data) {
})
}
/**
* 获取当前账号企业的飞算额度
* @param {object} data 参数 enterpriseId
*/
export function getFsCredit(data = {}) {
return http.get({
url: '/yyt-uec/credit/get/enterprise-feisuan-credit',
data
})
}
/**
* 获取当前账号企业的被担保的月结额度
* @param {object} data 参数 enterpriseId supplierId
*/
export function getMonthCredit(data = {}) {
return http.get({ url: '/yyt-uec/customer/get/supplier-credit', data })
}
/**
* 推送客户绑定
*

49
apis/enterpriseInfoApi.js

@ -0,0 +1,49 @@
import http from '../utils/http/index.js'
/**
* 完善企业信息
* @param {*} data
* @returns
*/
export function completeInfo(data) {
return http.post({
url: '/yyt-uec/save/my/enterprise',
data
})
}
/**
* 根据名称模糊查询企业列表
* @param {*} data
* @returns
*/
export function getCompanyList(data) {
return http.get({
url: '/base-paper-trading/get/customers/enterprise/basic/list',
data
})
}
/**
* 根据id查询企业详细信息
* @param {*} data
* @returns
*/
export function getCompanyInfoById(data) {
return http.get({
url: '/yyt-uec/get/enterprise-detail',
data
})
}
/**
* 根据企业名称查询企业坐标列表
* @param {*} data
* @returns
*/
export function getCompanyLocationList(data) {
return http.get({
url: '/yyt-uec/get/enterprise/geographic/position/address',
data
})
}

16
apis/forComparisonApi.js

@ -0,0 +1,16 @@
import http from '../utils/http/index.js'
// 提交询价单
export function createEnquiryOrder(data) {
return http.post({
url: '/base-paper-trading/add/enquiry-order',
data
})
}
// 查询纸种列表
export function getCategoryList(data) {
return http.get({
url: '/base-paper-trading/get/enquiry/category-and-brand-list/by-supplierId',
data
})
}

68
apis/mallApi.js

@ -0,0 +1,68 @@
import http from '@/utils/http/index.js'
/**
* 获取店铺列表
*/
export function getStoreList(data = {}) {
return http.get({
url: '/base-paper-trading/search/store/page',
data
})
}
/**
* 获取店铺信息
* @param {object} data 参数
* @returns {Promise<object[]>}
* swagger:http://api-ops-yyt-test.qniao.cn/base-paper-trading/swagger-ui/index.html?urls.primaryName=CustomerApi#/
*/
export const getCustomer = (data = {}) => {
return http.get({
url: '/base-paper-trading/get/store-detail/for/customer',
data
})
}
/**
* 获取店铺纸品列表
* @param {object} data 参数
* @returns {Promise<object[]>}
* swagger: http://api-ops-yyt-test.qniao.cn//base-paper-trading/swagger-ui/index.html?urls.primaryName=CustomerApi#/%E5%95%86%E5%93%81%E7%AE%A1%E7%90%86/getStoreProductListForCustomerUsingGET
*/
export const getPaperList = (data = {}) => {
return http.get({
url: '/base-paper-trading/get/store/product-list/for/customer',
data
})
}
// 获取购物车列表
export function getShoppingCarList(data) {
return http.get(
{
url: '/base-paper-trading/get/shopping-car-list',
data
},
{
hideLoading: true
}
)
}
// 移除购物车
export function removeShoppingCar(data) {
return http.post({
url: '/base-paper-trading/delete/shopping-car',
data
})
}
// 购物车结算
export function closePaperReserve(data) {
return http.post(
{
url: '/base-paper-trading/shopping/trolley/buyer/paper/reserve',
data
},
{
isEncrypt: true
}
)
}

139
apis/orderApi.js

@ -0,0 +1,139 @@
import http from '../utils/http/index.js'
/**
* 获取客户订单列表
* @param {object} data 获取验证码参数
* @returns {Promise<object[]>}
* swagger: http://api-ops-yyt-test.qniao.cn//base-paper-trading/swagger-ui/index.html?urls.primaryName=CustomerApi#/%E5%8E%9F%E7%BA%B8%E8%AE%A2%E5%8D%95/getCustomerOrderListPageUsingGET
*/
export const getOrderList = (data) => {
return http.get({
url: '/base-paper-trading/get/customer/order/list/page',
data
})
}
/**
* 获取待确认订单详情
* @param {object} data customerOrderIduserId
* @returns {Promise<object[]>}
*/
export const getPreOrderInfo = (data) => {
return http.get({
url: '/base-paper-trading/get/customer/to/be/confirmed/order',
data
})
}
/**
* 获取企业默认收货地址
* @param {object} data enterpriseId
* @returns {Promise<object[]>}
*/
export const getDefaultAddress = (data) => {
return http.get({
url: '/uec/get/default-enterprise-shipping-address',
data
})
}
/**
* 确认订单
* @param {object} data
* @returns {Promise<object>}
*/
export const submitClientOrder = (data) => {
return http.post(
{
url: '/base-paper-trading/customer/submit/order',
data
},
{
isEncrypt: true
}
)
}
/**
* 获取客户订单详情
* @param {object} data customerOrderId
* @returns {Promise<object>}
*/
export const getClientOrderInfo = (data) => {
return http.get({
url: '/base-paper-trading/get/customer/order/details',
data
})
}
/**
* 获取客户订单签署是否成功
* @param {object} data orderId
* @returns {Promise<object>}
*/
export const confirmContract = (data) => {
return http.get({
url: '/base-paper-trading/get/customer/signing/contract/status',
data
})
}
/**
* 客户上传收货凭证
* @param {object} data proofDeliveryUrl[] supplierOrderId
* @returns {Promise<Object>}
*/
export function clientUploadVoucher(data) {
return http.post({
url: '/base-paper-trading/customer/submit/upload/proof/receipt',
data
})
}
/**
* 客户删除收货凭证
* @param {object} data id
* @returns {Promise<Object>}
*/
export function clientDeleteVoucher(data) {
return http.post({
url: '/base-paper-trading/delete/certificate/img?id=' + data.id,
data
})
}
/**
* 客户确认收货
* @param {object} data supplierOrderId
* @returns {Promise<Object>}
*/
export function clientConfirmOrder(data) {
return http.post({
url: '/base-paper-trading/customer/submit/confirm/receipt',
data
})
}
/**
* 计算不开票价格
* @param {object} data customerOrderId
* @returns {Promise<Object>}
*/
export function calcNotInvoiceOrderInfo(data) {
return http.get({
url: '/base-paper-trading/get/free/checking/order/calculate',
data
})
}
/**
* 获取供应商收款码
* @param {object} data mallSupplierId
* @returns {Promise<Object>}
*/
export function getReciptCode(data) {
return http.get({
url: '/yyt-uec/get/mall/supplier/payee/code/byId',
data
})
}

37
apis/paperDetailsApi.js

@ -0,0 +1,37 @@
import http from '../utils/http/index.js'
/**
* 获取店铺纸品详情
* @param {object} data 参数
* @returns {Promise<object[]>}
* swagger: http://api-ops-yyt-test.qniao.cn//base-paper-trading/swagger-ui/index.html?urls.primaryName=CustomerApi#/%E5%95%86%E5%93%81%E7%AE%A1%E7%90%86/getProductDetailForCustomerUsingGET
*/
export const getPaperDetail = (data = {}) => {
return http.get({
url: '/base-paper-trading/get/product-detail/for/customer',
data
})
}
/**
* 立即订购
* swagger:https://api-ops-yyt-test.qniao.cn//base-paper-trading/swagger-ui/index.html?urls.primaryName=CustomerApi#/
*/
export const createGoodsReserve = (data = {}) => {
return http.post(
{
url: '/base-paper-trading/buyer/paper/goods/reserve',
data
},
{ isEncrypt: true }
)
}
/**
* 加入购物车
* swaggerhttp://api-ops-yyt-test.qniao.cn/base-paper-trading/swagger-ui/index.html?urls.primaryName=CustomerApi#/%E8%B4%AD%E7%89%A9%E8%BD%A6/addShoppingCarUsingPOST
*/
export const createShoppingCar = (data = {}) => {
return http.post({
url: '/base-paper-trading/add/shopping-car',
data
})
}

95
components/qn-input-number/qn-input-number.vue

@ -0,0 +1,95 @@
<template>
<view class="wrapper">
<view class="minus-box" @tap="minusTap">
<uni-icons size="16" custom-prefix="iconfont" type="icon-Less" color="#007AFF"></uni-icons>
</view>
<view style="padding: 0rpx 4rpx">
<qn-easyinput
:inputBorder="false"
class="quantity-input"
style="height: 64rpx"
:clearable="false"
type="number"
:value="value"
placeholder="请输入"
@blur="blur"
@confirm="confirm"
@input="input"
></qn-easyinput>
</view>
<view class="minus-box" @tap="addTap"><uni-icons size="16" type="plusempty" color="#007AFF"></uni-icons></view>
</view>
</template>
<script>
export default {
props: {
quantity: {
type: [Number, String],
default: 0
}
},
data() {
return {
value: 0
}
},
watch: {
quantity: {
handler(nv, ov) {
this.value = nv
},
immediate: true
}
},
methods: {
input(value) {
this.$emit('input', value)
},
blur(e) {
this.$emit('change', e.detail.value)
},
confirm(value) {
if (value.trim()) {
this.$emit('change', value)
}
},
minusTap() {
if (this.value == 0) {
return
}
this.value--
this.$emit('change', this.value)
},
addTap() {
this.value++
this.$emit('change', this.value)
}
}
}
</script>
<style lang="scss" scoped>
.wrapper {
display: flex;
flex-direction: row;
align-items: center;
.minus-box {
width: 64rpx;
height: 64rpx;
line-height: 64rpx;
text-align: center;
background: #f2f3f5;
border-radius: 8rpx;
color: #007aff;
}
.quantity-input {
width: 120rpx;
height: 64rpx;
background: #f2f3f5;
/deep/ .uni-easyinput__content {
min-height: 64rpx;
}
}
}
</style>

24
enums/index.js

@ -264,3 +264,27 @@ export const invoiceStatusMap = {
[invoiceStatusEnum.INVOICE]: '开票',
[invoiceStatusEnum.NO_INVOICE]: '不开票'
}
/**
* 纸品单位 1: 2:
*/
export const paperUnitEnum = {
PIECE: 1,
TON: 2
}
/**
* 纸品单位map
*/
export const paperUnitMap = {
[paperUnitEnum.PIECE]: '张',
[paperUnitEnum.TON]: '吨'
}
/**
* 加密类型 1:md5加密 2:sha256加密
*/
export const encryptType = {
MD5: 1,
SHA256: 2
}

48
pages.json

@ -75,6 +75,54 @@
"navigationStyle": "custom"
}
},
{
"path": "pages/store/index",
"style": {
"navigationBarTitleText": "店铺首页",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/enterprise-info/index",
"style": {
"navigationBarTitleText": "完善信息",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/for-comparison/index",
"style": {
"navigationBarTitleText": "实单询比价",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/order-make/index",
"style": {
"navigationBarTitleText": "订单确认",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/paper-details/index",
"style": {
"navigationBarTitleText": "纸品详情",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/cart/index",
"style": {
"navigationBarTitleText": "购物车",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/mine/index",
"style": {

550
pages/cart/index.vue

@ -0,0 +1,550 @@
<template>
<view class="wrapper">
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="购物车">
<view slot="right" class="right-title" @tap="delTap">删除</view>
</uni-nav-bar>
<view>
<scroll-list ref="list" :option="option" @load="upCallback" @refresh="downCallback" style="background-color: #ffffff">
<view class="group-box" v-for="(item, index) in list" :key="index">
<view class="group-checkbox">
<view class="checkbox" @tap="checkboxGroupTap(item, index)">
<image
class="select-img"
:src="item.checkedGroup ? '/static/imgs/cart/shopping-cart-select.png' : '/static/imgs/cart/shopping-cart-not-select.png'"
mode=""
></image>
</view>
<view>{{ item.supplierName }}</view>
</view>
<view class="list-box" v-for="(subItem, subIndex) in item.carItemList" :key="subIndex">
<view class="checkbox" @tap="checkboxTap(item, subItem)">
<image
class="select-img"
:src="subItem.checked ? '/static/imgs/cart/shopping-cart-select.png' : '/static/imgs/cart/shopping-cart-not-select.png'"
mode=""
></image>
</view>
<view class="list-row">
<image
class="image"
@tap="seeDetailsTap(subItem)"
:src="subItem.productImg || 'https://qncloud.oss-cn-shenzhen.aliyuncs.com/paper_shopkeeper/paper-default-small.png'"
mode=""
></image>
<view class="right">
<view class="name">{{ subItem.productName }}</view>
<view class="measure">{{ subItem.gramWeight }}g{{ subItem.width }}*{{ subItem.length }} | {{ subItem.quantity }}</view>
<view class="weight">预估重量{{ subItem.weight }}</view>
<view class="price-row">
<view class="value">¥{{ subItem.price }}</view>
<view><qnInputNumber :quantity="subItem.quantity" @input="change($event, subItem)" /></view>
</view>
</view>
</view>
</view>
</view>
<view slot="empty">
<no-data></no-data>
</view>
</scroll-list>
<view class="footer-box">
<view class="row">
<view class="left" @tap="selectAll">
<view>
<image
class="select-img"
:src="allSelected ? '/static/imgs/cart/shopping-cart-select.png' : '/static/imgs/cart/shopping-cart-not-select.png'"
mode=""
></image>
</view>
<view><text class="check-text">全选</text></view>
</view>
<view class="right">
<view>
<text class="name">应付</text>
<text class="value">¥{{ totalPrice }}</text>
</view>
<view class="right-balance-btn" @tap="closeAnAccountTap">结算</view>
</view>
</view>
</view>
</view>
<uni-popup ref="popup" type="center" :mask-click="false">
<view class="popup-box">
<view class="tip-title">{{ onlyQuantity ? '确定将当前纸品删除吗?' : allSelected ? '确定将购物车纸品删除吗?' : '确定将当前纸品删除吗?' }}</view>
<view class="operation-row">
<view class="cancel-text" @tap="cancelTap">{{ onlyQuantity ? '我在想想' : '取消' }}</view>
<view class="line"></view>
<view class="confirm-text" @tap="confirmTap">确定</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import qnFooter from '@/components/qn-footer/qn-footer.vue'
import { go2, back } from '@/utils/hook.js'
import qnInputNumber from '@/components/qn-input-number/qn-input-number.vue'
import { getShoppingCarList, removeShoppingCar, closePaperReserve } from '@/apis/mallApi.js'
import noData from './no-data.vue'
import { round } from '@/utils/index.js'
export default {
components: { qnInputNumber, qnFooter, noData },
data() {
return {
option: {
size: 10,
auto: true,
// height: '90%',
emptyText: '暂无数据~',
background: '#F7F8FA',
disabled: false
},
params: {
// userId: this.$store.state.userInfo.userId || null
},
pagination: {
pageNum: 0, //
pageSize: 10
},
checked: false,
list: [],
idList: [],
onlyQuantity: false
}
},
created() {
let that = this
uni.getSystemInfo({
success: function (res) {
that.option.height = res.windowHeight * (750 / res.windowWidth) - 180
}
})
},
computed: {
allSelected: {
get() {
if (this.list && this.list.length) {
return this.list.every((shop) => {
return shop.checkedGroup
})
}
return false
},
set(val) {
if (this.list && this.list.length) {
this.list.forEach((shop) => {
shop.checkedGroup = val
shop.carItemList.forEach((good) => {
good.checked = val
})
})
}
}
},
totalPrice() {
let num = 0
if (this.list && this.list.length) {
this.list.forEach((shop) => {
shop.carItemList.forEach((good) => {
if (good.checked) {
num += round(good.price * good.weight, 2)
}
})
})
}
return round(num, 2)
}
},
methods: {
go2,
back,
//
closeAnAccountTap() {
let orderGoodsList = []
this.list.forEach((el) => {
el.carItemList.forEach((good) => {
if (good.checked) {
let obj = {
buyTon: good.weight,
gramWeight: good.gramWeight,
length: good.length,
mallSupplierId: el.supplierId,
pieceQuantity: good.quantity,
productId: good.productId,
productSkuId: good.productSkuId,
unitPrice: good.price,
width: good.width
}
orderGoodsList.push(obj)
}
})
})
if (orderGoodsList.length === 0) {
uni.showToast({
title: '暂未选择商品',
icon: 'none'
})
return
}
const params = {
orderGoodsList: orderGoodsList,
purchaserEnterpriseId: this.$store.state.companyInfo.id,
userId: this.$store.state.userInfo.userId
// purchaserEnterpriseId: '677166943471538176',
// userId: '573244119569272832',
}
closePaperReserve(params).then((res) => {
if (res) {
go2('order-make', { orderId: res.orderId })
}
})
},
getList() {
return new Promise((resolve, reject) => {
getShoppingCarList({ ...this.params, ...this.pagination })
.then((res) => {
console.log('购物车', res)
if (res) {
res.records.forEach((el) => {
el.checkedGroup = false
el.carItemList.forEach((item) => {
item.checked = false
})
})
if (res.current == 1) {
this.list = res.records
} else {
this.list = this.list.concat(res.records)
}
resolve({ list: this.list, total: res.total })
}
})
.catch((err) => {
reject(err)
})
})
},
downCallback() {
this.pagination.pageNum = 1
this.getList()
.then(({ list, total }) => {
this.$refs.list.refreshSuccess({ list, total })
})
.catch((e) => {
console.error('e:', e)
this.$refs.list.refreshFail()
})
},
upCallback() {
this.pagination.pageNum++
this.getList()
.then(({ list, total }) => {
this.$refs.list.loadSuccess({ list, total })
})
.catch(() => {
this.$refs.list.loadFail()
})
},
//
checkboxGroupTap(item, index) {
item.checkedGroup = !item.checkedGroup
item.carItemList.forEach((el) => {
el.checked = item.checkedGroup
})
},
/**
* @param {Object} shop
* @param {Object} good 子项
*/
checkboxTap(shop, good) {
good.checked = !good.checked
//
shop.checkedGroup = this.isShopSelectedAll(shop.carItemList)
},
//
isShopSelectedAll(products) {
let tempArr = true
for (let product of products) {
if (product.checked) {
tempArr = false
break
}
}
return tempArr
},
//
selectAll() {
this.allSelected = !this.allSelected
},
delTap() {
// idList
this.idList = []
let quantity = 0
this.list.forEach((el) => {
el.carItemList.forEach((good) => {
if (good.checked) {
quantity = good.quantity
this.idList.push(good.id)
}
})
})
if (this.idList.length === 0) {
uni.showToast({
title: '暂未选择商品',
icon: 'none'
})
return
}
// 0
if (this.idList.length == 1 && quantity == 0) {
this.onlyQuantity = true
} else {
this.onlyQuantity = false
}
this.$refs.popup.open('center')
},
confirmTap() {
const params = {
idList: this.idList,
userId: this.$store.state.userInfo.userId
}
removeShoppingCar(params).then((res) => {
this.$refs.popup.close()
if (res) {
uni.showToast({
title: '删除成功!',
icon: 'success'
})
this.downCallback()
}
})
},
cancelTap() {
this.$refs.popup.close()
},
/**
* @param {Number} num
* 计数器返回值
*/
change(num, good) {
good.quantity = num
good.weight = round(good.gramWeight * good.width * good.length * good.quantity * 1e-12, 4)
}
}
}
</script>
<style lang="scss">
.wrapper {
.left-title {
font-size: 40rpx;
color: #000000;
letter-spacing: 0;
font-weight: 500;
}
.right-title {
font-size: 28rpx;
color: #f5222d;
text-align: right;
font-weight: 500;
float: right;
}
.group-box {
// padding: 0rpx 32rpx;
.group-checkbox {
margin-top: 20rpx;
display: flex;
flex-direction: row;
align-items: center;
height: 88rpx;
background: #ffffff;
padding: 0rpx 32rpx;
}
}
.select-img {
width: 32rpx;
height: 32rpx;
}
.checkbox {
flex: 0 0 35rpx;
margin-right: 20rpx;
}
.list-box {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
border-top: 2rpx solid rgba(221, 221, 221, 0.5);
padding: 28rpx 32rpx 40rpx 32rpx;
.list-row {
flex: 1;
display: flex;
flex-direction: row;
.image {
flex: 0 0 180rpx;
width: 180rpx;
height: 180rpx;
border-radius: 8px;
margin-right: 16rpx;
}
.right {
flex: 1;
width: 100%;
}
.name {
font-size: 34rpx;
color: #333333;
letter-spacing: 0;
text-align: left;
font-weight: 600;
padding-top: 10rpx;
}
.measure {
font-size: 24rpx;
color: #333333;
letter-spacing: 0;
text-align: left;
font-weight: 500;
margin-top: 16rpx;
}
.weight {
text-align: center;
font-size: 24rpx;
color: #888888;
font-weight: 400;
text-align: right;
padding-top: 8rpx;
}
.price-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding-top: 12rpx;
.value {
font-size: 30rpx;
color: #f5222d;
letter-spacing: 0;
text-align: left;
font-weight: 500;
}
}
}
}
.footer-box {
.check-text {
font-size: 24rpx;
color: #333333;
letter-spacing: 0;
text-align: center;
font-weight: 400;
padding-left: 12rpx;
vertical-align: middle;
}
.row {
display: flex;
flex-direction: row;
align-items: center;
height: 96rpx;
background: #ffffff;
padding: 0rpx 32rpx;
.left {
flex: 0 0 200rpx;
display: flex;
flex-direction: row;
// align-items: center;
}
.right {
// flex: 1;
flex-shrink: 1;
flex-grow: 1;
// width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
.name {
font-size: 28rpx;
color: rgba(0, 0, 0, 0.85);
text-align: right;
font-weight: 400;
}
.value {
vertical-align: middle;
font-size: 36rpx;
color: #f5222d;
letter-spacing: 0;
text-align: left;
font-weight: 500;
}
}
.right-balance-btn {
width: 201rpx;
height: 76rpx;
line-height: 76rpx;
background: #007aff;
border-radius: 38rpx;
font-size: 32rpx;
color: #ffffff;
letter-spacing: 0;
text-align: center;
font-weight: 400;
}
}
}
.popup-box {
width: 540rpx;
height: 226rpx;
background: #ffffff;
border-radius: 14rpx;
.tip-title {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
height: 126rpx;
font-size: 32rpx;
color: #333333;
letter-spacing: 0;
text-align: center;
font-weight: 400;
}
.operation-row {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 100rpx;
background: #ffffff;
border-top: 2rpx solid rgba(221, 221, 221, 0.5);
.cancel-text {
flex-grow: 1;
flex-shrink: 1;
font-size: 36rpx;
color: #000000;
letter-spacing: 0;
text-align: center;
font-weight: 400;
}
.line {
flex-grow: 0;
flex-shrink: 0;
width: 2rpx;
height: 100rpx;
border-left: 2rpx solid #dcdee3;
}
.confirm-text {
flex-grow: 1;
flex-shrink: 1;
font-size: 36rpx;
color: #108ee9;
letter-spacing: 0;
text-align: center;
font-weight: 400;
}
}
}
}
</style>

63
pages/cart/no-data.vue

@ -0,0 +1,63 @@
<template>
<view class="wrapper">
<image class="icon" src="/static/imgs/cart/no-data-icon.png"></image>
<view class="text-row">
<view>购物车是空的快去</view>
<view class="btn" @tap="nativeTo">逛逛</view>
</view>
</view>
</template>
<script>
import { go2 } from '@/utils/hook.js'
export default {
props: {
title: {
type: String,
default: null
}
},
data() {
return {}
},
methods: {
//
nativeTo() {
go2('store')
}
}
}
</script>
<style lang="scss">
.wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
vertical-align: bottom;
text-align: center;
margin-top: 25%;
.icon {
width: 560rpx;
height: 320rpx;
}
.text-row {
display: flex;
flex-direction: row;
font-size: 30rpx;
color: #333333;
letter-spacing: 0;
text-align: center;
font-weight: 400;
}
.btn {
font-size: 32rpx;
color: #007aff;
letter-spacing: 0;
text-align: center;
font-weight: 400;
text-decoration: underline;
}
}
</style>

5
pages/device-production-detail/index.vue

@ -8,7 +8,7 @@
<view class="justify-between group_6">
<text class="text_5">生产数据</text>
<view class="flex-row group_7">
<qn-datetime-picker :border="false" type="daterange" @change="dateRangeChange">
<qn-datetime-picker :end="maxTimestamp" :border="false" type="daterange" @change="dateRangeChange">
<text>{{ (dateRange ? `${dateRange[0]}${dateRange[1]}` : '全部') | formatDate }}</text>
</qn-datetime-picker>
<image v-show="!dateRange" src="/static/imgs/digital-workshops/down-arrow-icon.png" class="image-icon" />
@ -107,7 +107,8 @@ export default {
dateRange: null,
deviceList: [],
password: '',
hasPassword: true
hasPassword: true,
maxTimestamp: new Date().getTime()
}
},
onLoad(options) {

37
pages/digital-workshops/index.vue

@ -22,7 +22,7 @@
</view>
</view>
<view class="flex-row group_9">
<qn-datetime-picker :border="false" type="daterange" @change="dateRangeChange">
<qn-datetime-picker :end="maxTimestamp" :border="false" type="daterange" @change="dateRangeChange">
<text>{{ dateRange ? `${dateRange[0]}${dateRange[1]}` : '全部' }}</text>
</qn-datetime-picker>
<image v-show="!dateRange" src="/static/imgs/digital-workshops/down-arrow-icon.png" class="image_4" />
@ -78,18 +78,32 @@
<view class="grid-item flex-col" v-for="device in deviceList" :key="device.id" @click="go2('device-production-detail', { id: device.id })">
<view class="flex-row">
<text class="text_24">{{ device.name }}</text>
<view class="column flex-col items-center" :class="`right-text-wrapper${device.workingStatus == deviceStatus.WORKING ? '__active' : ''}`">
<view
v-if="device.cloudBoxId"
class="column flex-col items-center"
:class="`right-text-wrapper${device.workingStatus == deviceStatus.WORKING ? '__active' : ''}`"
>
<text>{{ device.workingStatus == deviceStatus.WORKING ? '工作中' : '空闲中' }}</text>
</view>
</view>
<image :src="device.cameraId ? '' : '/static/imgs/digital-workshops/no-camera.png'" class="image_6" />
<view class="bottom-group justify-between">
<text>产量</text>
<text>{{ device.produceTotalNum || 0 }}</text>
<image
:src="device.cameraId ? '/static/imgs/digital-workshops/camera-tip-bg.png' : '/static/imgs/digital-workshops/no-camera.png'"
class="image_6"
/>
<view v-if="device.cloudBoxId">
<view class="bottom-group justify-between">
<text>产量</text>
<text>{{ device.produceTotalNum || 0 }}</text>
</view>
<view class="bottom-group justify-between">
<text>时长</text>
<text>{{ device.totalWorkHour | formatNumber }}h</text>
</view>
</view>
<view class="bottom-group justify-between">
<text>时长</text>
<text>{{ device.totalWorkHour | formatNumber }}h</text>
<view v-else>
<view class="bottom-group justify-between">
<text>未安装云盒</text>
</view>
</view>
</view>
</view>
@ -133,7 +147,8 @@ export default {
fontSize: '40rpx'
},
deviceStatus: Object.freeze(deviceStatus),
curTab: 0
curTab: 0,
maxTimestamp: new Date().getTime()
}
},
computed: {
@ -540,6 +555,8 @@ export default {
border-bottom: solid 2rpx rgba(151, 151, 151, 0.4);
.text_28 {
width: 220rpx;
overflow: hidden;
text-overflow: ellipsis;
color: rgb(31, 31, 31);
font-size: 28rpx;
line-height: 40rpx;

613
pages/enterprise-info/index.vue

@ -0,0 +1,613 @@
<template>
<view class="content">
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="完善信息">
<text @click="jump" v-if="operation === 'add'" style="color: #007aff" slot="right">跳过</text>
</uni-nav-bar>
<view>
<qn-form-item label="基础信息" type="title"></qn-form-item>
<qn-form-item label="企业名称" required>
<qn-easyinput :maxlength="20" @blur="showCompany" v-model="form.name" :inputBorder="false" text="right" placeholder="请输入企业名称"></qn-easyinput>
</qn-form-item>
<qn-form-item label="企业简称">
<qn-easyinput :maxlength="20" v-model="form.shortName" :inputBorder="false" text="right" placeholder="请输入企业简称"></qn-easyinput>
</qn-form-item>
<qn-form-item label="联系人">
<qn-easyinput :maxlength="20" v-model="form.contactName" :inputBorder="false" text="right" placeholder="请输入用户名称"></qn-easyinput>
</qn-form-item>
<qn-form-item label="联系手机">
<qn-easyinput
:maxlength="11"
type="number"
v-model="form.contactMobile"
:inputBorder="false"
text="right"
placeholder="请输入用户手机号"
></qn-easyinput>
</qn-form-item>
<qn-form-item label="担任职务">
<qn-easyinput :maxlength="20" v-model="form.contactTitle" :inputBorder="false" text="right" placeholder="请输入用户职务"></qn-easyinput>
</qn-form-item>
<qn-form-item label="点击定位" required v-if="!hasSelected">
<image @click="showLocationList" style="width: 32rpx; height: 32rpx" src="/static/imgs/enterpriseInfo/location-icon.png"></image>
</qn-form-item>
<qn-form-item label="所在区域" required>
<qn-data-picker
:readonly="true"
text="right"
:border="false"
class="qn-picker"
placeholder="区域"
popup-title="请选择城市"
:map="{ text: 'name', value: 'id' }"
@change="onAreaChange"
:clear-icon="true"
:localdata="items"
>
<text v-if="form.locDistrictId">
{{ `${form.locProvinceName || ''}/${form.locCityName || ''}/${form.locDistrictName || ''}/${form.locStreetName || ''}` }}
</text>
</qn-data-picker>
</qn-form-item>
<qn-form-item label="详细地址" required>
<qn-easyinput
:maxlength="20"
:disabled="true"
:styles="{ disableColor: '#fff' }"
v-model="form.locDetail"
:inputBorder="false"
text="right"
placeholder="请定位详细地址"
></qn-easyinput>
</qn-form-item>
<qn-form-item label="工商信息" type="title"></qn-form-item>
<qn-form-item label="信用代码" required>
<qn-easyinput
:maxlength="18"
:disabled="hasSelected"
:styles="{ disableColor: '#fff' }"
v-model="form.uniformSocialCreditCode"
:inputBorder="false"
text="right"
placeholder="请输入信用代码"
></qn-easyinput>
</qn-form-item>
<qn-form-item label="法人/实控人" required>
<qn-easyinput
:maxlength="20"
:disabled="hasSelected"
:styles="{ disableColor: '#fff' }"
v-model="form.legalPersonName"
:inputBorder="false"
text="right"
placeholder="请输入法人/实控人"
></qn-easyinput>
</qn-form-item>
<qn-form-item label="法人/实控人手机" required>
<qn-easyinput
:maxlength="11"
type="number"
:disabled="hasSelected"
:styles="{ disableColor: '#fff' }"
v-model="form.legalPersonMobile"
:inputBorder="false"
text="right"
placeholder="请输入法人/实控人手机"
></qn-easyinput>
</qn-form-item>
<qn-form-item label="法人/实控人身份证号" required>
<qn-easyinput
:maxlength="18"
:disabled="hasSelected"
:styles="{ disableColor: '#fff' }"
v-model="form.legalPersonIdCardNo"
:inputBorder="false"
text="right"
placeholder="请输入身份证号"
></qn-easyinput>
</qn-form-item>
<qn-form-item label="身份证照片" size="large" required>
<view class="upload-area">
<image class="idCard" @click="!hasSelected && selectedImage('legalPersonIdCardFrontImg')" :src="frontIDCard" />
<image class="idCard" @click="!hasSelected && selectedImage('legalPersonIdCardBackImg')" :src="backIDCard" />
</view>
</qn-form-item>
<qn-form-item label="营业执照" required>
<text
v-if="!form.businessLicenseImg"
@click="!hasSelected && selectedImage('businessLicenseImg')"
:style="`font-size: 28rpx; color: ${hasSelected ? '#eee' : '#007aff'}`"
>
点击上传
</text>
<text
v-if="form.businessLicenseImg"
@click="!hasSelected && selectedImage('businessLicenseImg')"
:style="`font-size: 28rpx;margin-right: 16rpx; color: ${hasSelected ? '#eee' : '#F5222D'}`"
>
重新上传
</text>
<text v-if="form.businessLicenseImg" @click="!hasSelected && showImage()" style="font-size: 28rpx; color: #007aff">预览</text>
</qn-form-item>
<qn-form-item label="注册资本(万)" required>
<qn-easyinput
type="digit"
maxlength="10"
:disabled="hasSelected"
:styles="{ disableColor: '#fff' }"
v-model="form.registeredCapital"
:inputBorder="false"
text="right"
placeholder="请输入注册资本"
></qn-easyinput>
</qn-form-item>
<qn-form-item label="成立日期" required>
<qn-datetime-picker v-model="form.foundDate" type="date" :border="false" :disabled="hasSelected"></qn-datetime-picker>
</qn-form-item>
</view>
<uni-popup ref="popup" type="bottom">
<view class="popup_modal">
<slot name="title">
<view class="popup_modal-title">可选择已录入公司</view>
</slot>
<scroll-view scroll-y="true" class="popup_modal-scroll">
<view @click="selectCompany(item.enterpriseId)" class="popup_modal-scroll-item" v-for="item in searchList" :key="item.enterpriseId">
{{ item.enterpriseName }}
</view>
</scroll-view>
</view>
</uni-popup>
<uni-popup ref="locationPopup" type="bottom">
<view class="popup_modal">
<slot name="title">
<view class="popup_modal-title">可选择以下定位公司</view>
</slot>
<scroll-view scroll-y="true" class="popup_modal-scroll">
<view @click="selectLocation(item)" style="height: 100rpx" class="popup_modal-scroll-item" v-for="(item, index) in locationList" :key="index">
<view class="location-item">
<text class="title">{{ item.enterpriseName }}</text>
<text class="address">{{ `${item.provinceName}/${item.cityName}/${item.districtName}/${item.address}` }}</text>
</view>
</view>
</scroll-view>
</view>
</uni-popup>
<qn-footer fixed height="120rpx">
<view class="button-area">
<view class="button button__cancel" @click="cancel">
<text class="text">取消</text>
</view>
<view class="button button__submit" @click="saveInfo">
<text class="text" style="color: white">保存信息</text>
</view>
</view>
</qn-footer>
</view>
</template>
<script>
import { back, uploadImage, go2 } from '@/utils/hook.js'
import { getArea, getLicenseOcr, getFrontIdCardOcr } from '@/apis/commonApi.js'
import { completeInfo, getCompanyList, getCompanyInfoById, getCompanyLocationList } from '@/apis/enterpriseInfoApi.js'
const validateFields = [
{ field: 'name', label: '企业名称' },
{ field: 'uniformSocialCreditCode', label: '信用代码' },
{ field: 'legalPersonName', label: '法人姓名' },
{ field: 'locProvinceId', label: '所在省' },
{ field: 'locCityId', label: '所在市' },
{ field: 'locDistrictId', label: '所在区' },
{ field: 'locDetail', label: '企业详细地址' },
{ field: 'legalPersonIdCardNo', label: '法人身份证号' },
{ field: 'legalPersonMobile', label: '法人手机号' },
{ field: 'legalPersonIdCardFrontImg', label: '法人正面照片' },
{ field: 'legalPersonIdCardBackImg', label: '法人反面照片' },
{ field: 'businessLicenseImg', label: '营业执照' },
{ field: 'registeredCapital', label: '注册资本' },
{ field: 'foundDate', label: '成立日期' }
]
export default {
data() {
return {
operation: 'add',
form: {
id: null,
name: null,
shortName: null,
contactName: null,
contactMobile: null,
contactTitle: null,
uniformSocialCreditCode: null,
locProvinceId: null,
locCityId: null,
locDistrictId: null,
locStreetId: null,
locProvinceName: null,
locCityName: null,
locDistrictName: null,
locStreetName: null,
locDetail: null,
regAddrLongitude: null,
regAddrLatitude: null,
legalPersonName: null,
legalPersonMobile: null,
legalPersonIdCardNo: null,
legalPersonIdCardFrontImg: null,
legalPersonIdCardBackImg: null,
businessLicenseImg: null,
registeredCapital: null,
foundDate: null
},
searchList: [],
locationList: [],
hasSelected: false,
items: []
}
},
mounted() {
getArea().then((res) => {
if (res) {
this.items = res
}
})
},
methods: {
back,
jump() {
go2('store')
},
cancel() {
//
if (this.operation === 'add') {
go2('store', {}, true)
} else {
back()
}
},
showLocationList() {
if (!this.form.name || !this.form.name.trim()) {
uni.showToast({
title: '请先填写公司名称',
icon: 'none'
})
return
}
getCompanyLocationList({ enterpriseName: this.form.name }).then((res) => {
if (res && res.length > 0) {
this.locationList = res
this.$refs.locationPopup.open('bottom')
} else {
uni.showToast({
title: '暂无定位公司',
icon: 'error'
})
}
})
},
selectLocation(location) {
this.form.locProvinceId = location.provinceCode
this.form.locCityId = location.cityCode
this.form.locDistrictId = location.districtCode
this.form.locProvinceName = location.provinceName
this.form.locCityName = location.cityName
this.form.locDistrictName = location.districtName
this.form.locDetail = location.address
this.form.regAddrLongitude = location.longitude
this.form.regAddrLatitude = location.latitude
this.$refs.locationPopup.close()
},
showCompany(e) {
let enterpriseName = e.detail.value.trim()
if (enterpriseName) {
getCompanyList({ enterpriseName }).then((res) => {
if (res) {
this.searchList = res.records
if (this.searchList.length > 0) {
this.$refs.popup.open('bottom')
}
}
})
}
},
selectCompany(enterpriseId) {
this.$refs.popup.close()
getCompanyInfoById({ enterpriseId }).then((res) => {
if (res) {
this.form.id = enterpriseId
this.form.name = res.name
// watchname
setTimeout(() => {
//
this.reflectiveCompany(res)
this.hasSelected = true
}, 0)
}
})
},
reflectiveCompany(info) {
this.form.uniformSocialCreditCode = info.uniformSocialCreditCode
this.form.locProvinceId = info.locProvinceId
this.form.locCityId = info.locCityId
this.form.locStreetId = info.locStreetId
this.form.locDistrictId = info.locDistrictId
this.form.locProvinceName = info.locProvinceName
this.form.locCityName = info.locCityName
this.form.locStreetName = info.locStreetName
this.form.locDistrictName = info.locDistrictName
this.form.locDetail = info.locDetail
this.form.registeredCapital = info.registeredCapital
this.form.foundDate = info.foundDate
this.form.regAddrLongitude = info.regAddrLongitude
this.form.regAddrLatitude = info.regAddrLatitude
},
onAreaChange(e) {
if (e.detail.value && e.detail.value.length > 0) {
const [province, city, district, street] = e.detail.value
this.form.locProvinceId = province.value
this.form.locProvinceName = province.text
this.form.locCityId = city.value
this.form.locCityName = city.text
this.form.locDistrictId = district.value
this.form.locDistrictName = district.text
this.form.locStreetId = street.value
this.form.locStreetName = street.text
} else {
this.form.locProvinceId = null
this.form.locProvinceName = null
this.form.locCityId = null
this.form.locCityName = null
this.form.locDistrictId = null
this.form.locDistrictName = null
this.form.locStreetId = null
this.form.locStreetName = null
}
},
selectedImage(type) {
uploadImage()
.then((urls) => {
if (urls) {
this.form[type] = urls[0]
// OCR
if (type == 'businessLicenseImg') {
this.licenseOcr(urls[0])
}
//
if (type == 'legalPersonIdCardFrontImg') {
this.idCardFrontOcr(urls[0])
}
}
})
.catch((e) => {
uni.showToast({
title: '上传失败',
icon: 'fail'
})
})
},
// OCR
licenseOcr(url) {
getLicenseOcr({ photoUrl: url }).then((res) => {
if (res) {
this.form.uniformSocialCreditCode = res.regNum
this.form.name = res.company
this.form.legalPersonName = res.legalPerson
const foundDateArr = res.establishDate.split(/[年月日]/)
this.form.foundDate = foundDateArr[0] + '-' + foundDateArr[1] + '-' + foundDateArr[2]
this.form.registeredCapital = /\d+/.exec(res.capital)[0]
}
})
},
// OCR
idCardFrontOcr(url) {
getFrontIdCardOcr({ image: url }).then((res) => {
if (res && res.success) {
this.form.legalPersonIdCardNo = res.num
this.form.legalPersonName = res.name
}
})
},
showImage() {
uni.previewImage({
urls: [this.form.businessLicenseImg]
})
},
saveInfo() {
if (!this.form.id) {
for (let validateField of validateFields) {
if (this.form[validateField.field] === null || this.form[validateField.field] === '') {
uni.showToast({
title: `${validateField.label}不能为空`,
icon: 'none'
})
return
}
}
if (!/^1[3456789]\d{9}$/.test(this.form['legalPersonMobile'])) {
uni.showToast({
title: '请输入正确法人手机号',
icon: 'none'
})
return
}
}
if (this.form.contactMobile && !/^1[3456789]\d{9}$/.test(this.form['contactMobile'])) {
uni.showToast({
title: '请输入正确联系人手机号',
icon: 'none'
})
return
}
completeInfo(this.form).then((res) => {
if (res) {
uni.showToast({
title: '添加成功',
icon: 'success'
})
setTimeout(() => {
go2('store')
}, 1000)
}
})
}
},
watch: {
['form.name']() {
this.hasSelected = false
this.form.id = null
this.reflectiveCompany({})
}
},
computed: {
frontIDCard() {
let url = 'https://qncloud.oss-cn-shenzhen.aliyuncs.com/paper_shopkeeper/frontIDCard.png'
if (this.hasSelected || !this.form.legalPersonIdCardFrontImg) {
return url
}
return this.form.legalPersonIdCardFrontImg
},
backIDCard() {
let url = 'https://qncloud.oss-cn-shenzhen.aliyuncs.com/paper_shopkeeper/backDCard.png'
if (this.hasSelected || !this.form.legalPersonIdCardBackImg) {
return url
}
return this.form.legalPersonIdCardBackImg
}
}
}
</script>
<style lang="scss" scoped>
.content {
width: 750rpx;
display: flex;
flex-direction: column;
background-color: #f7f8fa;
}
.qn-form-item {
width: 750rpx;
padding: 0rpx 32rpx;
background-color: #fff;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
min-height: 80rpx;
.label {
flex-grow: 0;
flex-shrink: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
margin-right: 20rpx;
.label__text {
font-size: 28rpx;
color: #000000;
}
}
.value {
flex-grow: 1;
flex-shrink: 1;
text-align: right;
}
}
.qn-form-item__title {
background-color: #f7f8fa;
padding: 20rpx 32rpx;
border: none;
.title {
font-size: 30rpx;
color: #888888;
}
}
.popup_modal {
width: 750rpx;
height: 600rpx;
background-color: #fff;
border-radius: 10px 10px 0 0;
.popup_modal-title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 750rpx;
height: 88rpx;
font-weight: 600;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
}
.popup_modal-scroll {
width: 750rpx;
height: 600rpx;
.popup_modal-scroll-item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 750rpx;
height: 88rpx;
padding: 0rpx 32rpx;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
}
}
}
.upload-area {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top: 10rpx;
margin-bottom: 24rpx;
.idCard {
width: 324rpx;
height: 280rpx;
flex-grow: 0;
flex-shrink: 0;
}
}
.button-area {
width: 750rpx;
padding: 0 32rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.button {
flex-grow: 0;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10rpx;
.text {
font-size: 30rpx;
font-weight: 500;
text-align: center;
}
}
.button__cancel {
width: 270rpx;
height: 88rpx;
border: 2rpx solid #979797;
}
.button__submit {
width: 400rpx;
height: 88rpx;
background: #007aff;
}
}
.location-item {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
.title {
font-size: 32rpx;
color: #000000;
margin-bottom: 10rpx;
}
.address {
font-size: 24rpx;
color: #888888;
word-break: break-all;
}
}
</style>

617
pages/for-comparison/index.vue

@ -0,0 +1,617 @@
<template>
<view class="content">
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="实单询比价"></uni-nav-bar>
<view>
<view class="hint-box">全网优质原纸供应商20分钟极速响应</view>
<view class="qn-form-item qn-form-item">
<view class="label">
<uni-icons custom-prefix="iconfont" type="icon-required" size="14" color="#F5222D"></uni-icons>
<text class="label__text">纸种</text>
</view>
<view class="value">
<picker :value="form.categoryIndex" @change="categoryChange" :range="categoryNameList">
<view>
<text class="uni-input">{{ form.categoryName }}</text>
<uni-icons type="right" color="#000000" size="16"></uni-icons>
</view>
</picker>
</view>
</view>
<view class="qn-form-item qn-form-item">
<view class="label">
<uni-icons custom-prefix="iconfont" type="icon-required" size="14" color="#F5222D"></uni-icons>
<text class="label__text">品牌</text>
</view>
<view class="value">
<picker :value="form.brandIndex" @change="brandChange" :range="brandNameList">
<view>
<text class="uni-input">{{ form.brandName }}</text>
<uni-icons type="right" color="#000000" size="16"></uni-icons>
</view>
</picker>
</view>
</view>
<view class="qn-form-item qn-form-item">
<view class="label">
<uni-icons custom-prefix="iconfont" type="icon-required" size="14" color="#F5222D"></uni-icons>
<text class="label__text">纸品名称</text>
</view>
<view class="value">
<qn-easyinput :maxlength="20" v-model="form.paperName" :inputBorder="false" text="right" placeholder="请输入纸品名称"></qn-easyinput>
</view>
</view>
<view class="qn-form-item qn-form-item">
<view class="label">
<uni-icons custom-prefix="iconfont" type="icon-required" size="14" color="#F5222D"></uni-icons>
<text class="label__text">克重(g)</text>
</view>
<view class="value">
<picker :value="form.gramWeightIndex" @change="gramWeightChange" :range="weightList">
<view>
<text class="uni-input">{{ form.gramWeight }}</text>
<uni-icons type="right" color="#000000" size="16"></uni-icons>
</view>
</picker>
</view>
</view>
<view class="qn-form-item-gg">
<view class="label">
<uni-icons custom-prefix="iconfont" type="icon-required" size="14" color="#F5222D"></uni-icons>
<text class="label__text">规格(mm)</text>
</view>
<view class="value">
<view class="value">
<radio-group>
<label v-for="(ritem, rindex) in radioGroupList" :key="rindex" @tap="specificationTap(ritem, rindex)">
<radio :checked="rindex === 0" style="transform: scale(0.7)" />
<text class="uni-input">{{ ritem.name }}</text>
</label>
</radio-group>
</view>
<view class="input-row">
<view><uni-easyinput :inputBorder="false" class="easyinput" type="number" v-model="form.width" placeholder="请输入"></uni-easyinput></view>
<view class="symbol">x</view>
<view>
<uni-easyinput :inputBorder="false" class="easyinput" type="number" v-model="form.length" placeholder="请输入"></uni-easyinput>
</view>
</view>
</view>
</view>
<view class="qn-form-item qn-form-item">
<view class="label">
<uni-icons custom-prefix="iconfont" type="icon-required" size="14" color="#F5222D"></uni-icons>
<text class="label__text">数量()</text>
</view>
<view class="value">
<view class="value">
<qn-easyinput :maxlength="20" type="number" v-model="form.quantity" :inputBorder="false" text="right" placeholder="请输入数量"></qn-easyinput>
</view>
</view>
</view>
<view class="qn-form-item qn-form-item">
<view class="label"><text class="label__text">交货时间</text></view>
<view class="value">
<qn-datetime-picker
v-model="form.deliveryDay"
type="datetime"
:border="false"
placeholder="交货时间"
@change="deliveryTimeChange"
></qn-datetime-picker>
</view>
</view>
<view class="qn-form-item qn-form-item" style="border: none">
<view class="label">
<text class="label__text">交货区域</text>
</view>
<view class="value">
<qn-data-picker
:readonly="hasSelected"
text="right"
:border="false"
class="qn-picker"
placeholder="区域"
popup-title="请选择城市"
:map="{ text: 'name', value: 'id' }"
@change="onAreaChange"
:clear-icon="true"
:localdata="items"
>
<text v-if="form.locDistrictId">
{{ `${form.deliveryProvinceName || ''}/${form.deliveryCityName || ''}/${form.deliveryDistrictName || ''}/${form.deliveryStreetName || ''}` }}
</text>
</qn-data-picker>
</view>
</view>
<view class="qn-form-item-remark">
<view class="label"><text class="label__text">询价备注</text></view>
<view class="value">
<qn-easyinput
class="paper-price-textArea"
:maxlength="200"
:styles="{ disableColor: '#F7F8FA' }"
v-model="form.remark"
:inputBorder="false"
type="textarea"
placeholder="请输入询价备注"
></qn-easyinput>
</view>
</view>
</view>
<qn-footer fixed height="120rpx">
<view class="button-area">
<view class="button button__submit" @click="addUser"><text class="text" style="color: white">提交询价</text></view>
</view>
</qn-footer>
</view>
</template>
<script>
import { back, uploadImage } from '@/utils/hook.js'
import { getArea } from '@/apis/commonApi.js'
import { createEnquiryOrder, getCategoryList } from '@/apis/forComparisonApi.js'
const validateFields = ['categoryName', 'brandName', 'paperName', 'gramWeight', 'width', 'length', 'quantity']
export default {
data() {
return {
paperIndex: 0,
categoryNameList: [],
brandNameList: [],
weightList: [],
deliveryTimeList: ['当天到', '明天到'],
radioGroupList: [
{
name: '正度',
width: '787',
length: '1092',
disabled: true
},
{
name: '大度',
width: '889',
length: '1194',
disabled: true
},
{
name: '特规分切',
width: '',
length: '',
disabled: false
}
],
form: {
deliveryArea: '',
deliveryCityId: '',
deliveryCityName: '',
deliveryDay: '',
deliveryDayIndex: 0,
deliveryDistrictId: '',
deliveryDistrictName: '',
deliveryId: '',
deliveryProvinceId: '',
deliveryProvinceName: '',
deliveryStreetId: '',
deliveryStreetName: '',
detailList: [],
offerEnterprise: '',
remark: '',
brandId: '',
brandName: '',
brandIndex: 0,
categoryId: '',
categoryName: '',
categoryIndex: 0,
gramWeight: '',
gramWeightIndex: 0,
length: '1092',
paperName: '',
quantity: '',
width: '787',
productImg: ''
},
searchList: [],
hasSelected: false,
items: []
}
},
mounted() {
getArea().then((res) => {
if (res) {
this.items = res
}
})
},
onLoad(option) {
this.form.offerEnterprise = option.id
this.form.productImg = option.productImg
this.getCategoryList()
},
methods: {
back,
//
getCategoryList() {
const params = {
paperSupplierId: this.$store.state.supplierId
}
getCategoryList(params).then((res) => {
// console.log('', res)
if (res) {
this.categoryNameList = res.categoryNameList
this.brandNameList = res.brandNameList
this.weightList = res.weightList
this.form.categoryName = this.categoryNameList[0]
this.form.brandName = this.brandNameList[0]
this.form.gramWeight = this.weightList[0]
}
})
},
//
categoryChange(e) {
// console.log('e.target.value', e.target.value)
let index = e.target.value
this.form.categoryIndex = e.target.value
this.form.categoryName = this.categoryNameList[index]
},
//
brandChange(e) {
let index = e.target.value
this.form.brandIndex = e.target.value
this.form.brandName = this.brandNameList[index]
},
//
gramWeightChange(e) {
let index = e.target.value
this.form.gramWeightIndex = e.target.value
this.form.gramWeight = this.weightList[index]
},
//
specificationTap(item, index) {
this.form.width = item.width
this.form.length = item.length
},
//
deliveryTimeChange(datetime) {
if (datetime.length == 11) {
this.$nextTick(() => {
this.form.deliveryDay = datetime + '23:59:59'
})
}
},
onAreaChange(e) {
if (e.detail.value && e.detail.value.length > 0) {
const [province, city, district, street] = e.detail.value
this.form.deliveryProvinceId = province.value
this.form.deliveryProvinceName = province.text
this.form.deliveryCityId = city.value
this.form.deliveryCityName = city.text
this.form.deliveryDistrictId = district.value
this.form.deliveryDistrictName = district.text
this.form.deliveryStreetId = street.value
this.form.deliveryStreetName = street.text
this.form.deliveryArea = province.text + city.text + district.text + street.text
} else {
this.form.deliveryProvinceId = null
this.form.deliveryProvinceName = null
this.form.deliveryCityId = null
this.form.deliveryCityName = null
this.form.deliveryDistrictId = null
this.form.deliveryDistrictName = null
this.form.deliveryStreetId = null
this.form.deliveryStreetName = null
this.form.deliveryArea = null
}
},
selectedImage(type) {
uploadImage()
.then((urls) => {
if (urls) {
this.form[type] = urls[0]
}
})
.catch((e) => {
uni.showToast({
title: '上传失败',
icon: 'fail'
})
})
},
showImage() {
uni.previewImage({
urls: [this.form.businessLicenseImg]
})
},
addUser() {
for (let validateField of validateFields) {
if (this.form[validateField] === null || this.form[validateField] === '') {
uni.showToast({
title: '请完善信息',
icon: 'none'
})
return
}
}
const params = {
deliveryArea: this.form.deliveryArea,
deliveryCityId: this.form.deliveryCityId,
deliveryCityName: this.form.deliveryCityName,
deliveryDay: this.form.deliveryDay,
deliveryDistrictId: this.form.deliveryDistrictId,
deliveryDistrictName: this.form.deliveryDistrictName,
deliveryId: this.form.deliveryId,
deliveryProvinceId: this.form.deliveryProvinceId,
deliveryProvinceName: this.form.deliveryProvinceName,
deliveryStreetId: this.form.deliveryStreetId,
deliveryStreetName: this.form.deliveryStreetName,
detailList: [
{
brandId: this.form.brandId,
brandName: this.form.brandName,
categoryId: this.form.categoryId,
categoryName: this.form.categoryName,
gramWeight: this.form.gramWeight,
length: this.form.length,
paperName: this.form.paperName,
quantity: this.form.quantity,
remark: this.form.remark,
width: this.form.width
}
],
offerEnterprise: this.form.offerEnterprise,
remark: this.form.remark,
enterpriseId: this.$store.state.companyInfo.id,
productImg: this.form.productImg,
userId: this.$store.state.userInfo.userId
}
createEnquiryOrder(params).then((res) => {
if (res) {
uni.showToast({
title: '添加成功',
icon: 'success'
})
setTimeout(() => {
back()
}, 1000)
}
})
},
/**
* @param {Object} day '昨天:', this.getDay(-1, 7200000) '今天:', this.getDay(0, 3600000) '明天:', this.getDay(1, 3600000)
* @param {Object} hours
* 获取当前时间的前一天 后一天 一周 或者是当前时间的几个小时
*/
getDay(day, hours) {
let today = new Date()
let targetday = today.getTime() + 1000 * 60 * 60 * 24 * day + hours
today.setTime(targetday)
let tYear = today.getFullYear()
let tMonth = today.getMonth()
let tDate = today.getDate()
tMonth = this.doHandleMonth(tMonth + 1)
tDate = this.doHandleMonth(tDate)
return tYear + '-' + tMonth + '-' + tDate + ' ' + '23:59:59'
},
doHandleMonth(month) {
let m = month
if (month.toString().length === 1) {
m = '0' + month
}
return m
}
}
}
</script>
<style lang="scss">
.content {
width: 750rpx;
display: flex;
flex-direction: column;
background-color: #f7f8fa;
}
.hint-box {
padding: 0rpx 32rpx;
height: 76rpx;
line-height: 76rpx;
background: #e5f1ff;
font-size: 30rpx;
color: #007aff;
letter-spacing: 0;
font-weight: 400;
}
.uni-input {
font-size: 28rpx;
color: #333333;
letter-spacing: 0;
text-align: right;
font-weight: 400;
padding-right: 16rpx;
}
.qn-form-item-remark {
margin-top: 20rpx;
width: 750rpx;
padding: 28rpx 32rpx 10rpx 32rpx;
background-color: #fff;
.label {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
margin-right: 20rpx;
.label__text {
font-size: 28rpx;
color: #000000;
}
}
.value {
padding: 16rpx 0rpx;
}
.paper-price-textArea {
background: #f7f8fa;
border-radius: 20rpx;
padding: 10rpx;
height: 155rpx;
}
}
.qn-form-item-gg {
width: 750rpx;
padding: 24rpx 32rpx;
background-color: #fff;
display: flex;
flex-direction: row;
justify-content: space-between;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
.label {
flex-grow: 0;
flex-shrink: 0;
display: flex;
flex-direction: row;
justify-content: flex-start;
margin-right: 20rpx;
.label__text {
font-size: 28rpx;
color: #000000;
}
}
.value {
flex-grow: 1;
flex-shrink: 1;
text-align: right;
}
.input-row {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
padding-top: 20rpx;
.easyinput {
height: 64rpx;
width: 160rpx;
background: #f5f5f5;
border-radius: 8rpx;
}
.symbol {
padding: 0rpx 16rpx;
font-size: 32rpx;
color: rgba(0, 0, 0, 0.85);
font-weight: 400;
}
}
}
.qn-form-item {
width: 750rpx;
padding: 0rpx 32rpx;
background-color: #fff;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
min-height: 80rpx;
.label {
flex-grow: 0;
flex-shrink: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
margin-right: 20rpx;
.label__text {
font-size: 28rpx;
color: #000000;
}
}
.value {
flex-grow: 1;
flex-shrink: 1;
text-align: right;
}
}
.qn-form-item__title {
background-color: #f7f8fa;
padding: 20rpx 32rpx;
border: none;
.title {
font-size: 30rpx;
color: #888888;
}
}
.popup_modal {
width: 750rpx;
height: 600rpx;
background-color: #fff;
border-radius: 10px 10px 0 0;
.popup_modal-title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 750rpx;
height: 88rpx;
font-weight: 600;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
}
.popup_modal-scroll {
width: 750rpx;
height: 600rpx;
.popup_modal-scroll-item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
width: 750rpx;
height: 88rpx;
padding: 0rpx 32rpx;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
}
}
}
.upload-area {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top: 10rpx;
margin-bottom: 24rpx;
.idCard {
width: 324rpx;
height: 280rpx;
flex-grow: 0;
flex-shrink: 0;
}
}
.button-area {
width: 750rpx;
padding: 0 32rpx;
display: flex;
flex-direction: row;
align-items: center;
// justify-content: space-between;
.button {
flex-grow: 0;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10rpx;
.text {
font-size: 30rpx;
font-weight: 500;
text-align: center;
}
}
.button__cancel {
width: 270rpx;
height: 88rpx;
border: 2rpx solid #979797;
}
.button__submit {
// width: 400rpx;
width: 100%;
height: 88rpx;
background: #007aff;
}
}
</style>

283
pages/mall/index.vue

@ -1,32 +1,277 @@
<template>
<view>mall</view>
<view class="flex-col group">
<view class="flex-col items-center section_1">
<view class="flex-row section_2">
<text class="text">原纸商城</text>
<view class="flex-row items-center section_3">
<image
src="https://codefun-proj-user-res-1256085488.cos.ap-guangzhou.myqcloud.com/611dd17441a9be0011f45822/620ccb0962a7d90011fe5c8f/16488644996273525546.png"
class="image_1"
/>
<qn-easyinput @confirm="downCallback" :maxlength="15" v-model="condition.searchValue" :inputBorder="false" placeholder="输入搜索信息"></qn-easyinput>
</view>
</view>
</view>
<scroll-list ref="list" :option="option" @load="upCallback" @refresh="downCallback">
<view class="flex-col list">
<view class="list-item flex-col" :key="i" v-for="(item, i) in storeList">
<view class="flex-row">
<image
src="https://codefun-proj-user-res-1256085488.cos.ap-guangzhou.myqcloud.com/611dd17441a9be0011f45822/620ccb0962a7d90011fe5c8f/16488644996327336999.png"
class="image_2"
/>
<view class="right-group flex-col" @click="jumpStore(item)">
<view class="text_2" v-html="item.enterpriseName"></view>
<view class="bottom-group flex-row">
<text>全部商品 {{ item.productNumber }}</text>
<view class="center-section"></view>
<text class="text_5">上新 {{ item.currentProductNumber }}</text>
</view>
</view>
</view>
<view class="bottom-group_1 flex-row">
<view class="paper-group flex-col" v-for="paper in item.skuList" :key="paper.id">
<view class="top-group flex-col items-center">
<image :src="paper.litPicUrl || 'https://qncloud.oss-cn-shenzhen.aliyuncs.com/paper_shopkeeper/paper-default-small.png'" class="image_4" />
<view class="flex-col text-wrapper">
<text class="text_7">{{ paper.listPrice }}/{{ paper.stockUnit | formatUnit }}</text>
</view>
</view>
<view class="bottom-text-wrapper flex-col items-start">
<view class="text_8 text_9" v-html="paper.productName"></view>
</view>
</view>
</view>
</view>
</view>
</scroll-list>
<image src="/static/imgs/mall/cart-icon.png" class="image_11" />
</view>
</template>
<script>
import { enterpriseType } from '@/enums/index.js'
import { paperUnitMap } from '@/enums/index.js'
import { getStoreList } from '@/apis/mallApi.js'
import { go2 } from '@/utils/hook.js'
export default {
created() {
// //
// let type = this.$store.state.companyInfo.enterpriseType
// if (type == enterpriseType.PERSONAL) {
// // 广
// this.changeTabbar(0, false)
// this.changeTabbar(1, false)
// } else {
// // 广
// this.changeTabbar(0, true)
// this.changeTabbar(1, true)
// }
data() {
return {
condition: {
searchValue: '',
pageSize: 10,
pageIdentifier: ''
},
option: {
size: 10,
auto: true,
emptyText: '我是有底线的~',
background: '#F7F8FA',
fontSize: '40rpx'
},
storeList: []
}
},
methods: {
changeTabbar(index, isShow) {
uni.setTabBarItem({
index: index,
visible: isShow
go2,
//
getList() {
return new Promise((resolve, reject) => {
getStoreList({ ...this.condition })
.then((res) => {
if (res) {
if (this.condition.pageIdentifier) {
this.storeList = this.storeList.concat(res.records)
} else {
this.storeList = res.records
}
//
if (res.next && res.records.length == this.condition.pageSize) {
res.total = this.storeList.length + 1
this.condition.pageIdentifier = res.pageIdentifier?.join(',') || ''
} else {
res.total = this.storeList.length
}
resolve({ list: this.storeList, total: res.total })
} else {
reject()
}
})
.catch((err) => {
reject(err)
})
})
},
downCallback() {
this.condition.pageIdentifier = ''
this.getList()
.then(({ list, total }) => {
this.$refs.list.refreshSuccess({ list, total })
})
.catch(() => {
this.$refs.list.refreshFail()
})
},
upCallback() {
this.getList()
.then(({ list, total }) => {
this.$refs.list.loadSuccess({ list, total })
})
.catch(() => {
this.$refs.list.loadFail()
})
},
jumpStore(store) {
this.$store.commit('setSupplierId', store.mallSupplierId)
go2('store')
}
},
filters: {
formatUnit(value) {
return paperUnitMap[value] || ''
}
}
}
</script>
<style></style>
<style lang="scss" scoped>
.group {
flex: 1 1 auto;
height: 100vh;
overflow-y: auto;
position: relative;
.section_1 {
height: 170rpx;
width: 750rpx;
background: url('/static/imgs/mall/top-bg.png') no-repeat center/contain;
padding-top: 82rpx;
.section_2 {
width: 750rpx;
padding: 12rpx 32rpx;
.text {
align-self: center;
color: rgb(255, 255, 255);
font-size: 30rpx;
font-weight: 600;
line-height: 42rpx;
white-space: nowrap;
}
.section_3 {
margin-left: 66rpx;
padding: 14rpx 23rpx;
flex: 1 1 auto;
color: rgb(34, 34, 34);
font-size: 25rpx;
line-height: 36rpx;
white-space: nowrap;
background-color: rgb(255, 255, 255);
border-radius: 10rpx;
height: 64rpx;
.image_1 {
margin-right: 10rpx;
width: 25rpx;
height: 25rpx;
}
}
}
}
.list {
width: 750rpx;
padding: 0 16rpx 20rpx;
background-color: #f7f8fa;
.list-item {
background-color: #fff;
margin-top: 20rpx;
padding: 24rpx 14rpx 17rpx;
overflow: hidden;
height: 401rpx;
.bottom-group_1 {
margin-top: 16rpx;
width: 100%;
overflow-x: auto;
.paper-group {
width: 220rpx;
margin-right: 8rpx;
.top-group {
color: rgb(255, 255, 255);
font-size: 28rpx;
line-height: 40rpx;
white-space: nowrap;
border-radius: 8rpx;
position: relative;
.image_4 {
border: 2rpx solid #f7f8fa;
border-radius: 8rpx;
width: 220rpx;
height: 220rpx;
}
.text-wrapper {
background-color: rgba(0, 0, 0, 0.4);
border-radius: 20rpx;
position: absolute;
right: 10rpx;
bottom: 10rpx;
.text_7 {
margin: 0 10rpx;
}
}
}
.bottom-text-wrapper {
padding-top: 16rpx;
color: rgb(51, 51, 51);
font-size: 24rpx;
line-height: 33rpx;
white-space: nowrap;
width: 220rpx;
.text_8 {
margin: 0 10rpx;
}
.text_9 {
margin: initial;
}
}
}
}
.image_2 {
width: 76rpx;
height: 76rpx;
}
.right-group {
margin-left: 16rpx;
.text_2 {
width: 612rpx;
overflow: hidden;
text-overflow: ellipsis;
color: rgb(0, 0, 0);
font-size: 28rpx;
line-height: 40rpx;
white-space: nowrap;
}
.bottom-group {
margin-top: 3rpx;
color: rgb(136, 136, 136);
font-size: 24rpx;
line-height: 33rpx;
white-space: nowrap;
.center-section {
margin: 5rpx 0 3rpx 16rpx;
background-color: rgb(136, 136, 136);
width: 2rpx;
height: 24rpx;
}
.text_5 {
margin-left: 15rpx;
}
}
}
}
}
.image_11 {
border-radius: 50%;
width: 82rpx;
height: 82rpx;
position: fixed;
right: 32rpx;
bottom: 162rpx;
}
}
</style>

505
pages/order-make/index.vue

@ -0,0 +1,505 @@
<template>
<view>
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="订单确认"></uni-nav-bar>
<view class="address-area">
<view class="header">
<image class="img" src="/static/imgs/order/customer-default.png"></image>
<text class="text">{{ orderInfo.customerEnterpriseName }}</text>
</view>
<!-- 送货地址 -->
<view class="address-content" v-if="deliveryAddress.addressId" @click="go2('address-manage', { operation: 'select' })">
<view class="left">
<image style="width: 66rpx; height: 66rpx" src="/static/imgs/order/address-icon.png"></image>
<text style="font-size: 22rpx; margin-top: 8rpx; transform: scale(0.8)">送货至</text>
</view>
<view class="center">
<text style="font-size: 30rpx; font-weight: 600">{{ `${deliveryAddress.receiver} ${deliveryAddress.receiverMobile}` }}</text>
<text style="font-size: 28rpx; font-weight: 500; word-break: break-all; margin-top: 10rpx; line-height: 1.2">
{{
`${deliveryAddress.provinceName}${deliveryAddress.cityName}${deliveryAddress.districtName}${deliveryAddress.streetName}${deliveryAddress.detail}`
}}
</text>
</view>
<image class="right" src="/static/imgs/order/edit-address-icon.png"></image>
</view>
<view class="address-content" v-else @click="go2('address-manage', { operation: 'select' })">
<view class="left">
<image style="width: 66rpx; height: 66rpx" src="/static/imgs/order/address-icon.png"></image>
</view>
<view class="center">
<text style="font-size: 30rpx; font-weight: 400">请添加收货地址</text>
</view>
<image class="right" src="/static/imgs/order/right-arrow.png"></image>
</view>
</view>
<!-- 商品信息区域 -->
<view class="order-area">
<view v-for="item in orderInfo.supplierOrder" :key="item.supplierOrderId">
<view class="header">
<text style="font-size: 32rpx; font-weight: 600">{{ item.supplierEnterpriseName }}</text>
</view>
<view v-for="order in item.orderItems" :key="order.supplierOderItemId">
<view class="order-header">
<text style="font-size: 30rpx; font-weight: 600">
{{ `${order.brandName}${order.productName} | ${order.gramWeight}g | ${order.width}*${order.length} | ${order.pieceQuantity}` }}
</text>
</view>
<view class="order-row">
<text>重量():</text>
<text>{{ order.buyTon }}</text>
</view>
<view class="order-row">
<text>单价(/):</text>
<text>{{ order.unitPrice }}</text>
</view>
<view class="order-row">
<text>小计():</text>
<text>{{ order.subtotal }}</text>
</view>
<view class="order-row">
<text>其他费用():</text>
<text>{{ item.otherFee }}</text>
</view>
<view class="order-row">
<qn-easyinput
style="background-color: #f7f8fa; border-radius: 10rpx; padding: 8rpx 0rpx; font-size: 28rpx; color: #888888; height: 88rpx"
v-model="order.remark"
placeholder="请输入备注"
:inputBorder="false"
:maxlength="100"
></qn-easyinput>
</view>
</view>
</view>
</view>
<!-- 是否开票 -->
<view class="tax-area flex-row-center-space">
<text class="text">是否开票:</text>
<view style="width: 350rpx" class="flex-row-center-space">
<view class="flex-row-center-space" @click="selectInvoice(true)">
<image class="switch-icon" :src="isInvoice ? '/static/imgs/order/selected-icon.png' : '/static/imgs/order/select-icon.png'"></image>
<text class="text">开票</text>
</view>
<view class="flex-row-center-space" @click="selectInvoice(false)">
<image class="switch-icon" :src="!isInvoice ? '/static/imgs/order/selected-icon.png' : '/static/imgs/order/select-icon.png'"></image>
<text class="text">不开票</text>
</view>
</view>
</view>
<!-- 送货时间 -->
<view class="timer-area">
<text style="font-size: 30rpx; color: #000000">送货时间:</text>
<qn-datetime-picker v-model="orderInfo.receivedTime" type="datetime" :border="false"></qn-datetime-picker>
</view>
<!-- 支付方式 -->
<view class="pay-area">
<view class="pay-item">
<view class="left">
<image class="img" src="/static/imgs/order/month-pay-icon.png"></image>
<text style="font-size: 30rpx; color: #000000; margin: 0 16rpx">使用月结额度</text>
<text v-if="payMap['month'] != null" style="font-size: 28rpx; color: #888888">剩余额度: {{ payMap['month'].availableCreditLine }}</text>
</view>
<image
v-if="payMap['month'] != null && payMap['month'].availableCreditLine > orderInfo.totalOfferPrice"
@click="selectPayMethod('month')"
class="img"
:src="currentPayType == 'month' ? '/static/imgs/order/selected-icon.png' : '/static/imgs/order/select-icon.png'"
></image>
<text v-if="payMap['month'] == null" style="font-size: 28rpx; color: #888888">待申请</text>
<text v-if="payMap['month'] != null && payMap['month'].availableCreditLine < orderInfo.totalOfferPrice" style="font-size: 28rpx; color: #888888">
余额不足
</text>
</view>
<view class="pay-item" style="border: none">
<view class="left">
<image class="img" src="/static/imgs/order/fs-pay-icon.png"></image>
<text style="font-size: 30rpx; color: #000000; margin: 0 16rpx">使用飞算资金</text>
<text v-if="payMap['fs'] != null" style="font-size: 28rpx; color: #888888">剩余额度: {{ payMap['fs'].availableCreditLine }}</text>
</view>
<image
v-if="payMap['fs'] != null && payMap['fs'].availableCreditLine > orderInfo.totalOfferPrice"
@click="selectPayMethod('fs')"
class="img"
:src="currentPayType == 'fs' ? '/static/imgs/order/selected-icon.png' : '/static/imgs/order/select-icon.png'"
></image>
<text v-if="payMap['fs'] == null" style="font-size: 28rpx; color: #888888">待申请</text>
<text v-if="payMap['fs'] != null && payMap['fs'].availableCreditLine < orderInfo.totalOfferPrice" style="font-size: 28rpx; color: #888888">
余额不足
</text>
</view>
<view class="pay-item" style="border: none">
<view class="left">
<image class="img" src="/static/imgs/order/wxpay-icon.png"></image>
<text style="font-size: 30rpx; color: #000000; margin: 0 16rpx">使用现款支付</text>
</view>
<image
@click="selectPayMethod('wxpay')"
class="img"
:src="currentPayType == 'wxpay' ? '/static/imgs/order/selected-icon.png' : '/static/imgs/order/select-icon.png'"
></image>
</view>
</view>
<qn-footer fixed height="120rpx">
<view class="button-area">
<view class="text-line">
<text style="font-size: 28rpx">应付:</text>
<text style="font-size: 40rpx; color: #f5222d">{{ orderInfo.totalOfferPrice }}</text>
</view>
<view class="button" @click="submitOrder">确认下单</view>
</view>
</qn-footer>
</view>
</template>
<script>
import { go2, back, getCache } from '@/utils/hook.js'
import { getPreOrderInfo, getDefaultAddress, submitClientOrder, calcNotInvoiceOrderInfo } from '@/apis/orderApi'
import { getFsCredit, getMonthCredit } from '@/apis/commonApi'
import { isObject } from '@/utils/is'
import { invoiceStatusEnum } from '@/enums/index'
export default {
data() {
return {
orderInfo: {
customerEnterpriseName: '',
receivedTime: null
},
invoiceInfo: {}, //
noInvoiceInfo: null, //
deliveryAddress: {},
currentPayType: null,
payMap: {
month: {
availableCreditLine: 0,
value: 2
},
fs: {
availableCreditLine: 0,
value: 4
},
wxpay: {
value: 1
}
},
loading: false,
isInvoice: true //
}
},
onLoad(option) {
if (option.orderId) {
getPreOrderInfo({
customerOrderId: option.orderId
}).then((res) => {
if (res) {
this.orderInfo = res
this.invoiceInfo = res
}
})
} else {
uni.showToast({
title: '订单信息错误',
icon: 'error',
success: () => {
setTimeout(() => {
back()
}, 2000)
}
})
}
},
created() {
this.init()
},
onShow() {
let address = getCache('address')
if (address) {
this.deliveryAddress = address
this.deliveryAddress.addressId = address.id
}
},
methods: {
go2,
back,
selectPayMethod(type) {
this.currentPayType = type
},
selectInvoice(type) {
this.isInvoice = type
if (!type) {
//
if (this.noInvoiceInfo) {
this.orderInfo = this.noInvoiceInfo
} else {
//
calcNotInvoiceOrderInfo({
customerOrderId: this.orderInfo.orderId,
invoiceOrNot: invoiceStatusEnum.NO_INVOICE // 1:
}).then((res) => {
if (res) {
this.noInvoiceInfo = res
this.orderInfo = res
}
})
}
} else {
this.orderInfo = this.invoiceInfo
}
},
submitOrder() {
if (this.currentPayType == null) {
uni.showToast({
title: '请选择支付方式',
icon: 'none'
})
return
}
if (this.loading) {
return
}
if (!this.deliveryAddress.addressId) {
uni.showToast({
title: '请选择收货地址',
icon: 'none'
})
return
}
this.loading = true
let itemsRemarkList = []
//
for (let target of this.orderInfo.supplierOrder) {
target.orderItems.forEach((item) => {
itemsRemarkList.push({ customerOderItemId: item.customerOderItemId, remark: item.remark })
})
}
submitClientOrder({
deliveryAddress: this.deliveryAddress,
itemsRemarkList,
orderId: this.orderInfo.orderId,
paymentMethod: this.payMap[this.currentPayType].value,
receivedTime: this.orderInfo.receivedTime,
invoiceOrNot: this.isInvoice ? invoiceStatusEnum.INVOICE : invoiceStatusEnum.NO_INVOICE
})
.then((res) => {
if (res) {
uni.showToast({
title: '前往签约',
icon: 'success',
success: () => {
setTimeout(() => {
window.location.href = res.signUrl
}, 1000)
}
})
}
})
.finally(() => {
this.loading = false
})
},
init() {
//
getMonthCredit({
enterpriseId: this.$store.state.companyInfo.id,
supplierId: this.$store.state.supplierId
}).then((res) => {
if (res) {
if (res.supplierCredit !== null) {
this.payMap['month'].availableCreditLine = res.supplierCredit
} else {
this.payMap['month'] = null
}
} else {
this.payMap['month'] = null
}
})
//
getFsCredit({
enterpriseId: this.$store.state.companyInfo.id
}).then((res) => {
if (isObject(res)) {
this.payMap['fs'].availableCreditLine = res.availableCreditLine
} else {
this.payMap['fs'] = null
}
})
//
getDefaultAddress({ enterpriseId: this.$store.state.companyInfo.id }).then((res) => {
if (res) {
this.deliveryAddress = res
this.deliveryAddress.addressId = res.id
}
})
}
}
}
</script>
<style lang="scss" scoped>
.address-area {
width: 750rpx;
padding: 0 32rpx;
background-color: #fff;
.header {
width: 686rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 24rpx 0 40rpx;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
.img {
width: 100rpx;
height: 100rpx;
flex-grow: 0;
flex-shrink: 0;
margin-right: 20rpx;
}
.text {
font-size: 30rpx;
color: #333333;
font-weight: 600;
}
}
.address-content {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 24rpx 0;
.left {
width: 72rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
flex-grow: 0;
flex-shrink: 0;
}
.center {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
flex-grow: 1;
flex-shrink: 1;
margin: 0 38rpx 0 24rpx;
}
.right {
width: 40rpx;
height: 40rpx;
flex-grow: 0;
flex-shrink: 0;
}
}
}
.order-area {
width: 750rpx;
background-color: #fff;
padding-bottom: 14rpx;
.header {
width: 750rpx;
height: 88rpx;
background-color: #e5f1ff;
padding: 24rpx 32rpx;
}
.order-header {
width: 750rpx;
padding: 24rpx 32rpx;
border-bottom: 2rpx dashed #d8d8d8;
margin-bottom: 20rpx;
}
.order-row {
width: 750rpx;
padding: 0 32rpx;
margin-bottom: 18rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
color: #555555;
}
}
.timer-area {
margin-top: 20rpx;
width: 750rpx;
padding: 0rpx 32rpx;
height: 88rpx;
background-color: #fff;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
text-align: right;
}
.tax-area {
margin-top: 20rpx;
width: 750rpx;
padding: 0rpx 32rpx;
height: 88rpx;
background-color: #fff;
.text {
font-size: 30rpx;
color: #000000;
}
.switch-icon {
width: 40rpx;
height: 40rpx;
margin-right: 16rpx;
}
}
.pay-area {
background-color: #fff;
margin-top: 20rpx;
.pay-item {
width: 750rpx;
padding: 20rpx 32rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
.left {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
}
.img {
width: 40rpx;
height: 40rpx;
flex-grow: 0;
flex-shrink: 0;
}
}
}
.button-area {
width: 750rpx;
height: 88rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
.text-line {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
}
.button {
width: 320rpx;
height: 88rpx;
border-radius: 48rpx;
background-color: #007aff;
font-size: 36rpx;
font-weight: 500;
color: #fff;
text-align: center;
line-height: 88rpx;
}
}
</style>

749
pages/paper-details/index.vue

@ -0,0 +1,749 @@
<template>
<view class="wrapper">
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="纸品详情"></uni-nav-bar>
<view class="swiper-dot">
<uni-swiper-dot :info="info.imgList" :current="current" field="content" mode="indexes" style="height: 100%">
<swiper class="swiper-box" @change="swiperChange" style="height: 100%">
<swiper-item v-for="(item, index) in info.imgList" :key="index">
<view @tap="item != '' && previewImg(index, info.imgList)">
<image class="image" :src="item || 'https://qncloud.oss-cn-shenzhen.aliyuncs.com/paper_shopkeeper/paper-default.png'" mode=""></image>
</view>
</swiper-item>
</swiper>
</uni-swiper-dot>
</view>
<view class="info-box">
<view class="info">
<view class="price-row">
<text class="price">¥{{ info.skuList[0] ? info.skuList[0].listPrice : '-' }}</text>
<text class="unit">/{{ (info.skuList[0] ? info.skuList[0].stockUnit : '-') | stockUnit }}</text>
</view>
<view class="row">
<view class="name">{{ info.name }}</view>
</view>
</view>
<view class="list-box">
<view class="label">克重</view>
<view style="width: 600rpx; overflow-x: auto" class="flex-row-center-start">
<view class="tag-box" v-for="(tItem, tIndex) in info.skuList" :key="tIndex">
<text>{{ tItem.weight }}g</text>
</view>
</view>
</view>
<view class="list-box">
<view class="label" style="font-size: 24rpx">规格</view>
<view class="tag-box"><text>787*1092</text></view>
<view class="tag-box"><text>899*1194</text></view>
</view>
</view>
<view class="other">
<view class="title">商品卖点</view>
<view class="desc">{{ info.sellingProposition }}</view>
</view>
<view class="other">
<view class="title">商品描述</view>
<view class="desc">{{ info.description }}</view>
</view>
<view class="other">
<view class="title">送货说明</view>
<view class="desc">{{ info.shippingNote }}</view>
</view>
<view class="other" style="border: none">
<view class="title">其他说明</view>
<view class="desc">{{ info.otherNote }}</view>
</view>
<qn-footer fixed height="100rpx">
<view class="footer-row">
<view class="left">
<view @click="storeTap">
<image class="icon" src="/static/imgs/paperDetails/shop-icon.png"></image>
<view class="label">店铺</view>
</view>
<view @click="shoppingCartTap">
<image class="icon" src="/static/imgs/paperDetails/shopping-trolley.png"></image>
<view class="label">购物车</view>
</view>
<view @click="addShoppingTap(1)">
<image class="icon" src="/static/imgs/paperDetails/add-shopping-trolley.png"></image>
<view class="label">加购物车</view>
</view>
</view>
<view class="right">
<view class="inquiry-btn" @tap="inquiryTap">立即询单</view>
<view class="book-btn" @tap="addShoppingTap(2)">立即订购</view>
</view>
</view>
</qn-footer>
<uni-popup ref="popup" type="bottom">
<view class="popup_modal">
<view class="card-box">
<view class="box">
<view class="right-box">
<view class="title-row">
<view class="name">{{ info.name }}</view>
<view class="close-icon" @tap="closeTap"><uni-icons size="20" type="close" color="#888888"></uni-icons></view>
</view>
<view class="price">¥{{ buyPaperDto.unitPrice }}</view>
</view>
</view>
</view>
<view class="choose-box">
<view class="label">
请选择克重
<text class="note">库存{{ info.skuList[kgActive].stock }}{{ info.skuList[kgActive].stockUnit | stockUnit }}</text>
</view>
<view class="flex-row-center-start" style="width: 684rpx; overflow-x: auto">
<view
:class="['tag-box', kgActive === kIndex ? 'kg-select' : '']"
v-for="(kItem, kIndex) in info.skuList"
:key="kIndex"
@tap="weightTap(kItem, kIndex)"
>
{{ kItem.weight }}g
</view>
</view>
</view>
<view class="choose-box">
<view class="label">请选择规格</view>
<view class="tag-row">
<view
:class="['tag-box', specificationObj.active === sIndex ? 'kg-select' : '']"
v-for="(sItem, sIndex) in specificationList"
:key="sIndex"
@tap="specificationTap(sItem, sIndex)"
>
{{ sItem.name }}
</view>
</view>
<view class="input-row">
<view style="flex: 1 1 auto">
<qn-easyinput :inputBorder="false" class="easyinput" type="number" v-model="buyPaperDto.width" placeholder="请输入"></qn-easyinput>
</view>
<view class="symbol">x</view>
<view style="flex: 1 1 auto">
<qn-easyinput :inputBorder="false" class="easyinput" type="number" v-model="buyPaperDto.length" placeholder="请输入"></qn-easyinput>
</view>
</view>
</view>
<view class="quantity-row">
<view class="label">购买数量()</view>
<view><qn-input-number @input="change" /></view>
</view>
<view class="ygzl-text">预估重量{{ buyTon }}</view>
<view class="popup-footer-row"><view class="btn" @tap="confirm">确认</view></view>
</view>
</uni-popup>
</view>
</template>
<script>
import { go2, back } from '@/utils/hook.js'
import { getPaperDetail, createGoodsReserve, createShoppingCar } from '@/apis/paperDetailsApi.js'
import { round } from '@/utils/index.js'
import { fddEnterpriseStatus, paperUnitMap } from '@/enums/index.js'
import { getVerifyUrl } from '@/apis/commonApi.js'
const validateFields = [
{
value: 'length',
label: '纸品长度'
},
{
value: 'width',
label: '纸品宽度'
},
{
value: 'gramWeight',
label: '纸品克重'
},
{
value: 'pieceQuantity',
label: '购买数量'
}
]
export default {
data() {
return {
current: 0,
weightList: ['240', '250', '280'],
specificationList: [
{
name: '正度',
width: '787',
length: '1092',
disabled: true
},
{
name: '大度',
width: '889',
length: '1194',
disabled: true
},
{
name: '特规分切',
width: '',
length: '',
disabled: false
}
],
kgActive: 0,
specificationObj: {
active: 0,
width: '787',
length: '1092',
disabled: true
},
value: null,
params: {
productId: ''
},
buyPaperDto: {
buyTon: '',
gramWeight: '',
length: '',
mallSupplierId: '',
pieceQuantity: '',
productId: '',
productSkuId: '',
unitPrice: '',
width: '',
img: '',
listPrice: '',
name: ''
},
shoppingCarType: 1, // 1 2
info: {
skuList: [{}]
}
}
},
filters: {
stockUnit(value) {
return paperUnitMap[value]
}
},
onLoad(option) {
if (option.paperId) {
this.params.productId = option.paperId
if (this.hasLogin) {
this.queryData()
} else {
this.$store.commit('setNextPage', { name: 'paper-details', data: { paperId: option.paperId } })
go2('login', {}, true)
}
} else {
uni.showToast({
title: '参数错误',
icon: 'fail',
success: () => {
back()
}
})
}
},
computed: {
buyTon() {
let num = 0
num = round(this.buyPaperDto.gramWeight * this.buyPaperDto.width * this.buyPaperDto.length * this.buyPaperDto.pieceQuantity * 1e-12, 4)
return num
},
hasCompany() {
return this.$store.state.companyInfo.id != null
},
hasLogin() {
return this.$store.state.qnToken != ''
}
},
watch: {
buyTon(newVal) {
this.buyPaperDto.buyTon = newVal
}
},
methods: {
back,
//
queryData() {
getPaperDetail(this.params).then((res) => {
console.log('店铺纸品详情', res)
if (res) {
this.info = res
if (!this.info.imgList || this.info.imgList.length == 0) {
this.info.imgList = ['']
}
}
})
},
//
storeTap() {
go2('store')
},
//
shoppingCartTap() {
go2('cart')
},
//
addShoppingTap(type) {
if (!this.hasCompany) {
uni.showModal({
title: '提示',
content: '请先完善公司信息',
success: (res) => {
if (res.confirm) {
go2('enterprise-info')
}
}
})
return
}
if (this.$store.state.companyInfo.fddEnterpriseStatus != fddEnterpriseStatus.CERTIFIED_SUCCESS) {
uni.showModal({
title: '提示',
content: '请先进行法大大认证',
success: (res) => {
if (res.confirm) {
getVerifyUrl({ enterpriseId: this.$store.state.companyInfo.id }).then((url) => {
if (url) {
// #ifdef APP-PLUS
go2('page-view', {
title: '实名认证',
url: encodeURIComponent(url)
})
// #endif
// #ifdef H5
window ? (window.location.href = url) : ''
// #endif
}
})
}
}
})
return
}
this.shoppingCarType = type
this.buyPaperDto = {
buyTon: 0,
gramWeight: this.info.skuList[0].weight,
length: this.specificationObj.length,
mallSupplierId: this.info.supplierId,
pieceQuantity: 0,
productId: this.info.id,
productSkuId: this.info.skuList[0].id,
unitPrice: this.info.skuList[0].listPrice,
width: this.specificationObj.width
}
this.$refs.popup.open('bottom')
},
//
inquiryTap() {
if (!this.hasCompany) {
uni.showToast({
title: '请先完善公司信息',
icon: 'none'
})
return
}
go2('for-comparison', { id: this.info.supplierId, productImg: this.info.imgList[0] })
},
closeTap() {
this.$refs.popup.close()
},
//
weightTap(item, index) {
this.kgActive = index
this.buyPaperDto.gramWeight = item.weight
this.buyPaperDto.unitPrice = item.listPrice
this.buyPaperDto.productSkuId = item.id
},
//
specificationTap(item, index) {
this.specificationObj.active = index
this.specificationObj.width = item.width
this.specificationObj.length = item.length
this.specificationObj.disabled = item.disabled
this.buyPaperDto.width = item.width
this.buyPaperDto.length = item.length
},
/**
* @param {Number} num
* 计数器返回值
*/
change(num) {
this.buyPaperDto.pieceQuantity = num || 0
},
//
confirm() {
//
for (let item of validateFields) {
if (!this.buyPaperDto[item.value]) {
uni.showToast({
title: item.label + '必须大于0',
icon: 'none'
})
return
}
}
//
if (this.shoppingCarType == 1) {
const params = {
length: this.buyPaperDto.length,
productId: this.info.id,
productSkuId: this.buyPaperDto.productSkuId,
quantity: this.buyPaperDto.pieceQuantity,
supplierId: this.info.supplierId,
width: this.buyPaperDto.width,
enterpriseId: this.$store.state.companyInfo.id,
userId: this.$store.state.userInfo.userId
}
// console.log('', params)
createShoppingCar(params).then((res) => {
if (res) {
uni.showToast({
title: '加入成功!',
icon: 'success'
})
this.$refs.popup.close()
}
})
} else {
//
const params = {
orderGoodsList: [{ ...this.buyPaperDto }],
purchaserEnterpriseId: this.$store.state.companyInfo.id
}
createGoodsReserve(params).then((res) => {
if (res) {
uni.showToast({
title: '订购成功!',
icon: 'success'
})
this.$refs.popup.close()
setTimeout(() => {
go2('order-make', { orderId: res.orderId })
}, 1000)
}
})
}
},
//
swiperChange(e) {
this.current = e.detail.current
},
previewImg(index, list) {
uni.previewImage({
urls: list,
current: index
})
}
}
}
</script>
<style lang="scss">
.wrapper {
.swiper-dot {
width: 100%;
height: 500rpx;
}
.image {
width: 100%;
height: 500rpx;
}
.info-box {
margin: 20rpx 0;
height: 370rpx;
background: #ffffff;
.info {
padding: 0rpx 32rpx;
.price-row {
padding: 20rpx 0rpx;
}
.price {
font-size: 48rpx;
color: #f5222d;
letter-spacing: 0;
text-align: left;
font-weight: 500;
}
.unit {
font-size: 28rpx;
color: #f5222d;
letter-spacing: 0;
text-align: left;
font-weight: 400;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
.name {
font-size: 34rpx;
color: #000000;
letter-spacing: 0;
text-align: left;
font-weight: 600;
}
.value {
font-size: 24rpx;
color: rgba(0, 0, 0, 0.55);
letter-spacing: 0;
text-align: left;
font-weight: 400;
}
}
}
.list-box {
margin: 0rpx 32rpx;
height: 104rpx;
display: flex;
flex-direction: row;
align-items: center;
border-top: 2rpx solid rgba($color: #dddddd, $alpha: 0.8);
.label {
flex: 0 0 84rpx;
font-size: 28rpx;
color: #333333;
letter-spacing: 0;
text-align: left;
font-weight: 500;
}
.tag-box {
height: 60rpx;
line-height: 60rpx;
text-align: center;
background: #f4f5f6;
border-radius: 4rpx;
font-size: 28rpx;
color: #555555;
letter-spacing: 0;
font-weight: 400;
margin-right: 10rpx;
padding: 0rpx 17rpx;
}
}
}
.other {
padding: 0rpx 32rpx;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
background: #ffffff;
.title {
font-size: 28rpx;
color: #000000;
letter-spacing: 0;
font-weight: 500;
padding: 24rpx 0rpx 16rpx 0rpx;
}
.desc {
font-size: 28rpx;
color: #333333;
letter-spacing: 0;
font-weight: 400;
padding: 0rpx 0rpx 24rpx 0rpx;
}
}
.footer-row {
display: flex;
flex-direction: row;
// align-items: center;
justify-content: space-between;
padding: 0rpx 32rpx;
.left {
flex: 0 0 294rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
text-align: center;
padding-right: 24rpx;
.icon {
width: 40rpx;
height: 40rpx;
}
.label {
font-size: 22rpx;
color: #555555;
letter-spacing: 0;
font-weight: 400;
padding-top: 6rpx;
}
}
.right {
display: flex;
flex-direction: row;
align-items: center;
font-size: 28rpx;
color: #ffffff;
letter-spacing: 0;
text-align: center;
font-weight: 400;
.inquiry-btn {
width: 200rpx;
height: 80rpx;
line-height: 80rpx;
background: #faab0c;
border-top-left-radius: 2002000rpx;
border-bottom-left-radius: 2002000rpx;
}
.book-btn {
width: 200rpx;
height: 80rpx;
line-height: 80rpx;
background: #ee0a24;
border-top-right-radius: 2002000rpx;
border-bottom-right-radius: 2002000rpx;
}
}
}
.popup_modal {
// height: 960rpx;
background: #ffffff;
border-radius: 20rpx 20rpx 0 0;
.card-box {
padding: 0rpx 32rpx;
.box {
display: flex;
flex-direction: row;
// align-items: center;
// height: 240rpx;
background: #ffffff;
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
padding: 40rpx 0rpx;
.image {
flex: 0 0 160rpx;
width: 160rpx;
height: 160rpx;
border-radius: 10px;
margin-right: 20rpx;
}
.right-box {
flex: 1;
width: 100%;
padding-top: 10rpx;
}
.title-row {
display: flex;
flex-direction: row;
justify-content: space-between;
.name {
font-size: 34rpx;
color: #000000;
letter-spacing: 0;
text-align: left;
font-weight: 600;
padding-bottom: 30rpx;
}
.close-icon {
position: relative;
top: -20rpx;
}
}
.price {
font-size: 40rpx;
color: #f5222d;
letter-spacing: 0;
text-align: left;
font-weight: 600;
}
}
}
.choose-box {
border-bottom: 2rpx solid rgba(221, 221, 221, 0.5);
padding: 24rpx 32rpx;
.label {
font-size: 30rpx;
color: rgba(0, 0, 0, 0.85);
letter-spacing: 0;
text-align: left;
font-weight: 400;
padding: 0rpx 0rpx 20rpx 0rpx;
}
.tag-row {
display: flex;
flex-direction: row;
align-items: center;
}
.tag-box {
padding: 0rpx 47rpx;
height: 60rpx;
line-height: 60rpx;
background: #f5f5f5;
border-radius: 8px;
margin-right: 12rpx;
font-size: 28rpx;
color: rgba(0, 0, 0, 0.75);
text-align: center;
font-weight: 400;
}
.kg-select {
background: #1890ff;
color: #ffffff;
}
.input-row {
display: flex;
flex-direction: row;
align-items: center;
padding-top: 20rpx;
.easyinput {
height: 64rpx;
background: #f5f5f5;
border-radius: 8rpx;
}
.symbol {
padding: 0rpx 16rpx;
font-size: 32rpx;
color: rgba(0, 0, 0, 0.85);
font-weight: 400;
}
}
}
.quantity-row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 32rpx 32rpx 0rpx 32rpx;
.label {
font-size: 30rpx;
color: rgba(0, 0, 0, 0.85);
letter-spacing: 0;
font-weight: 400;
}
}
.ygzl-text {
padding: 20rpx 32rpx 0rpx;
display: flex;
flex-direction: row;
justify-content: flex-end;
font-family: PingFangSC-Regular;
font-size: 24rpx;
color: rgba(0, 0, 0, 0.5);
font-weight: 400;
}
.popup-footer-row {
display: flex;
flex-direction: row;
justify-content: center;
padding: 48rpx 32rpx 20rpx 32rpx;
.btn {
width: 686rpx;
height: 96rpx;
line-height: 96rpx;
text-align: center;
background: #007aff;
border-radius: 10rpx;
font-size: 36rpx;
color: #ffffff;
font-weight: 500;
}
}
}
.note {
margin-left: 16rpx;
font-size: 24rpx;
color: rgba(0, 0, 0, 0.55);
letter-spacing: 0;
text-align: left;
font-weight: 400;
}
}
</style>

2
pages/production-operation/index.vue

@ -1,6 +1,6 @@
<template>
<view class="content">
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed :title="operation == 'add' ? '新增设备' : '编辑设备'"></uni-nav-bar>
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed :title="operation == 'add' ? '新增产品' : '编辑产品'"></uni-nav-bar>
<view class="form">
<view class="flex-col group_9">
<view class="flex-row group_10">

353
pages/store/index.vue

@ -0,0 +1,353 @@
<template>
<view class="wrapper">
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="店铺首页"></uni-nav-bar>
<view class="top-box">
<view>
<image class="image" :src="customerInfo.logo || 'https://qncloud.oss-cn-shenzhen.aliyuncs.com/paper_shopkeeper/paper-default-small.png'"></image>
</view>
<view class="center">
<view class="title">{{ customerInfo.name }}</view>
<view class="desc">全部商品 {{ customerInfo.productNumber }} &nbsp; | &nbsp;上新 {{ customerInfo.currentProductNumber }}</view>
</view>
</view>
<view class="search-box">
<uni-easyinput
v-model="enterpriseName"
:inputBorder="false"
:clearSize="18"
:placeholderStyle="'font-size:25rpx;text-align: center;font-weight: 400;color: rgba(34,34,34,0.75);'"
placeholder="搜索"
confirmType="search"
type="text"
class="easyinput"
prefixIcon="search"
@input="searchConfirm"
/>
</view>
<scroll-list ref="list" :option="option" @load="upCallback" @refresh="downCallback" style="background-color: #ffffff">
<view class="content flex-row-start-start">
<view class="box" v-for="(item, index) in list" :key="index" @tap="seeDetailsTap(item)" :style="{ marginRight: index % 2 != 0 ? '0' : '20rpx' }">
<view class="image-box">
<view><image class="special-img" :src="item.isPromoting ? '/static/imgs/store/special-offe.png' : ''" mode=""></image></view>
<image
class="image"
:src="item.litPicUrl || 'https://qncloud.oss-cn-shenzhen.aliyuncs.com/paper_shopkeeper/paper-default-small.png'"
mode=""
></image>
</view>
<view class="title">{{ item.name }}</view>
<view class="desc">
<view>
<image class="icon" src="/static/imgs/store/address-icon.png"></image>
<text style="padding-left: 6rpx">{{ customerInfo.area }}</text>
</view>
</view>
<view class="footer">
<view class="left">
<text class="price price-single">{{ transformPrice(item.priceRange) }}</text>
</view>
<view class="btn">马上抢</view>
</view>
</view>
</view>
</scroll-list>
</view>
</template>
<script>
import qnHeader from '@/components/qn-header/qn-header.vue'
import { loginGo2, back } from '@/utils/hook.js'
import { getCustomer, getPaperList } from '@/apis/mallApi.js'
export default {
components: { qnHeader },
data() {
return {
option: {
size: 10,
auto: true,
emptyText: '暂无数据~',
background: '#F7F8FA',
disabled: false
},
params: {
asc: '',
desc: '',
name: '',
supplierId: this.$store.state.supplierId || null
},
pagination: {
pageNum: 0, //
pageSize: 10
},
enterpriseName: '',
list: [],
customerParams: {
supplierId: this.$store.state.supplierId || null
},
customerInfo: {},
timer: null
}
},
methods: {
back,
seeDetailsTap(item) {
loginGo2('paper-details', { paperId: item.id })
},
//
getCustomer() {
getCustomer(this.customerParams).then((res) => {
if (res) {
this.customerInfo = res
}
})
},
getList() {
return new Promise((resolve, reject) => {
getPaperList({ ...this.params, ...this.pagination })
.then((res) => {
console.log('纸品列表', res)
if (res) {
if (res.current == 1) {
this.list = res.records
} else {
this.list = this.list.concat(res.records)
}
resolve({ list: this.list, total: res.total })
} else {
reject()
}
})
.catch((err) => {
reject(err)
})
})
},
downCallback() {
this.pagination.pageNum = 1
this.getList()
.then(({ list, total }) => {
this.$refs.list.refreshSuccess({ list, total })
})
.catch(() => {
this.$refs.list.refreshFail()
})
},
upCallback() {
this.pagination.pageNum++
this.getList()
.then(({ list, total }) => {
this.$refs.list.loadSuccess({ list, total })
})
.catch(() => {
this.$refs.list.loadFail()
})
},
searchConfirm(value) {
this.params.name = value
if (this.timer) {
clearTimeout(this.timer)
this.timer = null
}
this.timer = setTimeout(() => {
this.downCallback()
}, 500)
},
transformPrice(value) {
return `¥${value}`
}
},
onShow() {
this.getCustomer()
}
}
</script>
<style lang="scss">
.wrapper {
.header {
justify-content: space-between;
.header-title {
font-size: 36rpx;
color: #000000;
letter-spacing: 0;
text-align: center;
font-weight: 500;
}
.right-title {
font-size: 28rpx;
color: #007aff;
text-align: center;
line-height: 40rpx;
font-weight: 500;
}
}
.top-box {
display: flex;
flex-direction: row;
align-items: center;
// justify-content: space-around;
height: 180rpx;
background: url('/static/imgs/store/store-icon.png') no-repeat;
background-size: 100%;
.image {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
margin-left: 32rpx;
}
.right {
width: 140rpx;
}
.center {
padding-left: 20rpx;
}
.title {
font-size: 34rpx;
color: #ffffff;
letter-spacing: 2rpx;
font-weight: 600;
padding-bottom: 12rpx;
}
.desc {
opacity: 0.75;
font-size: 28rpx;
color: #ffffff;
letter-spacing: 0;
font-weight: 500;
padding-right: 32rpx;
padding-top: 12rpx;
}
.cut {
display: flex;
align-items: center;
font-size: 24rpx;
color: #ffffff;
letter-spacing: 0;
text-align: center;
font-weight: 400;
.cut-icon {
width: 29.42rpx;
height: 26.67rpx;
margin-left: 10rpx;
}
}
.set {
opacity: 0.75;
font-size: 28rpx;
color: #ffffff;
letter-spacing: 0;
font-weight: 500;
position: relative;
top: 39rpx;
left: 60rpx;
}
}
.search-box {
display: flex;
align-items: center;
justify-content: center;
padding: 0rpx 32rpx;
height: 104rpx;
background: #ffffff;
.easyinput {
height: 72rpx;
background: #f5f6f7;
border-radius: 16rpx;
}
}
.content {
display: flex;
flex-wrap: wrap;
padding: 0rpx 32rpx 20rpx 32rpx;
.box {
// height: 514rpx;
width: 330rpx;
background: #ffffff;
box-shadow: 0rpx 8rpx 28rpx 0rpx rgba(112, 112, 112, 0.1);
border-radius: 10rpx;
margin-bottom: 20rpx;
.special-img {
width: 110rpx;
height: 110rpx;
position: absolute;
z-index: 10;
}
.image {
width: 330rpx;
height: 330rpx;
z-index: 9;
border-top-left-radius: 10rpx;
}
.title {
padding: 0rpx 16rpx;
font-size: 28rpx;
color: #000000;
letter-spacing: 0;
font-weight: 500;
padding-top: 10rpx;
}
.desc {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-size: 20rpx;
color: #333333;
letter-spacing: 0;
font-weight: 400;
padding: 16rpx 16rpx 10rpx 16rpx;
.icon {
width: 16rpx;
height: 16rpx;
}
}
.footer {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 10rpx 16rpx 37rpx 16rpx;
.left {
flex-grow: 1;
flex-shrink: 1;
}
.price {
color: #f5222d;
letter-spacing: 0;
font-weight: 600;
}
.price-single {
font-size: 34rpx;
}
.price-range {
font-size: 24rpx;
}
.unit {
font-size: 24rpx;
color: #f5222d;
letter-spacing: 0;
text-align: left;
font-weight: 400;
}
.btn {
flex-grow: 0;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
// text-align: center;
width: 108rpx;
height: 48rpx;
background: #ff4849;
border-radius: 27rpx;
font-size: 26rpx;
color: #ffffff;
letter-spacing: 0;
font-weight: 400;
}
}
}
}
}
</style>

BIN
static/imgs/cart/no-data-icon.png

Before After
Width: 560  |  Height: 320  |  Size: 38 KiB

BIN
static/imgs/cart/shopping-cart-not-select.png

Before After
Width: 32  |  Height: 32  |  Size: 994 B

BIN
static/imgs/cart/shopping-cart-select.png

Before After
Width: 32  |  Height: 32  |  Size: 1.1 KiB

BIN
static/imgs/digital-workshops/.DS_Store

BIN
static/imgs/digital-workshops/camera-tip-bg.png

Before After
Width: 296  |  Height: 182  |  Size: 8.3 KiB

BIN
static/imgs/mall/cart-icon.png

Before After
Width: 82  |  Height: 82  |  Size: 4.7 KiB

BIN
static/imgs/mall/top-bg.png

Before After
Width: 750  |  Height: 170  |  Size: 114 KiB

BIN
static/imgs/order/.DS_Store

BIN
static/imgs/order/address-icon.png

Before After
Width: 66  |  Height: 66  |  Size: 4.5 KiB

BIN
static/imgs/order/camera.png

Before After
Width: 56  |  Height: 56  |  Size: 1.7 KiB

BIN
static/imgs/order/customer-default.png

Before After
Width: 150  |  Height: 150  |  Size: 14 KiB

BIN
static/imgs/order/edit-address-icon.png

Before After
Width: 40  |  Height: 40  |  Size: 949 B

BIN
static/imgs/order/fs-pay-icon.png

Before After
Width: 40  |  Height: 40  |  Size: 1.2 KiB

BIN
static/imgs/order/location-icon.png

Before After
Width: 16  |  Height: 16  |  Size: 782 B

BIN
static/imgs/order/month-pay-icon.png

Before After
Width: 40  |  Height: 40  |  Size: 903 B

BIN
static/imgs/order/order-empty.png

Before After
Width: 560  |  Height: 560  |  Size: 45 KiB

BIN
static/imgs/order/paper-default-icon.png

Before After
Width: 100  |  Height: 100  |  Size: 16 KiB

BIN
static/imgs/order/right-arrow.png

Before After
Width: 32  |  Height: 32  |  Size: 604 B

BIN
static/imgs/order/select-icon.png

Before After
Width: 32  |  Height: 32  |  Size: 929 B

BIN
static/imgs/order/selected-icon.png

Before After
Width: 40  |  Height: 40  |  Size: 1.5 KiB

BIN
static/imgs/order/status-icon.png

Before After
Width: 40  |  Height: 40  |  Size: 1.0 KiB

BIN
static/imgs/order/wxpay-icon.png

Before After
Width: 40  |  Height: 40  |  Size: 1.2 KiB

BIN
static/imgs/paperDetails/add-shopping-trolley.png

Before After
Width: 40  |  Height: 40  |  Size: 954 B

BIN
static/imgs/paperDetails/shop-icon.png

Before After
Width: 40  |  Height: 40  |  Size: 969 B

BIN
static/imgs/paperDetails/shopping-trolley.png

Before After
Width: 40  |  Height: 40  |  Size: 922 B

BIN
static/imgs/store/address-icon.png

Before After
Width: 32  |  Height: 32  |  Size: 1.5 KiB

BIN
static/imgs/store/special-offe.png

Before After
Width: 110  |  Height: 110  |  Size: 3.0 KiB

BIN
static/imgs/store/store-icon.png

Before After
Width: 750  |  Height: 180  |  Size: 33 KiB

24
store/index.js

@ -17,13 +17,18 @@ let qnToken = null,
* @value fddEnterpriseStatus 法大大认证状态 1未认证2认证进行中3认证成功4认证失败
*/
companyInfo = null,
uecToken = null
uecToken = null,
/**
* @value supplierId 当前进入的店铺的供应商id
*/
supplierId = null
const companyInfoParams = ['id', 'name', 'fddEnterpriseStatus', 'enterpriseType']
const userInfoParams = ['name', 'userId', 'mobile', 'avatar']
try {
uecToken = uni.getStorageSync('uecToken')
qnToken = uni.getStorageSync('qnToken')
userInfo = uni.getStorageSync('userInfo')
supplierId = uni.getStorageSync('supplierId')
if (userInfo) {
userInfo = JSON.parse(userInfo)
}
@ -43,6 +48,7 @@ if (!store) {
uecToken: uecToken || '',
qnToken: qnToken || '', // token
userInfo: userInfo || {}, // 用户信息
supplierId: supplierId || '', // 供应商id
companyInfo: companyInfo || {}, // 纸盘商信息
nextPage: {
name: '',
@ -102,6 +108,22 @@ if (!store) {
console.warn('设置userInfo失败:', e)
}
},
setSupplierId(state, id) {
try {
uni.setStorageSync('supplierId', id)
state.supplierId = id
} catch (e) {
console.error('更改supplierId失败:', e)
}
},
removeSupplierId(state) {
try {
uni.removeStorageSync('supplierId')
state.supplierId = ''
} catch (e) {
console.error('删除supplierId失败:', e)
}
},
/**
* 更改当前用户信息
* @param {*} state 状态

16
utils/http/index.js

@ -1,6 +1,7 @@
import Http from './http.js'
import env from '@/env/index.js'
import { XAPPID } from '@/enums/index.js'
import { XAPPID, encryptType } from '@/enums/index.js'
import { md5 } from '@/utils/md5.js'
// 请求封装文件
const urlEnv = env === 'production' ? '' : `-${env}`
@ -28,7 +29,9 @@ const config = {
// 是否返回原始数据
isReturnNativeResponse: false,
// 需要对返回数据进行处理
isTransformResponse: true
isTransformResponse: true,
// 是否加密
isEncrypt: false
}
}
@ -74,6 +77,15 @@ const reqInterceptor = (config, options) => {
title: '加载中...'
})
}
if (options.isEncrypt) {
let data = config.data
const signStr = JSON.stringify(data)
const signStrMore = `&Authorization=${token}&X-APP-ID=${XAPPID}`
const sign = md5(JSON.stringify(data) + signStrMore)
data.sign = sign
data.signStr = signStr
data.signType = encryptType.MD5
}
return config
}

229
utils/md5.js

@ -0,0 +1,229 @@
export function md5(string) {
function RotateLeft(lValue, iShiftBits) {
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits))
}
function AddUnsigned(lX, lY) {
let lX4, lY4, lX8, lY8, lResult
lX8 = lX & 0x80000000
lY8 = lY & 0x80000000
lX4 = lX & 0x40000000
lY4 = lY & 0x40000000
lResult = (lX & 0x3fffffff) + (lY & 0x3fffffff)
if (lX4 & lY4) {
return lResult ^ 0x80000000 ^ lX8 ^ lY8
}
if (lX4 | lY4) {
if (lResult & 0x40000000) {
return lResult ^ 0xc0000000 ^ lX8 ^ lY8
} else {
return lResult ^ 0x40000000 ^ lX8 ^ lY8
}
} else {
return lResult ^ lX8 ^ lY8
}
}
function F(x, y, z) {
return (x & y) | (~x & z)
}
function G(x, y, z) {
return (x & z) | (y & ~z)
}
function H(x, y, z) {
return x ^ y ^ z
}
function I(x, y, z) {
return y ^ (x | ~z)
}
function FF(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac))
return AddUnsigned(RotateLeft(a, s), b)
}
function GG(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac))
return AddUnsigned(RotateLeft(a, s), b)
}
function HH(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac))
return AddUnsigned(RotateLeft(a, s), b)
}
function II(a, b, c, d, x, s, ac) {
a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac))
return AddUnsigned(RotateLeft(a, s), b)
}
function ConvertToWordArray(string) {
let lWordCount
let lMessageLength = string.length
let lNumberOfWords_temp1 = lMessageLength + 8
let lNumberOfWords_temp2 =
(lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64
let lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16
let lWordArray = Array(lNumberOfWords - 1)
let lBytePosition = 0
let lByteCount = 0
while (lByteCount < lMessageLength) {
lWordCount = (lByteCount - (lByteCount % 4)) / 4
lBytePosition = (lByteCount % 4) * 8
lWordArray[lWordCount] =
lWordArray[lWordCount] |
(string.charCodeAt(lByteCount) << lBytePosition)
lByteCount++
}
lWordCount = (lByteCount - (lByteCount % 4)) / 4
lBytePosition = (lByteCount % 4) * 8
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition)
lWordArray[lNumberOfWords - 2] = lMessageLength << 3
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29
return lWordArray
}
function WordToHex(lValue) {
let WordToHexValue = '',
WordToHexValue_temp = '',
lByte,
lCount
for (lCount = 0; lCount <= 3; lCount++) {
lByte = (lValue >>> (lCount * 8)) & 255
WordToHexValue_temp = '0' + lByte.toString(16)
WordToHexValue =
WordToHexValue +
WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2)
}
return WordToHexValue
}
function Utf8Encode(string) {
string = string.replace(/\r\n/g, '\n')
let utftext = ''
for (let n = 0; n < string.length; n++) {
let c = string.charCodeAt(n)
if (c < 128) {
utftext += String.fromCharCode(c)
} else if (c > 127 && c < 2048) {
utftext += String.fromCharCode((c >> 6) | 192)
utftext += String.fromCharCode((c & 63) | 128)
} else {
utftext += String.fromCharCode((c >> 12) | 224)
utftext += String.fromCharCode(((c >> 6) & 63) | 128)
utftext += String.fromCharCode((c & 63) | 128)
}
}
return utftext
}
let x = Array()
let k, AA, BB, CC, DD, a, b, c, d
let S11 = 7,
S12 = 12,
S13 = 17,
S14 = 22
let S21 = 5,
S22 = 9,
S23 = 14,
S24 = 20
let S31 = 4,
S32 = 11,
S33 = 16,
S34 = 23
let S41 = 6,
S42 = 10,
S43 = 15,
S44 = 21
string = Utf8Encode(string)
x = ConvertToWordArray(string)
a = 0x67452301
b = 0xefcdab89
c = 0x98badcfe
d = 0x10325476
for (k = 0; k < x.length; k += 16) {
AA = a
BB = b
CC = c
DD = d
a = FF(a, b, c, d, x[k + 0], S11, 0xd76aa478)
d = FF(d, a, b, c, x[k + 1], S12, 0xe8c7b756)
c = FF(c, d, a, b, x[k + 2], S13, 0x242070db)
b = FF(b, c, d, a, x[k + 3], S14, 0xc1bdceee)
a = FF(a, b, c, d, x[k + 4], S11, 0xf57c0faf)
d = FF(d, a, b, c, x[k + 5], S12, 0x4787c62a)
c = FF(c, d, a, b, x[k + 6], S13, 0xa8304613)
b = FF(b, c, d, a, x[k + 7], S14, 0xfd469501)
a = FF(a, b, c, d, x[k + 8], S11, 0x698098d8)
d = FF(d, a, b, c, x[k + 9], S12, 0x8b44f7af)
c = FF(c, d, a, b, x[k + 10], S13, 0xffff5bb1)
b = FF(b, c, d, a, x[k + 11], S14, 0x895cd7be)
a = FF(a, b, c, d, x[k + 12], S11, 0x6b901122)
d = FF(d, a, b, c, x[k + 13], S12, 0xfd987193)
c = FF(c, d, a, b, x[k + 14], S13, 0xa679438e)
b = FF(b, c, d, a, x[k + 15], S14, 0x49b40821)
a = GG(a, b, c, d, x[k + 1], S21, 0xf61e2562)
d = GG(d, a, b, c, x[k + 6], S22, 0xc040b340)
c = GG(c, d, a, b, x[k + 11], S23, 0x265e5a51)
b = GG(b, c, d, a, x[k + 0], S24, 0xe9b6c7aa)
a = GG(a, b, c, d, x[k + 5], S21, 0xd62f105d)
d = GG(d, a, b, c, x[k + 10], S22, 0x2441453)
c = GG(c, d, a, b, x[k + 15], S23, 0xd8a1e681)
b = GG(b, c, d, a, x[k + 4], S24, 0xe7d3fbc8)
a = GG(a, b, c, d, x[k + 9], S21, 0x21e1cde6)
d = GG(d, a, b, c, x[k + 14], S22, 0xc33707d6)
c = GG(c, d, a, b, x[k + 3], S23, 0xf4d50d87)
b = GG(b, c, d, a, x[k + 8], S24, 0x455a14ed)
a = GG(a, b, c, d, x[k + 13], S21, 0xa9e3e905)
d = GG(d, a, b, c, x[k + 2], S22, 0xfcefa3f8)
c = GG(c, d, a, b, x[k + 7], S23, 0x676f02d9)
b = GG(b, c, d, a, x[k + 12], S24, 0x8d2a4c8a)
a = HH(a, b, c, d, x[k + 5], S31, 0xfffa3942)
d = HH(d, a, b, c, x[k + 8], S32, 0x8771f681)
c = HH(c, d, a, b, x[k + 11], S33, 0x6d9d6122)
b = HH(b, c, d, a, x[k + 14], S34, 0xfde5380c)
a = HH(a, b, c, d, x[k + 1], S31, 0xa4beea44)
d = HH(d, a, b, c, x[k + 4], S32, 0x4bdecfa9)
c = HH(c, d, a, b, x[k + 7], S33, 0xf6bb4b60)
b = HH(b, c, d, a, x[k + 10], S34, 0xbebfbc70)
a = HH(a, b, c, d, x[k + 13], S31, 0x289b7ec6)
d = HH(d, a, b, c, x[k + 0], S32, 0xeaa127fa)
c = HH(c, d, a, b, x[k + 3], S33, 0xd4ef3085)
b = HH(b, c, d, a, x[k + 6], S34, 0x4881d05)
a = HH(a, b, c, d, x[k + 9], S31, 0xd9d4d039)
d = HH(d, a, b, c, x[k + 12], S32, 0xe6db99e5)
c = HH(c, d, a, b, x[k + 15], S33, 0x1fa27cf8)
b = HH(b, c, d, a, x[k + 2], S34, 0xc4ac5665)
a = II(a, b, c, d, x[k + 0], S41, 0xf4292244)
d = II(d, a, b, c, x[k + 7], S42, 0x432aff97)
c = II(c, d, a, b, x[k + 14], S43, 0xab9423a7)
b = II(b, c, d, a, x[k + 5], S44, 0xfc93a039)
a = II(a, b, c, d, x[k + 12], S41, 0x655b59c3)
d = II(d, a, b, c, x[k + 3], S42, 0x8f0ccc92)
c = II(c, d, a, b, x[k + 10], S43, 0xffeff47d)
b = II(b, c, d, a, x[k + 1], S44, 0x85845dd1)
a = II(a, b, c, d, x[k + 8], S41, 0x6fa87e4f)
d = II(d, a, b, c, x[k + 15], S42, 0xfe2ce6e0)
c = II(c, d, a, b, x[k + 6], S43, 0xa3014314)
b = II(b, c, d, a, x[k + 13], S44, 0x4e0811a1)
a = II(a, b, c, d, x[k + 4], S41, 0xf7537e82)
d = II(d, a, b, c, x[k + 11], S42, 0xbd3af235)
c = II(c, d, a, b, x[k + 2], S43, 0x2ad7d2bb)
b = II(b, c, d, a, x[k + 9], S44, 0xeb86d391)
a = AddUnsigned(a, AA)
b = AddUnsigned(b, BB)
c = AddUnsigned(c, CC)
d = AddUnsigned(d, DD)
}
let temp = WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d)
return temp.toLowerCase()
}
Loading…
Cancel
Save