Compare commits

..

No commits in common. "d30c9e90d6cefb04a573e9507b28fc5a0d974fff" and "2cb5175727271e18ef414cf0ccc06589f6a29e41" have entirely different histories.

6 changed files with 93 additions and 514 deletions

View File

@ -3,7 +3,6 @@ using Admin.NET.Application.Const;
using Admin.NET.Application.Entity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Text.RegularExpressions;
namespace Admin.NET.Application;
/// <summary>
/// 单位服务
@ -189,44 +188,5 @@ public class SysUnitService : IDynamicApiController, ITransient
return result;
}
/// <summary>
/// 生成编码
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpGet]
[ApiDescriptionSettings(Name = "createCodeNum")]
public async Task<string> CreateCodeNum()
{
string dt = DateTime.Now.ToString("yyyyMMdd");
var unit = await _rep.AsQueryable()
.Where(a => !a.IsDelete)
.Where(a => a.CodeNum.Contains(dt))
.OrderByDescending(t => t.CodeNum)
.FirstAsync();
if (unit != null)
{
Match match = Regex.Match(unit.CodeNum, @"\d+");
if (match.Success)
{
string numberStr = match.Value; // 获取匹配到的数字字符串
int number = int.Parse(numberStr); // 将数字字符串转换为整数
number++; // 对数字进行加1操作
// 将结果转换回字符串,并保持与原数字相同的长度
string paddedNumber = number.ToString().PadLeft(match.Value.Length, '0');
return paddedNumber;
}
else
{
return dt + "001";
}
}
else
{
return dt + "001";
}
}
}

View File

@ -1,58 +0,0 @@
import request from '/@/utils/request';
enum Api {
AddMaterialsClassify = '/api/materialClassify/add',
DeleteMaterialsClassify = '/api/materialClassify/delete',
UpdateMaterialsClassify = '/api/materialClassify/update',
PageMaterialsClassify = '/api/materialClassify/page',
DetailMaterialsClassify = '/api/materialClassify/detail',
ListMaterialsClassify = '/api/materialClassify/list',
}
// 增加物料
export const addMaterialsClassify = (params?: any) =>
request({
url: Api.AddMaterialsClassify,
method: 'post',
data: params,
});
// 删除物料
export const deleteMaterialsClassify = (params?: any) =>
request({
url: Api.DeleteMaterialsClassify,
method: 'post',
data: params,
});
// 编辑物料
export const updateMaterialsClassify = (params?: any) =>
request({
url: Api.UpdateMaterialsClassify,
method: 'post',
data: params,
});
// 分页查询物料
export const pageMaterialsClassify = (params?: any) =>
request({
url: Api.PageMaterialsClassify,
method: 'post',
data: params,
});
// 详情物料
export const detailMaterialsClassify = (id: any) =>
request({
url: Api.DetailMaterialsClassify,
method: 'get',
data: { id },
});
// 物料列表
export const listMaterialsClassify = () =>
request({
url: Api.ListMaterialsClassify,
method: 'get',
data: { },
});

View File

@ -1,164 +0,0 @@
<!-- 物料 -->
<template>
<div class="sys-open-access-container">
<el-dialog v-model="state.isShowDialog" :title="props.title" width="1000">
<el-form :inline="true" :model="ruleForm" class="demo-form-inline" label-width="90px">
<el-row>
<el-col :span="24">
<el-form-item label="物料类型" :rules="[{ required: true, message: '物料类型不能为空', trigger: 'blur' }]">
<el-input v-model="ruleForm.name" placeholder="请输入名称" clearable />
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-row style="display: flex; justify-content: space-around;">
<el-button style="width: 100px;" type="primary" @click="matterSubmit"></el-button>
<el-button style="width: 100px;" @click="closeDialog"></el-button>
</el-row>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue';
import { getAPI } from '/@/utils/axios-utils';
import { BrandApi, MaterialClassifyApi, PackageInfoApi, SysUnitGroupApi,SysUnitApi } from '/@/api-services/api';
import { AddMaterialsInput, BrandOutput, MaterialsOutput, PackageInfoOutput, SysUnitGroupOutput, SysUnitOutput} from '/@/api-services/models';
import { ElMessageBox, ElMessage, TabsPaneContext } from 'element-plus';
import { addMaterials, updateMaterials,detailMaterials } from '/@/api/main/materials';
import { listUnitGroup } from '/@/api/main/unit';
import {addMaterialsClassify, detailMaterialsClassify, updateMaterialsClassify} from "/@/api/main/materialClassify";
const props = defineProps({
title: String,
orgData: Array<MaterialsOutput>,
});
//
const emit = defineEmits(["reloadTable"]);
//
let fyListData = ref();
const fyListGet = async () => {
let res = await getAPI(MaterialClassifyApi).apiMaterialClassifyListGet();
if (res.data.code === 200) {
fyListData.value = res.data.result;
}
}
const ruleForm = ref<any>({});
const state = reactive({
loading: false,
isShowDialog:false,
editClassifyOpenAccessTitle:'新增',
tableData: [] ,//as Array<MaterialsOutput>
orgTreeData: [] ,//as Array<MaterialsOutput>
//matterFrom: {} ,//as AddMaterialsInput
queryParams: {
name: undefined,
},
tableParams: {
page: 1,
pageSize: 10,
total: 0 as any,
},
editPrintTitle: '',
unitGroupData:[] as Array<SysUnitGroupOutput>,
unitData:[] as Array<SysUnitOutput>,
});
//
const openDialog = async (row: any) => {
//ruleFormRef.value?.resetFields();
//state.selectedTabName = '0'; // tab
let rowData = JSON.parse(JSON.stringify(row));
if (rowData.id)
ruleForm.value = (await detailMaterialsClassify(rowData.id)).data.result;
else{
ruleForm.value = rowData;
ruleForm.value.isEnable=true;
}
state.isShowDialog = true;
};
//
const closeDialog = () => {
state.isShowDialog = false;
};
onMounted(() => {
fyListGet();
});
//
const matterSubmit = async () => {
let res;
if (props.title=='添加物料类型'){
res = await addMaterialsClassify(ruleForm.value);
}
else {
res = await updateMaterialsClassify(ruleForm.value);
}
//console.log(res)
if (res.data.code == 200) {
state.isShowDialog = false;
ElMessage({
message: '成功',
type: 'success',
})
//state.tableData.handleList();
}
else
ElMessage.error(res.message!)
emit("reloadTable");
closeDialog();
}
//
defineExpose({ openDialog });
</script>
<style lang="scss" scoped>
.main {
padding: 10px;
display: flex;
flex-direction: column;
.main-from {
// height: 300px;
width: 100%;
padding: 20px 10px;
.el-row {
width: 100%;
}
}
.main-table {
margin-top: 20px;
box-sizing: border-box;
padding: 10px;
flex-grow: 1;
height: 0;
display: flex;
flex-direction: column;
.tab {
flex: 1;
overflow: scroll;
}
.tab-hed {
display: flex;
justify-content: space-between;
margin: 5px;
align-items: center;
}
}
}
</style>

View File

@ -248,7 +248,6 @@ const openDialog = async (row: any) => {
ruleForm.value.isEnable=true;
ruleForm.value.codeNum = 'WL'+ getCurrentDate();
}
await fyListGet();
state.isShowDialog = true;
};

View File

@ -66,41 +66,6 @@
</el-row>
</el-form>
</el-card>
<div class="main-table ">
<div class="tab-left" >
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<div>
物料类型
</div>
<div>
<el-button type="success" link
@click.prevent="openAddMaterialsClassify"
style="border-right: 1px #515a6e solid; border-radius: 0px; margin-right: 3px; padding: 0 3px;">新增</el-button>
</div>
</div>
<el-table
ref="singleTableRef"
:data="leftTableData"
style="width: 100%"
tooltip-effect="light"
row-key="id"
@sort-change="sortChange"
highlight-current-row
@current-change="radioChangeEvent"
>
<el-table-column type="index" label="序号" width="55" align="center"/>
<el-table-column prop="name" label="名称" show-overflow-tooltip="" />
<el-table-column label="操作" width="140" align="center" fixed="right" show-overflow-tooltip="" v-if="auth('materials:update') || auth('materials:delete')" >
<template #default="scope">
<el-button icon="ele-Edit" size="small" text="" type="primary" @click="openEditMaterialsClassify(scope.row)" v-auth="'materials:update'" @click.native.stop="stopPropagation"> </el-button>
<el-button icon="ele-Delete" size="small" text="" type="primary" @click="delMaterialsClassify(scope.row)" v-auth="'materials:delete'" @click.native.stop="stopPropagation"> </el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
<div class="tab-right" style="width: 75%">
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
<el-table
:data="tableData"
@ -147,71 +112,39 @@
:title="editMaterialsTitle"
@reloadTable="handleQuery"
/>
<editClassifyDialog
ref="editDialogClassifyRef"
:title="editMaterialsClassifyTitle"
@reloadTable="initMatterClassify"
/>
</el-card>
</div>
</div>
</div>
</template>
<script lang="ts" setup="" name="matter">
import {ElMessageBox, ElMessage, ElTable} from "element-plus";
import { ref } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { auth } from '/@/utils/authFunction';
import editDialog from '/@/views/basics-date/matter/component/editOpenAccess.vue'
import editClassifyDialog from '/@/views/basics-date/matter/component/editClassifyOpenAccess.vue'
import { pageMaterials, deleteMaterials } from '/@/api/main/materials';
import {
deleteMaterialsClassify,
listMaterialsClassify,
} from "/@/api/main/materialClassify";
import {ref} from "vue";
const currentRow = ref();
const singleTableRef = ref<InstanceType<typeof ElTable>>();
// import { getDictDataItem as di, getDictDataList as dl } from '/@/utils/dict-utils';
// import { formatDate } from '/@/utils/formatTime';
import editDialog from '/@/views/basics-date/matter/component/editOpenAccess.vue'
import { pageMaterials, deleteMaterials } from '/@/api/main/materials';
const showAdvanceQueryUI = ref(false);
const editDialogRef = ref();
const editDialogClassifyRef = ref();
const loading = ref(false);
const tableData = ref<any>([]);
const leftTableData = ref<any>([]);
const queryParams = ref<any>({});
const tableParams = ref({
page: 1,
pageSize: 10,
total: 0,
});
//
const radioChangeEvent = (val: undefined) => {
if(val) {
currentRow.value = val.id
queryParams.value.classify = val.id;
handleQuery();
}
}
const stopPropagation = (event) => {
event.stopPropagation();
}
const editMaterialsTitle = ref("");
const editMaterialsClassifyTitle = ref("");
//
const changeAdvanceQueryUI = () => {
showAdvanceQueryUI.value = !showAdvanceQueryUI.value;
}
const initMatterClassify = async () => {
var res = await listMaterialsClassify();
leftTableData.value = res.data.result ?? [];
}
//
const handleQuery = async () => {
@ -256,34 +189,6 @@
})
.catch(() => {});
};
//
const openAddMaterialsClassify = () => {
editMaterialsClassifyTitle.value = '添加物料类型';
editDialogClassifyRef.value.openDialog({});
};
//
const openEditMaterialsClassify = (row: any) => {
editMaterialsClassifyTitle.value = '编辑物料类型';
editDialogClassifyRef.value.openDialog(row);
};
//
const delMaterialsClassify = (row: any) => {
ElMessageBox.confirm(`确定要删除吗?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
await deleteMaterialsClassify(row);
await initMatterClassify();
ElMessage.success("删除成功");
})
.catch(() => {});
};
//
const handleSizeChange = (val: number) => {
@ -298,53 +203,13 @@
};
handleQuery();
initMatterClassify();
</script>
<style scoped>
:deep(.el-ipnut),
:deep(.el-select),
:deep(.el-input-number) {
width: 100%;
}
</style>
<style lang="scss" scoped>
.main-table {
margin-top: 20px;
box-sizing: border-box;
padding: 10px;
flex-grow: 1;
height: 0;
display: flex;
// flex-direction: column;
.tab-left {
width: 25%;
display: flex;
flex-direction: column;
margin-right: 20px;
// div:nth-child(1) {
// width: 50%;
// }
// div:nth-child(2) {
// width: 50%;
// }
}
.tab {
width: 80%;
flex: 1;
overflow: scroll;
display: flex;
flex-direction: column;
div:nth-child(1) {
flex: 1;
overflow: scroll;
}
}
}
</style>

View File

@ -16,7 +16,7 @@
</el-row>
<el-form-item>
<el-button type="primary" @click="unitPage({groupUnitId:data.selectUnitGroupId})"></el-button>
<el-button type="primary" @click="unitPage"></el-button>
<el-button type="primary" @click="addUnit"></el-button>
<el-button @click="''"></el-button>
<el-button @click="''"></el-button>
@ -60,90 +60,84 @@
</vxe-table>
</div>
</div>
<div class="tab" style="overflow: hidden;margin-top:29px">
<div class="tab">
<div>
<el-table
ref="multipleTableRef"
:data="data.unit"
style="width: 100%"
v-loading="loading"
tooltip-effect="light"
row-key="id"
border="">
<el-table-column type="selection" width="60" />
<el-table-column prop="codeNum" label="编码" show-overflow-tooltip="" />
<el-table-column prop="name" label="名称" show-overflow-tooltip="" />
<el-table-column prop="code" label="代码" show-overflow-tooltip="" />
<el-table-column prop="isEnable" label="可用状态" show-overflow-tooltip="">
<template #default="scope">
{{ scope.row.isEnable ? '启用' : '关闭' }}
</template>
</el-table-column>
<el-table-column prop="childUnitCount" label="子单位数" show-overflow-tooltip="" />
<el-table-column prop="rate" label="换算率" show-overflow-tooltip="" />
<el-table-column prop="isEnable" label="作为基本单位" show-overflow-tooltip="">
<template #default="scope">
{{ scope.row.isBaseUnit ? '是' : '否' }}
</template>
</el-table-column>
<el-table-column label="操作"align="center" fixed="right" show-overflow-tooltip="" v-if="auth('materials:update') || auth('materials:delete')">
<template #default="scope">
<vxe-button type="text" @click="editUnit(scope.row)" icon="vxe-icon-edit">修改</vxe-button>
<vxe-button type="text" @click="deleteUnit(scope.row)" icon="vxe-icon-delete" style="color: rgb(223, 65, 65)">删除</vxe-button>
</template>
</el-table-column>
</el-table>
<!-- <el-table-->
<!-- :data="data.unit"-->
<!-- style="width: 40%"-->
<!-- v-loading="loading"-->
<!-- tooltip-effect="light"-->
<!-- row-key="id"-->
<!-- @sort-change="sortChange"-->
<!-- border="">-->
<!-- <el-table-column type="index" label="序号" width="55" align="center"/>-->
<!-- <el-table-column prop="name" label="名称" width="140" show-overflow-tooltip="" />-->
<!-- <el-table-column prop="codeNum" label="编码" width="140" show-overflow-tooltip="" />-->
<!-- <el-table-column prop="aliasName" label="别名" width="140" show-overflow-tooltip="" />-->
<!-- <el-table-column prop="simpleNumber" label="助记码" width="140" show-overflow-tooltip="" />-->
<!-- <el-table-column prop="specifications" label="规格型号" width="140" show-overflow-tooltip="" />-->
<!-- <el-table-column prop="isEnable" label="可用状态" width="120" show-overflow-tooltip="">-->
<!-- <template #default="scope">-->
<!-- <el-tag v-if="scope.row.isEnable"> </el-tag>-->
<!-- <el-tag type="danger" v-else> </el-tag>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column prop="remarks" label="备注" width="200" show-overflow-tooltip="" />-->
<!-- <el-table-column label="操作" width="140" align="center" fixed="right" show-overflow-tooltip="" v-if="auth('materials:update') || auth('materials:delete')">-->
<!-- <template #default="scope">-->
<!-- <el-button icon="ele-Edit" size="small" text="" type="primary" @click="editUnit(scope.row)"> </el-button>-->
<!-- <el-button icon="ele-Delete" size="small" text="" type="primary" @click="deleteUnit(scope.row)" > 删除 </el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- </el-table>-->
<!-- <el-pagination-->
<!-- v-model:currentPage="tableParams.page"-->
<!-- v-model:page-size="tableParams.pageSize"-->
<!-- :total="tableParams.total"-->
<!-- :page-sizes="[10, 20, 50, 100, 200, 500]"-->
<!-- small=""-->
<!-- background=""-->
<!-- @size-change="handleSizeChange"-->
<!-- @current-change="handleCurrentChange"-->
<!-- layout="total, sizes, prev, pager, next, jumper"-->
<!-- />-->
<vxe-table show-overflow height="100%" :data="data.unit" :border=true
:tree-config="{ transform: true }" :scroll-y="{ gt: 20 }">
<vxe-column type="checkbox" width="60" fixed="left"></vxe-column>
<!-- <vxe-table show-overflow height="100%" :data="data.unit" :border=true-->
<!-- :tree-config="{ transform: true }" :scroll-y="{ gt: 20 }">-->
<!-- <vxe-column type="checkbox" width="60" fixed="left"></vxe-column>-->
<vxe-column field="codeNum" sortable title="编码" width=""></vxe-column>
<vxe-column field="name" sortable title="名称" width=""></vxe-column>
<vxe-column field="code" sortable title="代码" width=""></vxe-column>
<!-- <vxe-column field="codeNum" sortable title="编码" width=""></vxe-column>-->
<!-- <vxe-column field="name" sortable title="名称" width=""></vxe-column>-->
<!-- <vxe-column field="code" sortable title="代码" width=""></vxe-column>-->
<!-- <vxe-column sortable title="可用状态" width="">-->
<!-- <template #default="{ row }">-->
<!-- {{ row.isEnable ? '启用' : '关闭' }}-->
<!-- &lt;!&ndash; <vxe-button type="text" icon="vxe-icon-delete"></vxe-button> &ndash;&gt;-->
<!-- </template>-->
<!-- </vxe-column>-->
<!-- <vxe-column field="childUnitCount" sortable title="子单位数" width=""></vxe-column>-->
<!-- <vxe-column field="rate" sortable title="换算率" width=""></vxe-column>-->
<!-- <vxe-column field="isBaseUnit" sortable title="作为基本单位" width="">-->
<!-- <template #default="{ row }">-->
<!-- {{ row.isBaseUnit ? '是' : '否' }}-->
<!-- &lt;!&ndash; <vxe-button type="text" icon="vxe-icon-delete"></vxe-button> &ndash;&gt;-->
<!-- </template>-->
<!-- </vxe-column>-->
<!-- <vxe-column title="操作" width="200" fixed="right" show-overflow>-->
<!-- <template #default="{ row }">-->
<!-- <vxe-button type="text" @click="editUnit(row)" icon="vxe-icon-edit">修改</vxe-button>-->
<!-- <vxe-button type="text" @click="deleteUnit(row)" icon="vxe-icon-delete" style="color: rgb(223, 65, 65)">删除</vxe-button>-->
<!-- &lt;!&ndash; <vxe-button type="text" icon="vxe-icon-delete"></vxe-button> &ndash;&gt;-->
<!-- </template>-->
<!-- </vxe-column>-->
<!-- </vxe-table>-->
<vxe-column sortable title="可用状态" width="">
<template #default="{ row }">
{{ row.isEnable ? '启用' : '关闭' }}
<!-- <vxe-button type="text" icon="vxe-icon-delete"></vxe-button> -->
</template>
</vxe-column>
<vxe-column field="childUnitCount" sortable title="子单位数" width=""></vxe-column>
<vxe-column field="rate" sortable title="换算率" width=""></vxe-column>
<vxe-column field="isBaseUnit" sortable title="作为基本单位" width="">
<template #default="{ row }">
{{ row.isBaseUnit ? '是' : '否' }}
<!-- <vxe-button type="text" icon="vxe-icon-delete"></vxe-button> -->
</template>
</vxe-column>
<vxe-column title="操作" width="200" fixed="right" show-overflow>
<template #default="{ row }">
<vxe-button type="text" @click="editUnit(row)" icon="vxe-icon-edit">修改</vxe-button>
<vxe-button type="text" @click="deleteUnit(row)" icon="vxe-icon-delete" style="color: rgb(223, 65, 65)">删除</vxe-button>
<!-- <vxe-button type="text" icon="vxe-icon-delete"></vxe-button> -->
</template>
</vxe-column>
</vxe-table>
</div>
<div style="line-height: 35px">
<el-pagination
v-model:currentPage="tableParams.page"
v-model:page-size="tableParams.pageSize"
:total="tableParams.total"
:page-sizes="[10, 20, 50, 100, 200, 500]"
small=""
background=""
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, sizes, prev, pager, next, jumper"
/>
</div>
<!-- <div>-->
<!-- <vxe-pager v-model:current-page="pageVO1.currentPage" v-model:page-size="pageVO1.pageSize"-->
<!-- :total="pageVO1.total" />-->
<!-- </div>-->
<div>
<vxe-pager v-model:current-page="pageVO1.currentPage" v-model:page-size="pageVO1.pageSize"
:total="pageVO1.total" />
</div>
</div>
</div>
@ -269,14 +263,9 @@ let data = reactive({
unitGroup: [] as SysUnitGroupOutput[],//
selectUnitGroupId:0,
});
const loading = ref(false);
const ruleFormRef = ref();
const isShowDialog=ref(false);
const tableParams = ref({
page: 1,
pageSize: 10,
total: 0,
});
let unitGroupModel=reactive<any>({isEnable:true,isDelete:false});
//
const rules = ref<FormRules>({
@ -287,8 +276,6 @@ let unitGroupModel=reactive<any>({isEnable:true,isDelete:false});
let mGroupTitle = ref('新增');
let dialogTableVisible = ref(false);
const unitFrom = ref<any>({isEnable:true,isDelete:false,name:'',codeNum:''})
const cancel=()=>{
@ -321,6 +308,7 @@ const unitGroup = async () => {
}
//
const radioChangeEvent = ({ row }) => {
data.selectUnitGroupId = row.id;
unitPage({groupUnitId:row.id})
@ -329,26 +317,15 @@ const formInline = reactive({} as SysUnitInput)
//
const unitPage = async (parameter = formInline) => {
let res = await getAPI(SysUnitApi).apiSysUnitPagePost({pageSize:tableParams.value.pageSize,page:tableParams.value.page, ...parameter,...formInline });
let res = await getAPI(SysUnitApi).apiSysUnitPagePost({ page: 1, pageSize: 10, ...parameter,...formInline });
data.unit = res.data.result?.items as any;
tableParams.value.total = res.data.result?.total;
pageVO1.total = res.data.result?.total!;
}
//
const handleSizeChange = (val: number) => {
tableParams.value.pageSize = val;
unitPage({groupUnitId:data.selectUnitGroupId});
};
//
const handleCurrentChange = (val: number) => {
tableParams.value.page = val;
unitPage({groupUnitId:data.selectUnitGroupId});
};
const addUnit= ()=>{
dialogTableVisible.value=true;
mTitle.value='新增'
}
@ -402,7 +379,7 @@ const deleteUnit=async(row:any)=>{
let res = await getAPI(SysUnitApi).apiSysUnitDeletePost(row);
if (res.data.code == 200) {
ElMessage({ message: '成功', type: 'success', })
unitPage({groupUnitId:data.selectUnitGroupId});
unitPage();
//state.tableData.handleList();
} else
ElMessage.error(res.data.message!)
@ -440,7 +417,7 @@ const deleteUnitGroup=async(row:any)=>{
if (res.data.code == 200) {
ElMessage({ message: '成功', type: 'success', })
unitGroup()
unitPage({groupUnitId:data.selectUnitGroupId})
unitPage()
//state.tableData.handleList();
} else
ElMessage.error(res.data.message!)
@ -458,7 +435,7 @@ const pageVO1 = reactive({
onMounted(() => {
unitGroup()
unitPage({groupUnitId:data.selectUnitGroupId})
unitPage()
})
</script>