diff --git a/admin/src/utils/api.js b/admin/src/utils/api.js
index 6776db34..effbb6bf 100644
--- a/admin/src/utils/api.js
+++ b/admin/src/utils/api.js
@@ -36,6 +36,9 @@ const api = {
listExam: (params = {}) => {
return axios.get('exam', {params: params});
},
+ listExamIndex: (params = {}) => {
+ return axios.get('exam-index', {params: params});
+ },
storeExam: (params = {}) => {
return axios.post('exam', params);
},
diff --git a/admin/src/views/exam/form.vue b/admin/src/views/exam/form.vue
index eb86a8a9..db47bb1a 100644
--- a/admin/src/views/exam/form.vue
+++ b/admin/src/views/exam/form.vue
@@ -2,33 +2,74 @@
-
-
-
+
+
+
-
-
+
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+ Unit: {{item.unit}}
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
- 启用
- 禁用
+ Enabled
+ Disabled
+
+
+
+
+
+
+
+
+
+
+
+ {{item}}
+
+
+
+
+
+
+
+
+
+
+
+
- {{ id ? '立即修改' : '立即创建' }}
+ Submit
@@ -41,81 +82,72 @@ import { reactive, ref, toRefs, onMounted, onBeforeUnmount, getCurrentInstance }
import { ElMessage } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import { localGet } from '../../utils'
+import api from "../../utils/api";
+
export default {
- name: 'AddGood',
+ name: 'ExamForm',
setup() {
const { proxy } = getCurrentInstance()
console.log('proxy', proxy)
- const goodRef = ref(null)
+ const formRef = ref(null)
const route = useRoute()
const router = useRouter()
const { id } = route.query
const state = reactive({
token: localGet('token') || '',
id: id,
- defaultCate: '',
+ allClasses: [],
formData: {
name: '',
description: '',
begin: '',
end: '',
- requires: {},
- filters: {},
+ indexes: [],
+ filters: {
+ classes: [],
+ register_time_range: []
+ },
status: '',
},
rules: {
- goodsName: [
+ name: [
{ required: 'true', }
],
- originalPrice: [
+ indexes: [
{ required: 'true', }
],
- sellingPrice: [
+ status: [
{ required: 'true',}
],
- stockNum: [
- { required: 'true', }
- ],
},
})
- let instance
onMounted(() => {
-
+ listAllClass()
+ listAllIndex()
+ if (id) {
+ let res = api.getExam(id)
+ // state.formData = res.data
+ } else {
+ let res = api.listExamIndex()
+ state.formData.indexes = res.data
+ }
})
onBeforeUnmount(() => {
})
const submitAdd = () => {
- goodRef.value.validate((vaild) => {
+ formRef.value.validate(async (vaild) => {
if (vaild) {
- // 默认新增用 post 方法
- let httpOption = axios.post
- let params = {
- goodsCategoryId: state.categoryId,
- goodsCoverImg: state.formData.goodsCoverImg,
- goodsDetailContent: instance.txt.html(),
- goodsIntro: state.formData.goodsIntro,
- goodsName: state.formData.goodsName,
- goodsSellStatus: state.formData.goodsSellStatus,
- originalPrice: state.formData.originalPrice,
- sellingPrice: state.formData.sellingPrice,
- stockNum: state.formData.stockNum,
- tag: state.formData.tag
+ let params = state.formData;
+ if (params.begin) {
+ params.begin = dayjs(params.begin).format('YYYY-MM-DD HH:mm:ss')
}
- if (hasEmoji(params.goodsIntro) || hasEmoji(params.goodsName) || hasEmoji(params.tag) || hasEmoji(params.goodsDetailContent)) {
- ElMessage.error('不要输入表情包,再输入就打死你个龟孙儿~')
- return
+ if (params.end) {
+ params.end = dayjs(params.end).format('YYYY-MM-DD HH:mm:ss')
}
- console.log('params', params)
- if (id) {
- params.goodsId = id
- // 修改商品使用 put 方法
- httpOption = axios.put
- }
- httpOption('/goods', params).then(() => {
- ElMessage.success(id ? '修改成功' : '添加成功')
- router.push({ path: '/good' })
- })
+ console.log(params)
+ let res = await api.storeExam(params)
+ console.log(res)
}
})
}
@@ -132,13 +164,26 @@ export default {
const handleChangeCate = (val) => {
state.categoryId = val[2] || 0
}
+
+ const listAllClass = async () => {
+ let res = await api.listClass()
+ state.allClasses = res.data
+ }
+ const listAllIndex = async () => {
+ let res = await api.listExamIndex()
+ state.formData.indexes = res.data
+ }
+ const getExam = async (id) => {
+ let res = await api.getExam(id)
+ console.log(res)
+ }
return {
...toRefs(state),
- goodRef,
+ formRef,
submitAdd,
handleBeforeUpload,
handleUrlSuccess,
- handleChangeCate
+ handleChangeCate,
}
}
}
diff --git a/admin/src/views/exam/index.vue b/admin/src/views/exam/index.vue
index 945401a3..41a02bd5 100644
--- a/admin/src/views/exam/index.vue
+++ b/admin/src/views/exam/index.vue
@@ -2,7 +2,7 @@
-
-
-
-
+
+
-
-
- 销售中
- 已下架
-
-
+
+
+
+
+
+
+
+
- 修改
+ Edit
下架
上架
@@ -85,13 +87,19 @@
import { onMounted, reactive, ref, toRefs } from 'vue'
import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router'
+import api from '../../utils/api'
export default {
- name: 'Good',
+ name: 'ExamTable',
setup() {
const multipleTable = ref(null)
const router = useRouter()
const state = reactive({
loading: false,
+ query: {
+ page: 1,
+ sort_field: 'id',
+ sort_type: 'desc'
+ },
tableData: [], // 数据列表
multipleSelection: [], // 选中项
total: 0, // 总条数
@@ -99,28 +107,27 @@ export default {
pageSize: 10 // 分页大小
})
onMounted(() => {
- getGoodList()
+ fetchTableData()
})
// 获取轮播图列表
- const getGoodList = () => {
+ const fetchTableData = async () => {
state.loading = true
- axios.get('/goods/list', {
- params: {
- pageNumber: state.currentPage,
- pageSize: state.pageSize
- }
- }).then(res => {
- state.tableData = res.list
- state.total = res.totalCount
- state.currentPage = res.currPage
- state.loading = false
- })
+ let res = await api.listExam(state.query)
+ renderTableData(res)
+ }
+ const renderTableData = (res) => {
+ state.tableData = res.data.data
+ state.page = res.data.meta.current_page
+ state.total = res.data.meta.total
+ state.currentPage = res.data.meta.current_page
+ state.pageSize = res.data.meta.per_page
+ state.loading = false
}
const handleAdd = () => {
router.push({ name: 'exam-form' })
}
const handleEdit = (id) => {
- router.push({ path: '/add', query: { id } })
+ router.push({ path: '/exam-form', query: { id } })
}
// 选择项
const handleSelectionChange = (val) => {
@@ -128,14 +135,14 @@ export default {
}
const changePage = (val) => {
state.currentPage = val
- getGoodList()
+ fetchTableData()
}
const handleStatus = (id, status) => {
axios.put(`/goods/status/${status}`, {
ids: id ? [id] : []
}).then(() => {
ElMessage.success('修改成功')
- getGoodList()
+ fetchTableData()
})
}
return {
@@ -144,7 +151,7 @@ export default {
handleSelectionChange,
handleAdd,
handleEdit,
- getGoodList,
+ fetchTableData,
changePage,
handleStatus
}
diff --git a/app/Http/Controllers/ExamController.php b/app/Http/Controllers/ExamController.php
index 4cb2f032..2ee6fb03 100644
--- a/app/Http/Controllers/ExamController.php
+++ b/app/Http/Controllers/ExamController.php
@@ -40,10 +40,10 @@ class ExamController extends Controller
{
$rules = [
'name' => 'required|string',
- 'begin' => 'required|date_format:Y-m-d H:i:s',
- 'end' => 'required|date_format:Y-m-d H:i:s',
- 'requires' => 'required|array|min:1',
- 'filters' => 'required|array|min:1',
+ 'indexes' => 'required|array|min:1',
+ 'status' => 'required|in:0,1',
+// 'begin' => 'nullable|date',
+// 'end' => 'nullable|date',
];
$request->validate($rules);
$result = $this->repository->store($request->all());
@@ -55,11 +55,13 @@ class ExamController extends Controller
* Display the specified resource.
*
* @param int $id
- * @return \Illuminate\Http\Response
+ * @return array
*/
public function show($id)
{
- //
+ $result = $this->repository->getDetail($id);
+ $resource = new ExamResource($result);
+ return $this->success($resource);
}
/**
@@ -73,10 +75,8 @@ class ExamController extends Controller
{
$rules = [
'name' => 'required|string',
- 'begin' => 'required|date_format:Y-m-d H:i:s',
- 'end' => 'required|date_format:Y-m-d H:i:s',
- 'requires' => 'required|array|min:1',
- 'filters' => 'required|array|min:1',
+ 'indexes' => 'required|array|min:1',
+ 'status' => 'required|in:0,1',
];
$request->validate($rules);
$result = $this->repository->update($request->all(), $id);
diff --git a/app/Http/Resources/ExamResource.php b/app/Http/Resources/ExamResource.php
index 5b22e0ea..a4d5443f 100644
--- a/app/Http/Resources/ExamResource.php
+++ b/app/Http/Resources/ExamResource.php
@@ -2,6 +2,9 @@
namespace App\Http\Resources;
+use App\Models\Exam;
+use App\Models\User;
+use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
class ExamResource extends JsonResource
@@ -21,8 +24,52 @@ class ExamResource extends JsonResource
'begin' => $this->begin,
'end' => $this->end,
'filters' => $this->filters,
- 'requires' => $this->requires,
+ 'filters_formatted' => $this->formatFilters($this->resource),
+ 'indexes' => $this->indexes,
+ 'indexes_formatted' => $this->formatIndexes($this->resource),
'status' => $this->status,
+ 'status_text' => $this->statusText,
];
}
+
+ private function formatFilters(Exam $exam)
+ {
+ $currentFilters = $exam->filters;
+ $arr = [];
+ $filter = Exam::FILTER_USER_CLASS;
+ if (!empty($currentFilters->{$filter})) {
+ $classes = collect(User::$classes)->only($currentFilters->{$filter});
+ $arr[] = sprintf('%s: %s', Exam::$filters[$filter]['name'], $classes->pluck('text')->implode(', '));
+ }
+
+ $filter = Exam::FILTER_USER_REGISTER_TIME_RANGE;
+ if (!empty($currentFilters->{$filter})) {
+ $range = $currentFilters->{$filter};
+ $arr[] = sprintf(
+ "%s: \n%s ~ %s",
+ Exam::$filters[$filter]['name'],
+ $range[0] ? Carbon::parse($range[0])->toDateTimeString() : '-',
+ $range[1] ? Carbon::parse($range[1])->toDateTimeString() : '-'
+ );
+ }
+
+ return implode("\n", $arr);
+ }
+
+ private function formatIndexes(Exam $exam)
+ {
+ $indexes = $exam->indexes;
+ $arr = [];
+ foreach ($indexes as $index) {
+ if (isset($index['checked']) && $index['checked']) {
+ $arr[] = sprintf(
+ '%s: %s %s',
+ Exam::$indexes[$index['index']]['name'] ?? '',
+ $index['require_value'],
+ Exam::$indexes[$index['index']]['unit'] ?? ''
+ );
+ }
+ }
+ return implode("\n", $arr);
+ }
}
diff --git a/app/Models/Exam.php b/app/Models/Exam.php
index a34e71ff..01f54222 100644
--- a/app/Models/Exam.php
+++ b/app/Models/Exam.php
@@ -4,28 +4,39 @@ namespace App\Models;
class Exam extends NexusModel
{
- protected $fillable = ['name', 'description', 'begin', 'end', 'status'];
+ protected $fillable = ['name', 'description', 'begin', 'end', 'status', 'filters', 'indexes'];
+
+ protected $casts = [
+ 'filters' => 'object',
+ 'indexes' => 'array',
+ ];
const STATUS_ENABLED = 0;
const STATUS_DISABLED = 1;
public static $status = [
- self::STATUS_ENABLED => ['text' => '启用中'],
- self::STATUS_DISABLED => ['text' => '已禁用'],
+ self::STATUS_ENABLED => ['text' => 'Enabled'],
+ self::STATUS_DISABLED => ['text' => 'Disabled'],
];
const INDEX_UPLOADED = 1;
- const INDEX_SEED_TIME = 2;
+ const INDEX_SEED_TIME_AVERGAGE = 2;
const INDEX_DOWNLOADED = 3;
- const INDEX_LEECH_TIME = 4;
- const INDEX_BONUS = 5;
+ const INDEX_BONUS = 4;
public static $indexes = [
- self::INDEX_UPLOADED => ['text' => 'Uploaded'],
- self::INDEX_SEED_TIME => ['text' => 'Seed time'],
- self::INDEX_DOWNLOADED => ['text' => 'Download'],
- self::INDEX_LEECH_TIME => ['text' => 'Leech time'],
- self::INDEX_BONUS => ['text' => 'Bonus'],
+ self::INDEX_UPLOADED => ['name' => 'Uploaded', 'unit' => 'GB'],
+ self::INDEX_SEED_TIME_AVERGAGE => ['name' => 'Seed Time Average', 'unit' => 'Hour'],
+ self::INDEX_DOWNLOADED => ['name' => 'Downloaded', 'unit' => 'GB'],
+ self::INDEX_BONUS => ['name' => 'Bonus', 'unit' => ''],
+ ];
+
+ const FILTER_USER_CLASS = 'classes';
+ const FILTER_USER_REGISTER_TIME_RANGE = 'register_time_range';
+
+ public static $filters = [
+ self::FILTER_USER_CLASS => ['name' => 'User Class'],
+ self::FILTER_USER_REGISTER_TIME_RANGE => ['name' => 'User Register Time Range'],
];
public function getStatusTextAttribute()
diff --git a/app/Repositories/ExamRepository.php b/app/Repositories/ExamRepository.php
index 4d8175ca..e0eeb22a 100644
--- a/app/Repositories/ExamRepository.php
+++ b/app/Repositories/ExamRepository.php
@@ -5,6 +5,7 @@ use App\Models\Exam;
use App\Models\Setting;
use App\Models\User;
use Carbon\Carbon;
+use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
class ExamRepository extends BaseRepository
@@ -19,6 +20,10 @@ class ExamRepository extends BaseRepository
public function store(array $params)
{
+ $data = Arr::only($params, ['name', 'description', 'status', 'filters']);
+ if (!empty($params['begin'])) {
+
+ }
$exam = Exam::query()->create($params);
return $exam;
}
@@ -30,11 +35,28 @@ class ExamRepository extends BaseRepository
return $exam;
}
+ public function getDetail($id)
+ {
+ $exam = Exam::query()->findOrFail($id);
+ return $exam;
+ }
+
public function listIndexes()
{
$out = [];
foreach(Exam::$indexes as $key => $value) {
- $out[$key] = $value['text'];
+ $value['index'] = $key;
+ $out[] = $value;
+ }
+ return $out;
+ }
+
+ public function listFilters()
+ {
+ $out = [];
+ foreach(Exam::$filters as $key => $value) {
+ $value['filter'] = $key;
+ $out[] = $value;
}
return $out;
}
diff --git a/database/migrations/2021_04_19_061650_create_exams_table.php b/database/migrations/2021_04_19_061650_create_exams_table.php
index 46f0d6a4..0a147583 100644
--- a/database/migrations/2021_04_19_061650_create_exams_table.php
+++ b/database/migrations/2021_04_19_061650_create_exams_table.php
@@ -17,10 +17,10 @@ class CreateExamsTable extends Migration
$table->id();
$table->string('name');
$table->text('description')->nullable();
- $table->dateTime('begin');
- $table->dateTime('end');
- $table->text('filters');
- $table->text('requires');
+ $table->dateTime('begin')->nullable();
+ $table->dateTime('end')->nullable();
+ $table->text('filters')->nullable();
+ $table->text('indexes');
$table->tinyInteger('status')->default(0);
$table->timestamps();
});