feat(卡密): 添加 搜索 删除

This commit is contained in:
李四 2024-01-25 17:05:15 +08:00
parent 758d727306
commit 5dccf37ebd
7 changed files with 373 additions and 9 deletions

View File

@ -0,0 +1,12 @@
import request from '@/utils/request'
export function add(params:Record<string, any>) {
return request.post(`carmi/add`,params)
}
export function get(params:Record<string, any>) {
return request.post(`carmi/get`,params)
}
export function del(params:Record<string, any>) {
return request.post(`carmi/del`,params)
}

View File

@ -1,16 +1,197 @@
<template>
<t-button theme="default" variant="base">填充按钮</t-button>
<t-row :gutter="6">
<t-col :span="3">
<t-input-adornment prepend="订单号">
<t-input v-model="order" style="width:100%;"/>
</t-input-adornment>
</t-col>
<t-col :span="3">
<t-input-adornment prepend="创建时间">
<t-date-picker v-model="date" style="width: 100%;" />
</t-input-adornment>
</t-col>
<t-col :span="3">
<t-input-adornment prepend="激活状态">
<t-select
style="width: 100%;"
v-model="state"
:options="optionsState"
clearable
></t-select>
</t-input-adornment>
</t-col>
<t-col >
<t-button @click="search">搜索</t-button>
<t-button theme="default" @click="reset">重置</t-button>
</t-col>
</t-row>
<t-button @click="visible1 = true">添加</t-button>
<t-button theme="default" @click="refresh">刷新</t-button>
<t-table
row-key="id"
:data="data"
bordered
:columns="columns"
:loading="loadingTable"
:pagination="pagination"
:disableDataPage="true"
@page-change="onPageChange">
<template #type="{row}">
{{ row.type === 0 ? '进件特约商户' : row.type === 1 ? '小程序注册' : '小程序备案' }}
</template>
<template #state="{row}">
{{ row.state === 0 ? '未激活' : '已激活' }}
</template>
<template #op="{row}">
<t-button theme="danger" size="small" variant="base" @click="del(row.id)">删除</t-button>
</template>
</t-table>
<t-dialog
v-model:visible="visible1"
header="添加"
:on-close="null"
:cancel-btn="null"
confirm-btn="确认"
@confirm="onClickConfirm"
>
<t-input-adornment prepend="激活类型">
<t-select
v-model="type"
:options="options"
clearable
></t-select>
</t-input-adornment>
<t-input-adornment prepend="生成数量">
<t-input v-model="nums" type="number" />
</t-input-adornment>
</t-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { getHelloWorld } from '@/addon/carmi/api/hello_world'
import { ref,onMounted } from 'vue'
import { PageInfo,MessagePlugin,DialogPlugin } from 'tdesign-vue-next';
import { add,get,del as deleteItem } from '@/addon/carmi/api/test'
const hello_world_text = ref('');
const getHelloWorldInfo = async () => {
hello_world_text.value = await (await getHelloWorld()).data
//
const del = (val:number)=>{
const confirmDia = DialogPlugin({
header: '提示',
body:'确认删除数据吗?',
width:'20%',
onConfirm: async () => {
const res = await deleteItem({id:val})
MessagePlugin.success('删除成功')
init()
confirmDia.hide();
},
})
}
getHelloWorldInfo()
//
const order = ref('')
//
const date = ref()
//
const state = ref()
const optionsState = [
{
value:0,
label:'未激活'
},
{
value:1,
label:'已激活'
},
]
//
const search = ()=>{
init({
number: order.value,
create_time: date.value,
state: state.value,
page: pagination.value.defaultCurrent,
limit: pagination.value.defaultPageSize
})
}
//
const reset = ()=>{
order.value =''
}
interface PARAMS {
number?:string,
create_time?:string,
state?:number,
page:number,
limit:number
}
const data = ref([])
const loadingTable = ref(false)
const init =async (params:PARAMS = {
page: pagination.value.defaultCurrent,
limit: pagination.value.defaultPageSize
}) => {
loadingTable.value = true
const res = await get(params)
loadingTable.value = false
data.value = res.data.data
pagination.value.total = res.data.total
MessagePlugin.success('获取成功!')
}
onMounted(()=>{
init()
})
const refresh = ()=>{
init()
}
const options = [
{
label:'进件',value:0
},
{
label:'小程序注册',value:1
},
{
label:'小程序备案',value:2
},
]
const visible1 = ref(false)
const type = ref(0)
const nums = ref(1)
const onClickConfirm = async ()=>{
if(nums.value > 0){
const res = await add({type:type.value,nums:nums.value})
visible1.value = false
MessagePlugin.success('添加成功')
init()
console.log(res);
type.value = 0
nums.value = 1
}
}
const pagination = ref({
defaultCurrent: 1,
defaultPageSize: 10,
total:0,
});
const onPageChange = (val:PageInfo)=>{
pagination.value.defaultCurrent = val.current
pagination.value.defaultPageSize = val.pageSize
init()
}
const columns = ref([
{ colKey: 'create_time', title: '创建时间', width: '200',align:'center' },
{colKey: 'type',title: '激活类型',width: '130',align:'center'},
{ colKey: 'code', title: '激活码',width: '200',align:'center' },
{ colKey: 'state', title: '激活状态',width: '100',align:'center'},
{ colKey: 'number', title: '订单号',width: '200',align:'center' },
{ colKey: 'update_time', title: '更新时间', width: '200',align:'center'},
{ colKey: 'op', title: '操作', width: '100',align:'center'},
]);
</script>
<style lang="scss" scoped>

View File

@ -9,7 +9,16 @@ import { useElementIcon } from './utils/common'
import 'highlight.js/styles/stackoverflow-light.css';
import hljs from 'highlight.js/lib/common'
import hljsVuePlugin from '@highlightjs/vue-plugin'
import { Button as TButton } from 'tdesign-vue-next';
import { Button as TButton,
Table as TTable,
Dialog as TDialog,
Select as TSelect,
InputAdornment as TInputAdornment,
Input as TInput,
Row as TRow,
Col as TCol,
DatePicker as TDatePicker
} from 'tdesign-vue-next';
import 'tdesign-vue-next/es/style/index.css';
window.hl = hljs
@ -23,6 +32,14 @@ async function run() {
app.use(hljsVuePlugin)
useElementIcon(app)
app.use(TButton)
app.use(TTable)
app.use(TDialog)
app.use(TSelect)
app.use(TInputAdornment)
app.use(TInput)
app.use(TRow)
app.use(TCol)
app.use(TDatePicker)
app.mount('#app')
}

View File

@ -0,0 +1,54 @@
<?php
namespace addon\carmi\app\adminapi\controller\carmi;
use core\base\BaseAdminController;
use think\Response;
use addon\carmi\app\model\Test;
use addon\carmi\app\service\CarmiService;
class Index extends BaseAdminController
{
/**
* 添加卡密
* @return Response
*/
public function add()
{
$data =$this->request->params([
['type', 0],
['nums', 1],
]);
$msg = new CarmiService();
$result = $msg->add($data);
if($result){
return success('ADD_SUCCESS', []);
}
}
/**
* 搜索卡密
* @return Response
*/
public function get()
{
$data = $this->request->params([
['number', ''],
['state', ""],
['create_time', 0],
]);
$msg = new CarmiService();
return success($msg->get($data));
}
/**
* 删除
* @return Response
*/
public function del()
{
$data = $this->request->params([
['id','']
]);
if((new CarmiService())->del($data['id'])){
return Response::create(['data' => [$data], 'msg' => '删除成功', 'code' => 1], 'json', 200);
};
}
}

View File

@ -22,7 +22,9 @@ Route::group('carmi', function () {
/***************************************************** hello world ****************************************************/
Route::get('hello_world', 'addon\carmi\app\adminapi\controller\hello_world\Index@index');
Route::post('add', 'addon\carmi\app\adminapi\controller\carmi\Index@add');
Route::post('get', 'addon\carmi\app\adminapi\controller\carmi\Index@get');
Route::post('del', 'addon\carmi\app\adminapi\controller\carmi\Index@del');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

View File

@ -0,0 +1,27 @@
<?php
namespace addon\carmi\app\model;
use core\base\BaseModel;
class Test extends BaseModel
{
public function searchNumberAttr($query, $value, $data)
{
if ($value) {
$query->where('number','like', '%'.$value . '%');
}
}
public function searchCreateTimeAttr($query, $value, $data)
{
if ($value) {
$timestamp = strtotime($value);
$query->where([['create_time', '>=', $timestamp]]);
}
}
public function searchStateAttr($query, $value, $data)
{
if($value == 0 || $value == 1 ){
$query->where([['state', '=', $value]]);
}
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace addon\carmi\app\service;
use core\base\BaseAdminService;
use addon\carmi\app\model\Test;
use think\Response;
class CarmiService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new Test();
}
// 添加
public function add(array $data)
{
$list = [];
for ($x=0; $x<$data['nums']; $x++) {
$item=[
"state"=>0,
"number"=>$this->generateOrderNumber(),
"code"=>$this->generateActivationCode(18),
"type"=>intval($data['type'])
];
array_push($list,$item);
}
return $this->model->saveAll($list);
}
// 获取列表
public function get(array $where = [])
{
$search_model = $this->model->withSearch(['number','create_time','state'],$where)->order('create_time desc');
return $this->pageQuery($search_model);
}
// 删除
public function del(int $id)
{
return $this->model->find($id)->delete();
}
// 生成订单号
function generateOrderNumber() {
$microtime = microtime(true);
$microtimeStr = str_replace('.', '', (string)$microtime); // 移除小数点
$uniqidPart = substr(uniqid(), -8); // 或者 substr(uniqid(), 7, 8) 去除前缀
return date('Ymd') . substr($microtimeStr, -6) . $uniqidPart;
}
// 生成激活码
// 使用 uniqid() 函数结合微秒时间戳获取基础唯一标识符
function generateActivationCode($length = 32) {
$uniqidPart = bin2hex(openssl_random_pseudo_bytes(16)); // 或者使用 uniqid('', true)
// 可选添加额外的安全性如用户ID或其它上下文信息如果适用
// $userId = get_current_user_id(); // 假设这是一个获取当前用户ID的方法
// $contextInfo = hash('sha256', $userId . time());
// $activationBase = $uniqidPart . $contextInfo;
// 直接使用 uniqidPart
$activationBase = $uniqidPart;
// 使用安全的哈希函数进一步处理,例如 SHA-256
$activationCode = hash('sha256', $activationBase);
// 如果需要特定长度的激活码,可以截取哈希值的一部分或者用更短的哈希函数
if ($length > 0 && $length < strlen($activationCode)) {
$activationCode = substr($activationCode, 0, $length);
}
return strtoupper($activationCode); // 返回大写字符串形式的激活码
}
}