feat: 新增云闪付模块,并新增商品类型枚举

This commit is contained in:
wangsongsole 2023-07-11 14:29:40 +08:00
parent 79785be9f8
commit d90bb154e3
12 changed files with 2918 additions and 2690 deletions

View File

@ -30,8 +30,9 @@ import cloneDeep from "lodash/cloneDeep"
import omit from "lodash/omit"
import { getVoucherWarningAccount, handelResponse } from "@/assets/api"
import MobileComponent from "./mobileComponent"
import YSFMobileComponent from "./ysf-mobileComponent"
import WangEditor from "./wangEditor"
import { receiveTypeList, week, earlyPerList, model } from "./static"
import { receiveTypeList, week, earlyPerList, model, ysf } from "./static"
const initArray = (targetNum) => {
return Array.from({ length: targetNum }, (_, index) => index)
}
@ -519,15 +520,16 @@ export default class addKnockGold extends Component {
disabled={this.state.isEdit}
onChange={({ target }) => {
this.onHandleChange(target.value, "channel")
// if (target.value == 1) {
// this.onHandleChange(defaultInstructionZfb, 'instruction');
// } else {
// this.onHandleChange(defaultInstructionWx, 'instruction');
// }
if (target.value === 3) {
this.onHandleChange(ysf, "instruction")
} else {
this.onHandleChange("", "instruction")
}
}}
value={this.state.model.channel}
>
<RadioButton value={1}>支付宝</RadioButton>
<RadioButton value={3}>云闪付</RadioButton>
<RadioButton disabled value={2}>
微信
</RadioButton>
@ -1096,7 +1098,11 @@ export default class addKnockGold extends Component {
</Form>
</Card>
<MobileComponent data={this.state.model} keyType={this.props.keyType} />
{this.state.model.channel !== 3 ? (
<MobileComponent data={this.state.model} keyType={this.props.keyType} />
) : (
<YSFMobileComponent data={this.state.model} keyType={this.props.keyType} />
)}
</div>
)
}

View File

@ -192,6 +192,202 @@
}
}
#ysf-redPacketsViews {
position: fixed !important;
top: 130px !important;
right: 90px !important;
border: 1px solid #e4e4e4;
border-radius: 5px;
font-size: 16px;
width: 375px !important;
box-sizing: border-box;
z-index: 1003;
overflow: auto;
scrollbar-width: none;
background-color: rgb(238 25 32);
padding: 25px 16px;
&::-webkit-scrollbar {
display: none
}
.available_time {
text-align: left;
margin-bottom: 8px;
.available_time_text {
font-size: 16px;
padding-bottom: 5px;
margin-top: 5px;
box-sizing: border-box;
}
.timeList {
display: grid;
grid-template-columns: repeat(3, 33.33%);
text-align: center;
li {
margin: 3px 0;
font-size: 11px;
color: #a8a8a8;
}
}
}
.type {
color: #fff;
font-size: 10px;
text-align: center;
margin-top: 10px;
}
.type>span {
padding: 4px 14px;
background-color: rgb(238 25 32);
border-radius: 20px;
}
.content {
min-height: 100%;
background: #fff;
position: relative;
padding: 0 14px 16px;
box-sizing: border-box;
border-radius: 0 0 6px 6px;
}
.bubble {
width: 100%;
border-radius: 1.28px 1.28px 0 0;
display: flex;
margin-bottom: -1.2px;
}
.segmentation {
display: flex;
justify-content: space-between;
width: 100%;
align-items: center;
}
.left,
.right {
width: 10px;
height: 18px;
background: rgb(238 25 32);
display: inline-block;
}
.left {
border-radius: 0 18px 18px 0;
margin-left: -15px;
}
.right {
border-radius: 18px 0 0 18px;
margin-right: -15px;
}
.middle {
width: 100%;
height: 1px;
background-image: linear-gradient(to right,
rgb(223, 222, 222) 0%,
rgb(223, 222, 222) 50%,
transparent 50%);
background-size: 8px 2px;
background-repeat: repeat-x;
}
.title {
color: rgb(163, 160, 163);
text-align: center;
}
.information {
text-align: center;
}
.information-p2 {
color: rgb(145, 143, 146);
font-size: 12px;
}
.money {
margin: 6px 0;
}
.form {
margin: 30px 0;
}
.mt0 {
margin-top: 0 !important;
}
.form-label {
font-size: 16px;
}
.form-input {
width: 100%;
height: 32px;
border-radius: 8px;
outline: 0;
border: .16px solid rgb(217, 216, 218);
background: #fffefe;
padding: 0 10px;
box-sizing: border-box;
margin: 10px 0;
font-size: 12px;
}
.form-input::placeholder {
color: rgb(204, 205, 209);
font-size: 12px;
}
.form-note {
color: red;
font-size: 11px;
}
.text-center {
text-align: center;
}
.form-button {
width: 100%;
height: 38px;
border-radius: 19.2px;
outline: 0;
border: 0;
font-size: 16px;
color: white;
background: rgb(238 25 32);
margin-top: 30px;
}
.illustrate {
margin-top: 18px;
}
.illustrate-title {
font-size: 16px;
margin-bottom: 6px;
}
.illustrate-text {
color: rgb(150, 152, 158);
font-size: 12px;
line-height: 22px;
min-height: 200px;
}
}
#redPackets {

View File

@ -16,6 +16,16 @@ export const week = [
{ key: "7", text: "周日" }
]
export const ysf = `用户可在云闪付APP-我的红包中查看最近60天内即将过期的云闪付红包金额及到期时间。用户参加活动 (如天天领红包、移动积分兑换红包等活动)获得的云闪付红包有效期以营销活动页面规则说明为准,到期后自动失效。
<br>()在云闪付红包的有效期内不限使用时间
<br>() 使用商户:专享红包支持云闪付APP内手机充值水电煤缴费商城购物等多场景抵扣支付也可通过云闪付APP在云闪付线下受理商户进行二维码主扫或被扫支付时抵扣个别商户不支持红包抵扣具体以支付结果为准
<br>() 使用规则:
<br>1线下商户:用户在云闪付线下受理商户使用云闪付APP出示付款码支付时可使用云闪付红包抵扣订单金额如肯德基全家便利店星巴克屈臣氏罗森便利店DQ来伊份等
<br>2线上商户:在云闪付APP内或线上商户选择云闪付APP支付时可使用云闪付红包抵扣订单金额如12306京东到家本来生活等
<br>31元云闪付红包可抵扣1元人民币订单金额
<br>4订单金额满0.01元时方可使用云闪付红包;抵扣订单金额时需至少支付0.01
<br>5云闪付红包不可用于提现购买活期+或者其他理财产品`
//预警百分比
export const earlyPerList = ["70", "50", "30", "20"]

View File

@ -1,67 +1,56 @@
import React from 'react';
import Editor from 'wangeditor';
import './index.less';
import React from "react"
import Editor from "wangeditor"
import "./index.less"
export default class wangEditor extends React.Component {
constructor(props) {
super(props);
super(props)
this.state = {
editorHtml: '',
editorHtml: "",
count: 0
};
}
}
componentDidMount() {
let self = this;
const editor = new Editor('#wangeditorDom');
this.setState({ editor });
editor.config.colors = ['#696969', '#9093a2', '#fgddbb', '#e3e7eb'];
editor.config.pasteText = true;
let self = this
const editor = new Editor("#wangeditorDom")
this.setState({ editor })
editor.config.colors = ["#696969", "#9093a2", "#fgddbb", "#e3e7eb"]
editor.config.pasteText = true
// 500px
editor.config.height = 200;
editor.config.showFullScreen = false;
editor.config.menus = [
'bold',
'foreColor',
'italic',
'indent',
'link',
'justify'
];
editor.config.height = 200
editor.config.showFullScreen = false
editor.config.menus = ["bold", "foreColor", "italic", "indent", "link", "justify"]
// height create()
// height create()
editor.config.onchange = function (newHtml) {
var text = editor.txt.text();
var text = editor.txt.text()
if (text.length == 0) {
//
self.props.setEdittext('');
self.props.setEdittext("")
}
if (text.length > self.props.limitLength) {
let str = text.slice(0, self.props.limitLength);
self.setState({ editorHtml: str });
editor.txt.html(str);
self.props.setEdittext(str);
return;
let str = text.slice(0, self.props.limitLength)
self.setState({ editorHtml: str })
editor.txt.html(str)
self.props.setEdittext(str)
return
}
self.setState({ count: text.length });
self.setState({ editorHtml: newHtml });
self.props.setEdittext(newHtml);
};
self.setState({ count: text.length })
self.setState({ editorHtml: newHtml })
self.props.setEdittext(newHtml)
}
editor.create();
editor.create()
//
setTimeout(() => {
editor.txt.html(this.props.text);
}, 100);
editor.txt.html(this.props.text)
}
render() {
return (
<div className='countBox_par'>
<div id='wangeditorDom' style={{ width: this.props.width }}></div>
<p className='countBox'>
{this.state.count + '/' + this.props.limitLength}
</p>
<div className="countBox_par">
<div id="wangeditorDom" style={{ width: this.props.width }}></div>
<p className="countBox">{this.state.count + "/" + this.props.limitLength}</p>
</div>
);
)
}
}

View File

@ -0,0 +1,134 @@
import "./index.less"
import { Placeholder } from "zent"
import { useState, useEffect } from "react"
import { sortWeeks } from "@/tools/utils.js"
const widths = [24, 100, 100, 100, 80, 100, 100, 100, 80, 100, 100, 100, 80, 100, 100, 100, 100]
export default ({ data }) => {
const [newWeek, setNewWeek] = useState([])
useEffect(() => {
setNewWeek(sortWeeks(data.receive_rule.week))
}, [data.receive_rule.week, data.receive_irregular])
function createElement() {
if (data.receive_type === 1) {
return (
<div className="available_time">
<p className="available_time_text">领取时间</p>
<ul className="timeList">
{newWeek?.map((item) => (
<li key={item}>
{item}
{data.receive_rule.time.map((item1, index) => {
if (item1[1])
return (
<p key={index} style={{ textAlign: "center", marginTop: "5px" }}>
{item1[0]}~{item1[1]}
</p>
)
})}
</li>
))}
</ul>
</div>
)
} else if (data.receive_type === 2) {
return (
<div className="available_time">
<p className="available_time_text">领取时间</p>
<ul className="timeList">
{data.receive_irregular?.map((item) => (
<li key={item.data}>
{item.date}
{item.time.map((item1) => {
if (item1[1])
return (
<p style={{ marginTop: "5px" }} key={item1[1]}>
{item1[0]}~{item1[1]}
</p>
)
})}
</li>
))}
</ul>
</div>
)
} else if (data.receive_type === 3) {
return (
<div className="available_time">
<p className="available_time_text">领取时间</p>
<ul className="timeList">
{data.receive_day?.map((item) => (
<li key={item.item}>{item.join(" ~ ")}</li>
))}
</ul>
</div>
)
}
}
return (
<div id="ysf-redPacketsViews" className="mobile">
<img
className="bubble"
src="https://lsxdemall.oss-cn-beijing.aliyuncs.com/MarketingSystem/img/ysf-logo.png"
alt=""
/>
<div className="content">
<p className="title">云闪付</p>
<div className="information">
<p className="money" style={{ fontSize: "32px" }}>
<span className="tag" style={{ fontSize: "20px" }}>
</span>
{data.cash_amount_type === "1"
? parseFloat(data.denomination || 0.01)
: `${parseFloat(data.min_denomination || 0.01)} ~ ${parseFloat(
data.max_denomination || 88.88
)}`}
</p>
<p className="information-p2">
请在&nbsp;
{data.effect_date[1] || "2023-12-30 23:59:59"}
&nbsp;内领取
</p>
<p className="type">
<span>{data.cash_amount_type === "1" ? "固额红包" : "随机红包"}</span>
</p>
</div>
<div className="form" v-if="coupon.status===3">
<p className="form-label">云闪付账号</p>
<input className="form-input" disabled type="text" placeholder="请输入手机号" />
<input className="form-input mt0" disabled type="text" placeholder="请再次输入手机号" />
<p className="form-note">您可在云闪付的个人信息中查看云闪付账号</p>
<button className="form-button">立即领取</button>
</div>
<div className="segmentation">
<i className="left"></i>
<i className="middle"></i>
<i className="right"></i>
</div>
<div className="illustrate">
{data.instruction || [1, 2, 3].includes(data.receive_type) ? (
<>
{createElement()}
<p className="illustrate-title">活动说明</p>
<p
className="illustrate-text"
dangerouslySetInnerHTML={{
__html: data.instruction
}}
></p>
</>
) : (
<Placeholder.TextBlock
className="TextBlock"
animate
widths={widths}
rows={12}
dashed={false}
/>
)}
</div>
</div>
</div>
)
}

View File

@ -1,17 +1,14 @@
import React, { useRef, useEffect } from "react";
import { useSetState } from "ahooks";
import { Sweetalert, Notify } from "zent";
import isNaN from "lodash/isNaN";
import isNil from "lodash/isNil";
import omitBy from "lodash/omitBy";
import TabPage from "@/components/tabPage/main.js";
import Ipt from "@/components/input/main";
import Grid from "@/components/gird/main.js";
import {
getCodeProductList,
handelResponse,
deleteGoodsScope
} from "@/assets/api.js";
import React, { useRef, useEffect } from "react"
import { useSetState } from "ahooks"
import { Sweetalert, Notify } from "zent"
import isNaN from "lodash/isNaN"
import isNil from "lodash/isNil"
import omitBy from "lodash/omitBy"
import TabPage from "@/components/tabPage/main.js"
import Ipt from "@/components/input/main"
import Grid from "@/components/gird/main.js"
import { getCodeProductList, handelResponse, deleteGoodsScope } from "@/assets/api.js"
import { productTypeMenu } from "@/tools"
const tableColumn = [
{
@ -92,7 +89,7 @@ const tableColumn = [
type: "slot",
width: "200px"
}
];
]
const UseCouponCommodity = () => {
const [state, setState] = useSetState({
@ -106,8 +103,8 @@ const UseCouponCommodity = () => {
limit: 10,
total: 0,
isQuery: false
});
const table_el = useRef(null);
})
const table_el = useRef(null)
/**
*
@ -119,42 +116,42 @@ const UseCouponCommodity = () => {
code_batch_id: sessionStorage.getItem("code_id"),
page: state.page,
limit: state.limit
};
}
param = omitBy(
{
...param
},
(value) => {
return isNaN(value) || isNil(value);
return isNaN(value) || isNil(value)
}
);
return param;
};
)
return param
}
const getTable = () => {
let param = getParam();
let param = getParam()
getCodeProductList(param).then((res) => {
handelResponse(res, (req, msg) => {
let resData = [];
let resData = []
req.data.map((item) => {
/* type 1为商品 2为立减金 转译字符方便处理 */
/* 此处only 商品为product_id 立减金为channel_activity_id */
if (item.type === 1) {
item.entity.upstream = "直连天下";
item.entity.only = item.entity.product_id;
item.entity.id = item.id;
item.entity.weight = item.weight;
item.entity.upstream = "直连天下"
item.entity.only = item.entity.product_id
item.entity.id = item.id
item.entity.weight = item.weight
item.entity.all_budget =
Number(item.entity.contract_price) * Number(item.entity.quantity);
item.entity.type = 1;
resData.push(item.entity);
Number(item.entity.contract_price) * Number(item.entity.quantity)
item.entity.type = 1
resData.push(item.entity)
} else if (item.type === 2) {
resData.push({
product_id: item.entity.goods_id,
product_type_text: "立减金",
only: item.entity.channel_activity_id,
id: item.id,
upstream: String(item.entity.channel) === "1" ? "支付宝" : "微信",
upstream: productTypeMenu(item.entity.channel),
code_batch_id: item.code_batch_id,
contract_price: item.entity.price,
create_time: item.create_time,
@ -167,31 +164,31 @@ const UseCouponCommodity = () => {
item.entity.time_limit.effect_time.start_time +
" 至 " +
item.entity.time_limit.effect_time.end_time //
});
})
}
});
setState({ tableData: resData });
});
});
};
})
setState({ tableData: resData })
})
})
}
useEffect(() => {
getTable();
}, [state.isQuery]);
getTable()
}, [state.isQuery])
const selectionFun = () => {};
const selectionFun = () => {}
const searchCallback = () => {
getTable();
};
getTable()
}
const onPageChange = (data) => {
setState({ page: data, isQuery: !state.isQuery });
};
setState({ page: data, isQuery: !state.isQuery })
}
const onCountChange = (data) => {
setState({ limit: data, isQuery: !state.isQuery });
};
setState({ limit: data, isQuery: !state.isQuery })
}
const tabChange = (data) => {
setState({ page: 1, limit: 10, status: data, isQuery: !state.isQuery });
};
setState({ page: 1, limit: 10, status: data, isQuery: !state.isQuery })
}
const deleteRow = (row) => {
Sweetalert.confirm({
type: "warning",
@ -204,41 +201,37 @@ const UseCouponCommodity = () => {
handelResponse(
res,
(response, msg) => {
Notify.clear();
Notify.success(msg);
setState({ isQuery: !state.isQuery });
Notify.clear()
Notify.success(msg)
setState({ isQuery: !state.isQuery })
},
(err) => {
Notify.error(err);
Notify.error(err)
}
);
)
})
.catch((err) => {});
.catch((err) => {})
},
onCancel() {},
className: "questModal",
parentComponent: this
});
};
})
}
return (
<div className='table-box-app'>
<TabPage
tabs={state.tabList}
tabChange={(data) => tabChange(data)}></TabPage>
<div className='query-box'>
<div className="table-box-app">
<TabPage tabs={state.tabList} tabChange={(data) => tabChange(data)}></TabPage>
<div className="query-box">
<div></div>
<Ipt
onChange={(e) => setState({ key_word: e })}
value={state.key_word}
wordSearch={() => searchCallback()}
icon='search'
icon="search"
placeholder={"请输入商品名称进行匹配查询"}
countShow={false}
height={"36px"}
width={"260px"}
onClearItem={(e) =>
setState({ key_word: "", isQuery: !state.isQuery })
}
onClearItem={(e) => setState({ key_word: "", isQuery: !state.isQuery })}
alignment={"left"}
/>
</div>
@ -267,7 +260,7 @@ const UseCouponCommodity = () => {
<span>
{rowData.begin_time} {rowData.end_time}
</span>
);
)
}
if (com === "opearo") {
@ -275,17 +268,18 @@ const UseCouponCommodity = () => {
<div>
<span
style={{ color: "red" }}
className='grid-link'
onClick={() => deleteRow(rowData)}>
className="grid-link"
onClick={() => deleteRow(rowData)}
>
删除
</span>
</div>
);
)
}
}}
/>
</div>
);
};
)
}
export default UseCouponCommodity;
export default UseCouponCommodity

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@ import Ipt from "@/components/input/main"
import Grid from "@/components/gird/main.js"
import TabPage from "@/components/tabPage/main.js"
import { getCodeProductList, handelResponse, delCodeProduct } from "@/assets/api.js"
import { productTypeMenu } from "@/tools"
const Column = [
{
@ -140,7 +141,7 @@ export default class commodityList extends React.Component {
resData.push({
product_id: item.entity.goods_id,
product_type_text: "立减金",
upstream: String(item.entity.channel) === "1" ? "支付宝" : "微信",
upstream: productTypeMenu(item.entity.channel),
contract_price: item.entity.price,
create_time: item.entity.create_time,
official_price: item.entity.reduce_amount,
@ -160,7 +161,7 @@ export default class commodityList extends React.Component {
resData.push({
product_id: item.entity.goods_id,
product_type_text: item.entity.cash_amount_type === "2" ? "随机红包" : "固额红包",
upstream: item.entity.channel === 1 ? "支付宝" : "微信",
upstream: productTypeMenu(item.entity.channel),
contract_price: (item.entity.total_contract_price / item.entity.num).toFixed(2), //合同单价,
create_time: item.entity.create_time,
official_price: price,

View File

@ -1,4 +1,5 @@
import { divNum } from "@/tools/number"
import { productTypeMenu } from "@/tools"
//基本信息
export const codeInfo = {
code_name: [{ type: "required", message: "请输入兑换码名称" }],
@ -198,7 +199,7 @@ export function redPacketsDataFn(params) {
newObj.only = params.cash_activity_id //批次号
newObj.type = 3 //类型
newObj.checked = params?.checked
newObj.upstream = params.channel === 1 ? "支付宝" : "微信" //上游
newObj.upstream = productTypeMenu(params.channel) //上游
newObj.edit = "edit"
newObj.all_budget = params.all_budget
newObj.effectDate = params.begin_time + " 至 " + params.end_time //有效时间
@ -222,7 +223,7 @@ export function reductionFn(params) {
newObj.only = params.channel_activity_id //批次号
newObj.type = 2 //类型
newObj.checked = params?.checked
newObj.upstream = String(params.channel) === "1" ? "支付宝" : "微信" //上游
newObj.upstream = productTypeMenu(params.channel) //上游
newObj.edit = "edit"
newObj.all_budget = params.all_budget
newObj.effectDate =

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ const kgType = (item) => {
export const knockGoldFun = (item) => {
let table_obj = {}
table_obj.type = 2 // 类型
table_obj.upstream = String(item.channel) === "1" ? "支付宝" : "微信" // 上游平台
table_obj.upstream = productTypeMenu(item.channel) // 上游平台
table_obj.only = item // 存储就数据 编辑好用
table_obj.product_id = item.goods_id ? item.goods_id : item.channel_activity_id // 商品编号
table_obj.product_name = item.batch_goods_name // 商品名
@ -42,7 +42,7 @@ export const redPacketsFun = (item) => {
? item.denomination
: `${item.min_denomination}~${item.max_denomination}`
table_obj.type = 3 // 类型
table_obj.upstream = item.channel === 1 ? "支付宝" : "微信" // 上游平台
table_obj.upstream = productTypeMenu(item.channel) // 上游平台
table_obj.only = item // 存储就数据 编辑好用
table_obj.product_id = item.goods_id || item.id || item.cash_activity_id // 商品编号
table_obj.product_name = item.batch_goods_name // 商品名
@ -59,7 +59,6 @@ export const redPacketsFun = (item) => {
// 卡密判断
export const submitIsKm = (data) => {
console.log("submitIsKm =>", data)
let visible = true
let deDateTime = JSON.parse(sessionStorage.getItem("knockGold_effectDate"))
let end_time = new Date(deDateTime.end_time).getTime() // 计划结束时间
@ -75,3 +74,15 @@ export const submitIsKm = (data) => {
}
return visible
}
/* 商品类型 */
export function productTypeMenu(type) {
switch (type) {
case 1:
return "支付宝"
case 2:
return "微信"
case 3:
return "云闪付"
}
}